/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.accessibility;

import java.net.*;
import java.util.*;
import java.util.List;

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.cocoa.*;
import org.eclipse.swt.widgets.*;

/**
 * Instances of this class provide a bridge between application
 * code and assistive technology clients. Many platforms provide
 * default accessible behavior for most widgets, and this class
 * allows that default behavior to be overridden. Applications
 * can get the default Accessible object for a control by sending
 * it <code>getAccessible</code>, and then add an accessible listener
 * to override simple items like the name and help string, or they
 * can add an accessible control listener to override complex items.
 * As a rule of thumb, an application would only want to use the
 * accessible control listener to implement accessibility for a
 * custom control.
 *
 * @see Control#getAccessible
 * @see AccessibleListener
 * @see AccessibleEvent
 * @see AccessibleControlListener
 * @see AccessibleControlEvent
 * @see <a href="http://www.eclipse.org/swt/snippets/#accessibility">Accessibility snippets</a>
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
 *
 * @since 2.0
 */
@SuppressWarnings({"rawtypes", "unchecked"})
public class Accessible {

	static boolean DEBUG = false;

	static final int MAX_RELATION_TYPES = 15;

	static NSString[] baseAttributes = {
		OS.NSAccessibilityRoleAttribute,
		OS.NSAccessibilitySubroleAttribute,
		OS.NSAccessibilityRoleDescriptionAttribute,
		OS.NSAccessibilityHelpAttribute,
		OS.NSAccessibilityFocusedAttribute,
		OS.NSAccessibilityParentAttribute,
		OS.NSAccessibilityChildrenAttribute,
		OS.NSAccessibilityPositionAttribute,
		OS.NSAccessibilitySizeAttribute,
		OS.NSAccessibilityWindowAttribute,
		OS.NSAccessibilityTopLevelUIElementAttribute,
	};

	NSMutableArray attributeNames = null;
	NSMutableArray parameterizedAttributeNames = null;
	NSMutableArray actionNames = null;

	List<AccessibleListener> accessibleListeners;
	List<AccessibleControlListener> accessibleControlListeners;
	List<AccessibleTextListener> accessibleTextListeners;
	List<AccessibleActionListener> accessibleActionListeners;
	List<AccessibleEditableTextListener> accessibleEditableTextListeners;
	List<AccessibleHyperlinkListener> accessibleHyperlinkListeners;
	List<AccessibleTableListener> accessibleTableListeners;
	List<AccessibleTableCellListener> accessibleTableCellListeners;
	List<AccessibleTextExtendedListener> accessibleTextExtendedListeners;
	List<AccessibleValueListener> accessibleValueListeners;
	List<AccessibleAttributeListener> accessibleAttributeListeners;

	Relation relations[] = new Relation[MAX_RELATION_TYPES];
	Accessible parent;
	Control control;
	int currentRole = -1;

	Map /*<Integer, SWTAccessibleDelegate>*/ childToIdMap = new HashMap();
	SWTAccessibleDelegate delegate;

	int index = -1;

	TableAccessibleDelegate tableDelegate;

	/**
	 * Constructs a new instance of this class given its parent.
	 *
	 * @param parent the Accessible parent, which must not be null
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
	 * </ul>
	 *
	 * @see #dispose
	 * @see Control#getAccessible
	 *
	 * @since 3.6
	 */
	public Accessible(Accessible parent) {
		if (parent == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
		this.parent = parent;
		this.control = parent.control;
		delegate = new SWTAccessibleDelegate(this, ACC.CHILDID_SELF);
	}

	/**
	 * @since 3.5
	 * @deprecated
	 */
	@Deprecated
	protected Accessible() {
	}

	Accessible(Control control) {
		this.control = control;
	}

	/**
	 * Invokes platform specific functionality to allocate a new accessible object.
	 * <p>
	 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
	 * API for <code>Accessible</code>. It is marked public only so that it
	 * can be shared within the packages provided by SWT. It is not
	 * available on all platforms, and should never be called from
	 * application code.
	 * </p>
	 *
	 * @param control the control to get the accessible object for
	 * @return the platform specific accessible object
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	public static Accessible internal_new_Accessible(Control control) {
		return new Accessible(control);
	}

	id accessibleHandle(Accessible accessible) {
		if (accessible.delegate != null) return accessible.delegate;
		if (accessible.control != null) {
			NSView view = accessible.control.view;
			long /*int*/ handle = OS.objc_msgSend(view.id, OS.sel_accessibleHandle);
			return new id(handle);
		}
		return null;
	}

	/**
	 * Adds the listener to the collection of listeners who will
	 * be notified when an accessible client asks for certain strings,
	 * such as name, description, help, or keyboard shortcut. The
	 * listener is notified by sending it one of the messages defined
	 * in the <code>AccessibleListener</code> interface.
	 *
	 * @param listener the listener that should be notified when the receiver
	 * is asked for a name, description, help, or keyboard shortcut string
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleListener
	 * @see #removeAccessibleListener
	 */
	public void addAccessibleListener(AccessibleListener listener) {
		checkWidget();
		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleListeners == null) accessibleListeners = new ArrayList<>();
		accessibleListeners.add(listener);
	}

	/**
	 * Adds the listener to the collection of listeners who will
	 * be notified when an accessible client asks for custom control
	 * specific information. The listener is notified by sending it
	 * one of the messages defined in the <code>AccessibleControlListener</code>
	 * interface.
	 *
	 * @param listener the listener that should be notified when the receiver
	 * is asked for custom control specific information
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleControlListener
	 * @see #removeAccessibleControlListener
	 */
	public void addAccessibleControlListener(AccessibleControlListener listener) {
		checkWidget();
		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleControlListeners == null) accessibleControlListeners = new ArrayList<>();
		accessibleControlListeners.add(listener);
	}

	/**
	 * Adds the listener to the collection of listeners who will
	 * be notified when an accessible client asks for custom text control
	 * specific information. The listener is notified by sending it
	 * one of the messages defined in the <code>AccessibleTextListener</code>
	 * and <code>AccessibleTextExtendedListener</code> interfaces.
	 *
	 * @param listener the listener that should be notified when the receiver
	 * is asked for custom text control specific information
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleTextListener
	 * @see AccessibleTextExtendedListener
	 * @see #removeAccessibleTextListener
	 *
	 * @since 3.0
	 */
	public void addAccessibleTextListener (AccessibleTextListener listener) {
		checkWidget ();
		if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
		if (listener instanceof AccessibleTextExtendedListener) {
			if (accessibleTextExtendedListeners == null) accessibleTextExtendedListeners = new ArrayList<>();
			accessibleTextExtendedListeners.add ((AccessibleTextExtendedListener) listener);
		} else {
			if (accessibleTextListeners == null) accessibleTextListeners = new ArrayList<>();
			accessibleTextListeners.add (listener);
		}
	}

	/**
	 * Adds the listener to the collection of listeners that will be
	 * notified when an accessible client asks for any of the properties
	 * defined in the <code>AccessibleActionListener</code> interface.
	 *
	 * @param listener the listener that should be notified when the receiver
	 * is asked for <code>AccessibleActionListener</code> interface properties
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleActionListener
	 * @see #removeAccessibleActionListener
	 *
	 * @since 3.6
	 */
	public void addAccessibleActionListener(AccessibleActionListener listener) {
		checkWidget();
		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleActionListeners == null) accessibleActionListeners = new ArrayList<>();
		accessibleActionListeners.add(listener);
	}

	/**
	 * Adds the listener to the collection of listeners that will be
	 * notified when an accessible client asks for any of the properties
	 * defined in the <code>AccessibleEditableTextListener</code> interface.
	 *
	 * @param listener the listener that should be notified when the receiver
	 * is asked for <code>AccessibleEditableTextListener</code> interface properties
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleEditableTextListener
	 * @see #removeAccessibleEditableTextListener
	 *
	 * @since 3.7
	 */
	public void addAccessibleEditableTextListener(AccessibleEditableTextListener listener) {
	    checkWidget();
	    if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleEditableTextListeners == null) accessibleEditableTextListeners = new ArrayList<>();
	    accessibleEditableTextListeners.add(listener);
	}

	/**
	 * Adds the listener to the collection of listeners that will be
	 * notified when an accessible client asks for any of the properties
	 * defined in the <code>AccessibleHyperlinkListener</code> interface.
	 *
	 * @param listener the listener that should be notified when the receiver
	 * is asked for <code>AccessibleHyperlinkListener</code> interface properties
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleHyperlinkListener
	 * @see #removeAccessibleHyperlinkListener
	 *
	 * @since 3.6
	 */
	public void addAccessibleHyperlinkListener(AccessibleHyperlinkListener listener) {
		checkWidget();
		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleHyperlinkListeners == null) accessibleHyperlinkListeners = new ArrayList<>();
		accessibleHyperlinkListeners.add(listener);
	}

	/**
	 * Adds the listener to the collection of listeners that will be
	 * notified when an accessible client asks for any of the properties
	 * defined in the <code>AccessibleTableListener</code> interface.
	 *
	 * @param listener the listener that should be notified when the receiver
	 * is asked for <code>AccessibleTableListener</code> interface properties
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleTableListener
	 * @see #removeAccessibleTableListener
	 *
	 * @since 3.6
	 */
	public void addAccessibleTableListener(AccessibleTableListener listener) {
		checkWidget();
		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleTableListeners == null) accessibleTableListeners = new ArrayList<>();
		accessibleTableListeners.add(listener);
	}

	/**
	 * Adds the listener to the collection of listeners that will be
	 * notified when an accessible client asks for any of the properties
	 * defined in the <code>AccessibleTableCellListener</code> interface.
	 *
	 * @param listener the listener that should be notified when the receiver
	 * is asked for <code>AccessibleTableCellListener</code> interface properties
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleTableCellListener
	 * @see #removeAccessibleTableCellListener
	 *
	 * @since 3.6
	 */
	public void addAccessibleTableCellListener(AccessibleTableCellListener listener) {
		checkWidget();
		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleTableCellListeners == null) accessibleTableCellListeners = new ArrayList<>();
		accessibleTableCellListeners.add(listener);
	}

	/**
	 * Adds the listener to the collection of listeners that will be
	 * notified when an accessible client asks for any of the properties
	 * defined in the <code>AccessibleValueListener</code> interface.
	 *
	 * @param listener the listener that should be notified when the receiver
	 * is asked for <code>AccessibleValueListener</code> interface properties
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleValueListener
	 * @see #removeAccessibleValueListener
	 *
	 * @since 3.6
	 */
	public void addAccessibleValueListener(AccessibleValueListener listener) {
		checkWidget();
		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleValueListeners == null) accessibleValueListeners = new ArrayList<>();
		accessibleValueListeners.add(listener);
	}

	/**
	 * Adds the listener to the collection of listeners that will be
	 * notified when an accessible client asks for any of the properties
	 * defined in the <code>AccessibleAttributeListener</code> interface.
	 *
	 * @param listener the listener that should be notified when the receiver
	 * is asked for <code>AccessibleAttributeListener</code> interface properties
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleAttributeListener
	 * @see #removeAccessibleAttributeListener
	 *
	 * @since 3.6
	 */
	public void addAccessibleAttributeListener(AccessibleAttributeListener listener) {
		checkWidget();
		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleAttributeListeners == null) accessibleAttributeListeners = new ArrayList<>();
		accessibleAttributeListeners.add(listener);
	}

	void addCGColor(double /*float*/ [] comps, NSMutableAttributedString inAttribString, NSString inAttribute, NSRange inRange) {
		long /*int*/ cgColorSpace = OS.CGColorSpaceCreateDeviceRGB();
		long /*int*/ cgColor = OS.CGColorCreate(cgColorSpace, comps);
		OS.CGColorSpaceRelease(cgColorSpace);
		inAttribString.addAttribute(inAttribute, new id(cgColor), inRange);
	    OS.CGColorRelease(cgColor);
	}

	/**
	 * Adds a relation with the specified type and target
	 * to the receiver's set of relations.
	 *
	 * @param type an <code>ACC</code> constant beginning with RELATION_* indicating the type of relation
	 * @param target the accessible that is the target for this relation
	 * @exception IllegalArgumentException ERROR_NULL_ARGUMENT - if the Accessible target is null
	 *
	 * @since 3.6
	 */
	public void addRelation(int type, Accessible target) {
		checkWidget();
		if (target == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
		if (relations[type] == null) {
			relations[type] = new Relation(this, type);
		}
		relations[type].addTarget(target);
	}

	int accessibleListenersSize() {
		return accessibleListeners == null ? 0 : accessibleListeners.size();
	}

	int accessibleControlListenersSize() {
		return accessibleControlListeners == null ? 0 : accessibleControlListeners.size();
	}

	int accessibleValueListenersSize() {
		return accessibleValueListeners == null ? 0 : accessibleValueListeners.size();
	}

	int accessibleTextExtendedListenersSize() {
		return accessibleTextExtendedListeners == null ? 0 : accessibleTextExtendedListeners.size();
	}

	int accessibleTextListenersSize() {
		return accessibleTextListeners == null ? 0 : accessibleTextListeners.size();
	}

	int accessibleTableCellListenersSize() {
		return accessibleTableCellListeners == null ? 0 : accessibleTableCellListeners.size();
	}

	int accessibleTableListenersSize() {
		return accessibleTableListeners == null ? 0 : accessibleTableListeners.size();
	}

	int accessibleHyperlinkListenersSize() {
		return accessibleHyperlinkListeners == null ? 0 : accessibleHyperlinkListeners.size();
	}

	int accessibleEditableTextListenersSize() {
		return accessibleEditableTextListeners == null ? 0 : accessibleEditableTextListeners.size();
	}

	int accessibleAttributeListenersSize() {
		return accessibleAttributeListeners == null ? 0 : accessibleAttributeListeners.size();
	}

	int accessibleActionListenersSize() {
		return accessibleActionListeners == null ? 0 : accessibleActionListeners.size();
	}

	void checkRole(int role) {
		// A lightweight control can change its role at any time, so track
		// the current role for the control.  If it changes, reset the attribute list.
		if (role != currentRole) {
			currentRole = role;

			if (attributeNames != null) {
				attributeNames.release();
				attributeNames = null;
			}

			if (parameterizedAttributeNames != null) {
				parameterizedAttributeNames.release();
				parameterizedAttributeNames = null;
			}

			if (actionNames != null) {
				actionNames.release();
				actionNames = null;
			}
		}
	}

	void createTableDelegate() {
		if (tableDelegate == null) {
			tableDelegate = new TableAccessibleDelegate(this);
		}
	}

	id getColumnIndexRangeAttribute(int childID) {
		AccessibleTableCellEvent event = new AccessibleTableCellEvent(this);
		for (int i = 0; i < accessibleTableCellListenersSize(); i++) {
			AccessibleTableCellListener listener = accessibleTableCellListeners.get(i);
			listener.getColumnIndex(event);
			listener.getColumnSpan(event);
		}
		NSRange range = new NSRange();
		range.location = event.index;
		range.length = event.count;
		return NSValue.valueWithRange(range);
	}

	id getRowIndexRangeAttribute(int childID) {
		AccessibleTableCellEvent event = new AccessibleTableCellEvent(this);
		for (int i = 0; i < accessibleTableCellListenersSize(); i++) {
			AccessibleTableCellListener listener = accessibleTableCellListeners.get(i);
			listener.getRowIndex(event);
			listener.getRowSpan(event);
		}
		NSRange range = new NSRange();
		range.location = event.index;
		range.length = event.count;
		return NSValue.valueWithRange(range);
	}

	id getSelectedAttribute(int childID) {
		if (accessibleTableListenersSize() > 0) {
			AccessibleTableEvent event = new AccessibleTableEvent(this);
			event.row = index;
			for (int i = 0; i < accessibleTableListenersSize(); i++) {
				AccessibleTableListener listener = accessibleTableListeners.get(i);
				if (currentRole == ACC.ROLE_ROW)
					listener.isRowSelected(event);
				else
					listener.isColumnSelected(event);
			}
			return NSNumber.numberWithBool(event.isSelected);
		}

		return NSNumber.numberWithBool(false);
	}

	id getIndexAttribute(int childID) {
		return NSNumber.numberWithInt(index);
	}

	id getHeaderAttribute(int childID) {
		id returnValue = null;
		AccessibleTableEvent tableEvent = new AccessibleTableEvent(this);
		for (int i = 0; i < accessibleTableListenersSize(); i++) {
			AccessibleTableListener listener = accessibleTableListeners.get(i);
			listener.getColumnHeader(tableEvent);
		}
		if (tableEvent.accessible != null) returnValue = tableEvent.accessible.delegate;

		return returnValue;
	}

	id getVisibleColumnsAttribute(int childID) {
		if (accessibleTableListenersSize() == 0) return null;
		id returnValue = null;
		AccessibleTableEvent event = new AccessibleTableEvent(this);
		for (int i = 0; i < accessibleTableListenersSize(); i++) {
			AccessibleTableListener listener = accessibleTableListeners.get(i);
			listener.getVisibleColumns(event);
		}
		if (event.accessibles != null) {
			NSMutableArray array = NSMutableArray.arrayWithCapacity(event.accessibles.length);
			Accessible[] accessibles = event.accessibles;
			for (int i = 0; i < accessibles.length; i++) {
				Accessible acc = accessibles[i];
				array.addObject(acc.delegate);
			}
			returnValue = array;
		}
		return returnValue == null ? NSArray.array() : returnValue;
	}

	id getVisibleRowsAttribute(int childID) {
		if (accessibleTableListenersSize() == 0) return null;
		id returnValue = null;
		AccessibleTableEvent event = new AccessibleTableEvent(this);
		for (int i = 0; i < accessibleTableListenersSize(); i++) {
			AccessibleTableListener listener = accessibleTableListeners.get(i);
			listener.getVisibleRows(event);
		}
		if (event.accessibles != null) {
			NSMutableArray array = NSMutableArray.arrayWithCapacity(event.accessibles.length);
			Accessible[] accessibles = event.accessibles;
			for (int i = 0; i < accessibles.length; i++) {
				Accessible acc = accessibles[i];
				array.addObject(acc.delegate);
			}
			returnValue = array;
		}
		return returnValue == null ? NSArray.array() : returnValue;
	}

	id getSelectedRowsAttribute(int childID) {
		if (accessibleTableListenersSize() == 0) return null;
		id returnValue = null;
		AccessibleTableEvent event = new AccessibleTableEvent(this);
		for (int i = 0; i < accessibleTableListenersSize(); i++) {
			AccessibleTableListener listener = accessibleTableListeners.get(i);
			listener.getSelectedRows(event);
		}
		if (event.selected != null) {
			int[] selected = event.selected;
			NSMutableArray array = NSMutableArray.arrayWithCapacity(selected.length);
			for (int i = 0; i < selected.length; i++) {
				event.row = selected[i];
				for (int j = 0; j < accessibleTableListenersSize(); j++) {
					AccessibleTableListener listener = accessibleTableListeners.get(j);
					listener.getRow(event);
				}
				if (event.accessible != null) array.addObject(event.accessible.delegate);
			}
			returnValue = array;
		}
		return returnValue == null ? NSArray.array() : returnValue;
	}


	int getRowCount() {
		AccessibleTableEvent event = new AccessibleTableEvent(this);

		for (int i = 0; i < accessibleTableListenersSize(); i++) {
			AccessibleTableListener listener = accessibleTableListeners.get(i);
			listener.getRowCount(event);
		}

		return event.count;
	}

	id getRowsAttribute(int childID) {
		if (accessibleTableListenersSize() == 0) return null;

		AccessibleTableEvent event = new AccessibleTableEvent(this);
		for (int i = 0; i < accessibleTableListenersSize(); i++) {
			AccessibleTableListener listener = accessibleTableListeners.get(i);
			listener.getRowCount(event);
			listener.getRows(event);
		}

		if (event.accessibles == null) event.accessibles = new Accessible[0];

		if (event.count != event.accessibles.length) {
			createTableDelegate();

			// Rerun the row query now that our accessible is in place.
			for (int i = 0; i < accessibleTableListenersSize(); i++) {
				AccessibleTableListener listener = accessibleTableListeners.get(i);
				listener.getRowCount(event);
				listener.getRows(event);
			}
		}

		NSMutableArray array = NSMutableArray.arrayWithCapacity(event.accessibles.length);
		Object[] rows = event.accessibles;
		for (int i = 0; i < rows.length; i++) {
			Accessible acc = (Accessible) rows[i];
			acc.index = i;
			array.addObject(acc.delegate);
		}
		return array;
	}

	id getSelectedColumnsAttribute(int childID) {
		if (accessibleTableListenersSize() == 0) return null;

		id returnValue = null;
		AccessibleTableEvent event = new AccessibleTableEvent(this);
		for (int i = 0; i < accessibleTableListenersSize(); i++) {
			AccessibleTableListener listener = accessibleTableListeners.get(i);
			listener.getSelectedColumns(event);
		}
		if (event.selected != null) {
			int[] selected = event.selected;
			NSMutableArray array = NSMutableArray.arrayWithCapacity(selected.length);
			for (int i = 0; i < selected.length; i++) {
				event.column = selected[i];
				for (int j = 0; j < accessibleTableListenersSize(); j++) {
					AccessibleTableListener listener = accessibleTableListeners.get(j);
					listener.getColumn(event);
				}
				if (event.accessible != null) array.addObject(event.accessible.delegate);
			}
			returnValue = array;
		}
		return returnValue == null ? NSArray.array() : returnValue;
	}

	int getColumnCount() {
		AccessibleTableEvent event = new AccessibleTableEvent(this);

		for (int i = 0; i < accessibleTableListenersSize(); i++) {
			AccessibleTableListener listener = accessibleTableListeners.get(i);
			listener.getColumnCount(event);
		}

		return event.count;
	}

	id getColumnsAttribute(int childID) {
		if (accessibleTableListenersSize() == 0) return null;

		AccessibleTableEvent event = new AccessibleTableEvent(this);
		for (int i = 0; i < accessibleTableListenersSize(); i++) {
			AccessibleTableListener listener = accessibleTableListeners.get(i);
			listener.getColumnCount(event);
			listener.getColumns(event);
		}

		if (event.accessibles == null) event.accessibles = new Accessible[0];

		if (event.count != event.accessibles.length) {
			createTableDelegate();

			// Rerun the Column query, now that our adapter is in place.
			for (int i = 0; i < accessibleTableListenersSize(); i++) {
				AccessibleTableListener listener = accessibleTableListeners.get(i);
				listener.getColumnCount(event);
				listener.getColumns(event);
			}
		}

		NSMutableArray array = NSMutableArray.arrayWithCapacity(event.accessibles.length);
		Accessible[] accessibles = event.accessibles;
		for (int i = 0; i < accessibles.length; i++) {
			Accessible acc = accessibles[i];
			acc.index = i;
			array.addObject(acc.delegate);
		}
		return array;
	}

	/**
	 * Gets the human-readable description of an action.
	 * <p>
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. It is marked public only so that it can be shared
	 * within the packages provided by SWT. It is not available on all
	 * platforms and should never be accessed from application code.
	 * </p>
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	public id internal_accessibilityActionDescription(NSString action, int childID) {
		NSString returnValue = NSString.string();
		String actionName = action.getString();
		if (accessibleActionListenersSize() > 0) {
			AccessibleActionEvent event = new AccessibleActionEvent(this);
			for (int i = 0; i < accessibleActionListenersSize(); i++) {
				AccessibleActionListener listener = accessibleActionListeners.get(i);
				listener.getActionCount(event);
			}
			int index = -1;
			for (int i = 0; i < event.count; i++) {
				event.index = i;
				for (int j = 0; j < accessibleActionListenersSize(); j++) {
					AccessibleActionListener listener = accessibleActionListeners.get(j);
					listener.getName(event);
				}
				if (actionName.equals(event.result)) {
					index = i;
					break;
				}
			}
			if (index != -1) {
				event.index = index;
				event.result = null;
				for (int i = 0; i < accessibleActionListenersSize(); i++) {
					AccessibleActionListener listener = accessibleActionListeners.get(i);
					listener.getDescription(event);
				}
				if (event.result != null) returnValue = NSString.stringWith(event.result);
			}
		}
		return returnValue;
	}

	/**
	 * Gets the array of action names that this object can perform.
	 * <p>
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. It is marked public only so that it can be shared
	 * within the packages provided by SWT. It is not available on all
	 * platforms and should never be accessed from application code.
	 * </p>
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	public NSArray internal_accessibilityActionNames(int childID) {
		if (accessibleActionListenersSize() > 0) {
			AccessibleActionEvent event = new AccessibleActionEvent(this);
			for (int i = 0; i < accessibleActionListenersSize(); i++) {
				AccessibleActionListener listener = accessibleActionListeners.get(i);
				listener.getActionCount(event);
			}
			NSMutableArray array = NSMutableArray.arrayWithCapacity(event.count);
			for (int i = 0; i < event.count; i++) {
				event.index = i;
				for (int j = 0; j < accessibleActionListenersSize(); j++) {
					AccessibleActionListener listener = accessibleActionListeners.get(j);
					listener.getName(event);
				}
				array.addObject(NSString.stringWith(event.result));
			}
			return array;
		} else {
			// The supported action list depends on the role played by the control.
			AccessibleControlEvent event = new AccessibleControlEvent(this);
			event.childID = childID;
			event.detail = -1;
			for (int i = 0; i < accessibleControlListenersSize(); i++) {
				AccessibleControlListener listener = accessibleControlListeners.get(i);
				listener.getRole(event);
			}

			// No accessible listener is overriding the role of the control, so let Cocoa return the default set for the control.
			if (event.detail == -1) {
				return null;
			}

			checkRole(event.detail);

			if ((childID == ACC.CHILDID_SELF) && (actionNames != null)) {
				return retainedAutoreleased(actionNames);
			}

			NSMutableArray returnValue = NSMutableArray.arrayWithCapacity(5);

			switch (event.detail) {
				case ACC.ROLE_PUSHBUTTON:
				case ACC.ROLE_RADIOBUTTON:
				case ACC.ROLE_CHECKBUTTON:
				case ACC.ROLE_TABITEM:
				case ACC.ROLE_LINK:
				case ACC.ROLE_CHECKMENUITEM:
				case ACC.ROLE_RADIOMENUITEM:
				case ACC.ROLE_SPLITBUTTON:
					returnValue.addObject(OS.NSAccessibilityPressAction);
					break;
				case ACC.ROLE_COMBOBOX:
					returnValue.addObject(OS.NSAccessibilityConfirmAction);
					break;
				case ACC.ROLE_WINDOW:
				case ACC.ROLE_DIALOG:
//					TODO
//					returnValue.addObject(OS.NSAccessibilityRaiseAction);
					break;
			}


			if (childID == ACC.CHILDID_SELF) {
				actionNames = returnValue;
				actionNames.retain();
				return retainedAutoreleased(actionNames);
			} else {
				// Caller must retain if they want to hold on to it.
				return returnValue;
			}
		}
	}

	/**
	 * Checks to see if the specified attribute can be set by a screen reader or other
	 * assistive service.
	 * <p>
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. It is marked public only so that it can be shared
	 * within the packages provided by SWT. It is not available on all
	 * platforms and should never be accessed from application code.
	 * </p>
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	public boolean internal_accessibilityIsAttributeSettable(NSString attribute, int childID) {
		if (accessibleTextExtendedListenersSize() > 0) {
			if (attribute.isEqualToString(OS.NSAccessibilitySelectedTextRangeAttribute)) return true;
			if (attribute.isEqualToString(OS.NSAccessibilityVisibleCharacterRangeAttribute)) return true;
		}
		if (accessibleEditableTextListenersSize() > 0) {
			if (attribute.isEqualToString(OS.NSAccessibilitySelectedTextAttribute)) return true;
		}
		if (accessibleValueListenersSize() > 0) {
			if (attribute.isEqualToString(OS.NSAccessibilityValueAttribute)) return true;
		}
		return false;
	}

	/**
	 * Gets the array of attributes this object supports.
	 * <p>
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. It is marked public only so that it can be shared
	 * within the packages provided by SWT. It is not available on all
	 * platforms and should never be accessed from application code.
	 * </p>
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	public NSArray internal_accessibilityAttributeNames(int childID) {
		// The supported attribute set depends on the role played by the control.
		// We may need to add or remove from the base set as needed.
		AccessibleControlEvent event = new AccessibleControlEvent(this);
		event.childID = childID;
		event.detail = -1;
		for (int i = 0; i < accessibleControlListenersSize(); i++) {
			AccessibleControlListener listener = accessibleControlListeners.get(i);
			listener.getRole(event);
		}

		// No accessible listener is overriding the role of the control, so let Cocoa
		// return the default set for the control.
		if (event.detail == -1)
			return null;

		checkRole(event.detail);

		// If the attributes haven't changed return the cached list.
		if (attributeNames != null) return retainedAutoreleased(attributeNames);

		// Set up the base set of attributes.
		NSMutableArray returnValue = NSMutableArray.arrayWithCapacity(baseAttributes.length);

		for (int i = 0; i < baseAttributes.length; i++) {
			returnValue.addObject(baseAttributes[i]);
		}

		switch(event.detail) {
			case ACC.ROLE_CLIENT_AREA:
				break;
			case ACC.ROLE_WINDOW:
				returnValue.addObject(OS.NSAccessibilityTitleAttribute);
//				TODO
//				returnValue.addObject(OS.NSAccessibilityMainAttribute);
//				returnValue.addObject(OS.NSAccessibilityMinimizedAttribute);
				break;
			case ACC.ROLE_MENUBAR:
				returnValue.addObject(OS.NSAccessibilitySelectedChildrenAttribute);
				returnValue.addObject(OS.NSAccessibilityVisibleChildrenAttribute);
				break;
			case ACC.ROLE_MENU:
				returnValue.addObject(OS.NSAccessibilityEnabledAttribute);
				returnValue.addObject(OS.NSAccessibilitySelectedChildrenAttribute);
				returnValue.addObject(OS.NSAccessibilityVisibleChildrenAttribute);
				break;
			case ACC.ROLE_MENUITEM:
				returnValue.addObject(OS.NSAccessibilityEnabledAttribute);
				break;
			case ACC.ROLE_SEPARATOR:
				returnValue.addObject(OS.NSAccessibilityMaxValueAttribute);
				returnValue.addObject(OS.NSAccessibilityMinValueAttribute);
				returnValue.addObject(OS.NSAccessibilityValueAttribute);
				//TODO
//				returnValue.addObject(OS.NSAccessibilityOrientationAttribute);
//				returnValue.addObject(OS.NSAccessibilityPreviousContentsAttribute);
//				returnValue.addObject(OS.NSAccessibilityNextContentsAttribute);
				break;
			case ACC.ROLE_TOOLTIP:
				returnValue.addObject(OS.NSAccessibilityTitleAttribute);
				break;
			case ACC.ROLE_SCROLLBAR:
				returnValue.addObject(OS.NSAccessibilityValueAttribute);
				//TODO
//				returnValue.addObject(OS.NSAccessibilityOrientationAttribute);
				break;
			case ACC.ROLE_DIALOG:
				returnValue.addObject(OS.NSAccessibilityTitleAttribute);
//				TODO
//				returnValue.addObject(OS.NSAccessibilityMainAttribute);
//				returnValue.addObject(OS.NSAccessibilityMinimizedAttribute);
				break;
			case ACC.ROLE_LABEL:
				returnValue.addObject(OS.NSAccessibilityEnabledAttribute);
				returnValue.addObject(OS.NSAccessibilityValueAttribute);
				break;
			case ACC.ROLE_PUSHBUTTON:
				returnValue.addObject(OS.NSAccessibilityEnabledAttribute);
				returnValue.addObject(OS.NSAccessibilityTitleAttribute);
				break;
			case ACC.ROLE_CHECKBUTTON:
			case ACC.ROLE_RADIOBUTTON:
				returnValue.addObject(OS.NSAccessibilityEnabledAttribute);
				returnValue.addObject(OS.NSAccessibilityValueAttribute);
				returnValue.addObject(OS.NSAccessibilityTitleAttribute);
				break;
			case ACC.ROLE_SPLITBUTTON:
				break;
			case ACC.ROLE_COMBOBOX:
				returnValue.addObject(OS.NSAccessibilityEnabledAttribute);
				returnValue.addObject(OS.NSAccessibilityExpandedAttribute);
				returnValue.addObject(OS.NSAccessibilityNumberOfCharactersAttribute);
				returnValue.addObject(OS.NSAccessibilitySelectedTextAttribute);
				returnValue.addObject(OS.NSAccessibilitySelectedTextRangeAttribute);
				returnValue.addObject(OS.NSAccessibilityVisibleCharacterRangeAttribute);
				returnValue.addObject(OS.NSAccessibilityValueAttribute);
				break;
			case ACC.ROLE_TEXT:
			case ACC.ROLE_PARAGRAPH:
			case ACC.ROLE_HEADING:
				returnValue.addObject(OS.NSAccessibilityEnabledAttribute);
				returnValue.addObject(OS.NSAccessibilityNumberOfCharactersAttribute);
				returnValue.addObject(OS.NSAccessibilitySelectedTextAttribute);
				returnValue.addObject(OS.NSAccessibilitySelectedTextRangeAttribute);
				returnValue.addObject(OS.NSAccessibilityInsertionPointLineNumberAttribute);
				returnValue.addObject(OS.NSAccessibilitySelectedTextRangesAttribute);
				returnValue.addObject(OS.NSAccessibilityVisibleCharacterRangeAttribute);
				returnValue.addObject(OS.NSAccessibilityValueAttribute);
				break;
			case ACC.ROLE_TOOLBAR:
				break;
			case ACC.ROLE_LIST:
				returnValue.addObject(OS.NSAccessibilityEnabledAttribute);
				returnValue.addObject(OS.NSAccessibilityColumnsAttribute);
				returnValue.addObject(OS.NSAccessibilitySelectedColumnsAttribute);
				returnValue.addObject(OS.NSAccessibilityRowsAttribute);
				returnValue.addObject(OS.NSAccessibilitySelectedRowsAttribute);
				returnValue.addObject(OS.NSAccessibilityHeaderAttribute);
				returnValue.addObject(OS.NSAccessibilityVisibleRowsAttribute);
				returnValue.addObject(OS.NSAccessibilityVisibleColumnsAttribute);
				returnValue.addObject(OS.NSAccessibilityVisibleChildrenAttribute);
				break;
			case ACC.ROLE_LISTITEM:
				returnValue.addObject(OS.NSAccessibilityValueAttribute);
				break;
			case ACC.ROLE_TABLE:
				returnValue.addObject(OS.NSAccessibilityEnabledAttribute);
				returnValue.addObject(OS.NSAccessibilityColumnsAttribute);
				returnValue.addObject(OS.NSAccessibilitySelectedColumnsAttribute);
				returnValue.addObject(OS.NSAccessibilityVisibleColumnsAttribute);
				returnValue.addObject(OS.NSAccessibilityRowsAttribute);
				returnValue.addObject(OS.NSAccessibilitySelectedRowsAttribute);
				returnValue.addObject(OS.NSAccessibilityVisibleRowsAttribute);
				returnValue.addObject(OS.NSAccessibilityHeaderAttribute);
				break;
			case ACC.ROLE_TABLECELL:
				returnValue.addObject(OS.NSAccessibilityEnabledAttribute);
				returnValue.addObject(OS.NSAccessibilityValueAttribute);
				break;
			case ACC.ROLE_TREE:
				returnValue.addObject(OS.NSAccessibilityColumnsAttribute);
				returnValue.addObject(OS.NSAccessibilitySelectedColumnsAttribute);
				returnValue.addObject(OS.NSAccessibilityRowsAttribute);
				returnValue.addObject(OS.NSAccessibilitySelectedRowsAttribute);
				returnValue.addObject(OS.NSAccessibilityHeaderAttribute);
				returnValue.addObject(OS.NSAccessibilityVisibleRowsAttribute);
				returnValue.addObject(OS.NSAccessibilityVisibleColumnsAttribute);
				break;
			case ACC.ROLE_TREEITEM:
				returnValue.addObject(OS.NSAccessibilityColumnsAttribute);
				returnValue.addObject(OS.NSAccessibilitySelectedColumnsAttribute);
				returnValue.addObject(OS.NSAccessibilityRowsAttribute);
				returnValue.addObject(OS.NSAccessibilitySelectedRowsAttribute);
				returnValue.addObject(OS.NSAccessibilityHeaderAttribute);
				returnValue.addObject(OS.NSAccessibilityVisibleRowsAttribute);
				returnValue.addObject(OS.NSAccessibilityVisibleColumnsAttribute);
			case ACC.ROLE_TABFOLDER:
				returnValue.addObject(OS.NSAccessibilityValueAttribute);
				returnValue.addObject(OS.NSAccessibilityContentsAttribute);
				returnValue.addObject(OS.NSAccessibilityTabsAttribute);
				break;
			case ACC.ROLE_TABITEM:
				returnValue.addObject(OS.NSAccessibilityEnabledAttribute);
				returnValue.addObject(OS.NSAccessibilityValueAttribute);
				returnValue.addObject(OS.NSAccessibilityTitleAttribute);
				break;
			case ACC.ROLE_PROGRESSBAR:
				returnValue.addObject(OS.NSAccessibilityEnabledAttribute);
				returnValue.addObject(OS.NSAccessibilityMaxValueAttribute);
				returnValue.addObject(OS.NSAccessibilityMinValueAttribute);
				returnValue.addObject(OS.NSAccessibilityValueAttribute);
				break;
			case ACC.ROLE_SLIDER:
				returnValue.addObject(OS.NSAccessibilityEnabledAttribute);
				returnValue.addObject(OS.NSAccessibilityMaxValueAttribute);
				returnValue.addObject(OS.NSAccessibilityMinValueAttribute);
				returnValue.addObject(OS.NSAccessibilityValueAttribute);
				//TODO
//				returnValue.addObject(OS.NSAccessibilityOrientationAttribute);
//				increment
//				decrement
				break;
			case ACC.ROLE_LINK:
				//TODO
				returnValue.addObject(OS.NSAccessibilityEnabledAttribute);
//				returnValue.addObject(OS.NSAccessibilityURLAttribute);
//				visited
				break;
			case ACC.ROLE_ALERT:
				break;
			case ACC.ROLE_ANIMATION:
				break;
			case ACC.ROLE_CANVAS:
				break;
			case ACC.ROLE_COLUMN:
				returnValue.removeObject(OS.NSAccessibilityChildrenAttribute);
				returnValue.removeObject(OS.NSAccessibilityFocusedAttribute);
				returnValue.addObject(OS.NSAccessibilityIndexAttribute);
				returnValue.addObject(OS.NSAccessibilitySelectedAttribute);
				returnValue.addObject(OS.NSAccessibilityRowsAttribute);
				returnValue.addObject(OS.NSAccessibilityVisibleRowsAttribute);
				returnValue.addObject(OS.NSAccessibilityHeaderAttribute);
				break;
			case ACC.ROLE_DOCUMENT:
				break;
			case ACC.ROLE_GRAPHIC:
				returnValue.addObject(OS.NSAccessibilityEnabledAttribute);
				returnValue.addObject(OS.NSAccessibilityTitleAttribute);
				returnValue.addObject(OS.NSAccessibilityDescriptionAttribute);
				break;
			case ACC.ROLE_GROUP:
				break;
			case ACC.ROLE_ROW:
				returnValue.addObject(OS.NSAccessibilityVisibleChildrenAttribute);
				returnValue.addObject(OS.NSAccessibilityIndexAttribute);
				returnValue.addObject(OS.NSAccessibilitySelectedAttribute);
				break;
			case ACC.ROLE_SPINBUTTON:
				break;
			case ACC.ROLE_STATUSBAR:
				break;
			case ACC.ROLE_CHECKMENUITEM:
				break;
			case ACC.ROLE_RADIOMENUITEM:
				break;
			case ACC.ROLE_CLOCK:
				break;
			case ACC.ROLE_DATETIME:
				break;
			case ACC.ROLE_CALENDAR:
				break;
			case ACC.ROLE_FOOTER:
				break;
			case ACC.ROLE_HEADER:
				break;
			case ACC.ROLE_FORM:
				break;
			case ACC.ROLE_PAGE:
				break;
			case ACC.ROLE_SECTION:
				break;
		}


		/*
		 * Only report back sub-roles when the SWT role maps to a sub-role.
		 */
		if (event.detail != -1) {
			String osRole = roleToOs(event.detail);
			if (osRole.indexOf(':') == -1)
				returnValue.removeObject(OS.NSAccessibilitySubroleAttribute);
		}

		/*
		 * Children never return their own children, so remove that attribute.
		 */
		if (childID != ACC.CHILDID_SELF) {
			returnValue.removeObject(OS.NSAccessibilityChildrenAttribute);
		}

		if (childID == ACC.CHILDID_SELF) {
			attributeNames = returnValue;
			attributeNames.retain();
			return retainedAutoreleased(attributeNames);
		} else {
			// Caller must retain if necessary.
			return returnValue;
		}
	}

	/**
	 * Returns the value for the specified attribute. Return type depends on the attribute
	 * being queried; see the implementations of the accessor methods for details.
	 * <p>
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. It is marked public only so that it can be shared
	 * within the packages provided by SWT. It is not available on all
	 * platforms and should never be accessed from application code.
	 * </p>
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	public id internal_accessibilityAttributeValue(NSString attribute, int childID) {
		if (attribute.isEqualToString(OS.NSAccessibilityRoleAttribute)) return getRoleAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilitySubroleAttribute)) return getSubroleAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityRoleDescriptionAttribute)) return getRoleDescriptionAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityExpandedAttribute)) return getExpandedAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityHelpAttribute)) return getHelpAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityTitleAttribute)) return getTitleAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityValueAttribute)) return getValueAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityMaxValueAttribute)) return getMaxValueAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityMinValueAttribute)) return getMinValueAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityEnabledAttribute)) return getEnabledAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityFocusedAttribute)) return getFocusedAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityParentAttribute)) return getParentAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityChildrenAttribute)) return getChildrenAttribute(childID, false);
		if (attribute.isEqualToString(OS.NSAccessibilityVisibleChildrenAttribute)) return getChildrenAttribute(childID, true);
		if (attribute.isEqualToString(OS.NSAccessibilityContentsAttribute)) return getChildrenAttribute(childID, false);
		// FIXME:  There's no specific API just for tabs, which won't include the buttons (if any.)
		if (attribute.isEqualToString(OS.NSAccessibilityTabsAttribute)) return getTabsAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityWindowAttribute)) return getWindowAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityTopLevelUIElementAttribute)) return getTopLevelUIElementAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityPositionAttribute)) return getPositionAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilitySizeAttribute)) return getSizeAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityDescriptionAttribute)) return getDescriptionAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityNumberOfCharactersAttribute)) return getNumberOfCharactersAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilitySelectedTextAttribute)) return getSelectedTextAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilitySelectedTextRangeAttribute)) return getSelectedTextRangeAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityInsertionPointLineNumberAttribute)) return getInsertionPointLineNumberAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilitySelectedTextRangesAttribute)) return getSelectedTextRangesAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityVisibleCharacterRangeAttribute)) return getVisibleCharacterRangeAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityServesAsTitleForUIElementsAttribute)) return getServesAsTitleForUIElementsAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityTitleUIElementAttribute)) return getTitleUIElementAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityColumnsAttribute)) return getColumnsAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilitySelectedColumnsAttribute)) return getSelectedColumnsAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityRowsAttribute)) return getRowsAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilitySelectedRowsAttribute)) return getSelectedRowsAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityVisibleRowsAttribute)) return getVisibleRowsAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityVisibleColumnsAttribute)) return getVisibleColumnsAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityHeaderAttribute)) return getHeaderAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilityIndexAttribute)) return getIndexAttribute(childID);
		if (attribute.isEqualToString(OS.NSAccessibilitySelectedAttribute)) return getSelectedAttribute(childID);
		if (OS.VERSION >= 0x1060 && attribute.isEqualToString(OS.NSAccessibilityRowIndexRangeAttribute)) return getRowIndexRangeAttribute(childID);
		if (OS.VERSION >= 0x1060 && attribute.isEqualToString(OS.NSAccessibilityColumnIndexRangeAttribute)) return getColumnIndexRangeAttribute(childID);

		// If this object don't know how to get the value it's up to the control itself to return an attribute value.
		return null;
	}

	/**
	 * Returns the value of the specified attribute, using the supplied parameter. Return
	 * and parameter types vary depending on the attribute being queried.
	 * <p>
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. It is marked public only so that it can be shared
	 * within the packages provided by SWT. It is not available on all
	 * platforms and should never be accessed from application code.
	 * </p>
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	public id internal_accessibilityAttributeValue_forParameter(NSString attribute, id parameter, int childID) {
		if (attribute.isEqualToString(OS.NSAccessibilityStringForRangeParameterizedAttribute)) return getStringForRangeParameterizedAttribute(parameter, childID);
		if (attribute.isEqualToString(OS.NSAccessibilityRangeForLineParameterizedAttribute)) return getRangeForLineParameterizedAttribute(parameter, childID);
		if (attribute.isEqualToString(OS.NSAccessibilityRangeForIndexParameterizedAttribute)) return getRangeForIndexParameterizedAttribute(parameter, childID);
		if (attribute.isEqualToString(OS.NSAccessibilityLineForIndexParameterizedAttribute)) return getLineForIndexParameterizedAttribute(parameter, childID);
		if (attribute.isEqualToString(OS.NSAccessibilityBoundsForRangeParameterizedAttribute)) return getBoundsForRangeParameterizedAttribute(parameter, childID);
		if (attribute.isEqualToString(OS.NSAccessibilityRangeForPositionParameterizedAttribute)) return getRangeForPositionParameterizedAttribute(parameter, childID);
		if (attribute.isEqualToString(OS.NSAccessibilityAttributedStringForRangeParameterizedAttribute)) return getAttributedStringForRangeParameterizedAttribute(parameter, childID);
		if (attribute.isEqualToString(OS.NSAccessibilityStyleRangeForIndexParameterizedAttribute)) return getStyleRangeForIndexAttribute(parameter, childID);
		if (OS.VERSION >= 0x1060 && attribute.isEqualToString(OS.NSAccessibilityCellForColumnAndRowParameterizedAttribute)) return getCellForColumnAndRowParameter(parameter, childID);
		return null;
	}

	/**
	 * Returns the UI Element that has the focus. You can assume that the search
	 * for the focus has already been narrowed down to the receiver.
	 * Override this method to do a deeper search with a UIElement -
	 * e.g. a NSMatrix would determine if one of its cells has the focus.
	 * <p>
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. It is marked public only so that it can be shared
	 * within the packages provided by SWT. It is not available on all
	 * platforms and should never be accessed from application code.
	 * </p>
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	public id internal_accessibilityFocusedUIElement(int childID) {
		AccessibleControlEvent event = new AccessibleControlEvent(this);
		event.childID = ACC.CHILDID_MULTIPLE; // set to invalid value, to test if the application sets it in getFocus()
		event.accessible = null;
		for (int i = 0; i < accessibleControlListenersSize(); i++) {
			AccessibleControlListener listener = accessibleControlListeners.get(i);
			listener.getFocus(event);
		}

		// The listener did not respond, so let Cocoa figure it out.
		if (event.childID == ACC.CHILDID_MULTIPLE)
			return null;

		/* The application can optionally answer an accessible. */
		if (event.accessible != null) {
			return new id(OS.NSAccessibilityUnignoredAncestor(event.accessible.control.view.id));
		}

		/* Or the application can answer a valid child ID, including CHILDID_SELF and CHILDID_NONE. */
		if (event.childID == ACC.CHILDID_SELF || event.childID == ACC.CHILDID_NONE) {
			return new id(OS.NSAccessibilityUnignoredAncestor(control.view.id));
		}

		return new id(OS.NSAccessibilityUnignoredAncestor(childIDToOs(event.childID).id));
	}

	/**
	 * Returns the deepest descendant of the UIElement hierarchy that contains the point.
	 * You can assume the point has already been determined to lie within the receiver.
	 * Override this method to do deeper hit testing within a UIElement - e.g. a NSMatrix
	 * would test its cells. The point is bottom-left relative screen coordinates.
	 *
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. It is marked public only so that it can be shared
	 * within the packages provided by SWT. It is not available on all
	 * platforms and should never be accessed from application code.
	 * </p>
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	public id internal_accessibilityHitTest(NSPoint point, int childID) {
		AccessibleControlEvent event = new AccessibleControlEvent(this);
		event.x = (int) point.x;
		Monitor primaryMonitor = Display.getCurrent().getPrimaryMonitor();
		event.y = (int) (primaryMonitor.getBounds().height - point.y);

		// Set an impossible value to determine if anything responded to the event.
		event.childID = ACC.CHILDID_MULTIPLE;
		for (int i = 0; i < accessibleControlListenersSize(); i++) {
			AccessibleControlListener listener = accessibleControlListeners.get(i);
			listener.getChildAtPoint(event);
		}

		// The listener did not respond, so let Cocoa figure it out.
		if (event.childID == ACC.CHILDID_MULTIPLE && event.accessible == null)
			return null;

		if (event.accessible != null) {
			return new id(OS.NSAccessibilityUnignoredAncestor(event.accessible.delegate.id));
		}

		if (event.childID == ACC.CHILDID_SELF || event.childID == ACC.CHILDID_NONE) {
			return new id(OS.NSAccessibilityUnignoredAncestor(control.view.id));
		}

		return new id(OS.NSAccessibilityUnignoredAncestor(childIDToOs(event.childID).id));
	}

	/**
	 * Return YES if the UIElement doesn't show up to the outside world -
	 * i.e. its parent should return the UIElement's children as its own -
	 * cutting the UIElement out. E.g. NSControls are ignored when they are single-celled.
	 *
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. It is marked public only so that it can be shared
	 * within the packages provided by SWT. It is not available on all
	 * platforms and should never be accessed from application code.
	 * </p>
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	public boolean internal_accessibilityIsIgnored(int childID) {
		AccessibleControlEvent event = new AccessibleControlEvent(this);
		event.childID = childID;
		event.detail = -1;
		for (int i = 0; i < accessibleControlListenersSize(); i++) {
			AccessibleControlListener listener = accessibleControlListeners.get(i);
			listener.getRole(event);
		}

		boolean shouldIgnore = (event.detail == -1);

		if (shouldIgnore) {
			shouldIgnore = getTitleAttribute(childID) == null && getHelpAttribute(childID) == null && getDescriptionAttribute(childID) == null;
		}

		return shouldIgnore;
	}

	/**
	 * Return the array of supported attributes that take parameters.
	 *
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. It is marked public only so that it can be shared
	 * within the packages provided by SWT. It is not available on all
	 * platforms and should never be accessed from application code.
	 * </p>
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	public NSArray internal_accessibilityParameterizedAttributeNames(int childID) {
		AccessibleControlEvent event = new AccessibleControlEvent(this);
		event.childID = childID;
		event.detail = -1;
		for (int i = 0; i < accessibleControlListenersSize(); i++) {
			AccessibleControlListener listener = accessibleControlListeners.get(i);
			listener.getRole(event);
		}

		// No accessible listener is overriding the role of the control, so let Cocoa
		// return the default set for the control.
		if (event.detail == -1)
			return null;

		checkRole(event.detail);

		if ((childID == ACC.CHILDID_SELF) && (parameterizedAttributeNames != null)) {
			return retainedAutoreleased(parameterizedAttributeNames);
		}

		NSMutableArray returnValue = NSMutableArray.arrayWithCapacity(4);

		switch(event.detail) {
			case ACC.ROLE_TEXT:
			case ACC.ROLE_PARAGRAPH:
			case ACC.ROLE_HEADING:
				returnValue.addObject(OS.NSAccessibilityStringForRangeParameterizedAttribute);
				returnValue.addObject(OS.NSAccessibilityRangeForLineParameterizedAttribute);
				returnValue.addObject(OS.NSAccessibilityRangeForIndexParameterizedAttribute);
				returnValue.addObject(OS.NSAccessibilityLineForIndexParameterizedAttribute);
				returnValue.addObject(OS.NSAccessibilityBoundsForRangeParameterizedAttribute);
				returnValue.addObject(OS.NSAccessibilityRangeForPositionParameterizedAttribute);
				returnValue.addObject(OS.NSAccessibilityAttributedStringForRangeParameterizedAttribute);
				returnValue.addObject(OS.NSAccessibilityStyleRangeForIndexParameterizedAttribute);
				break;
			case ACC.ROLE_TABLE:
				if (OS.VERSION >= 0x1060) returnValue.addObject(OS.NSAccessibilityCellForColumnAndRowParameterizedAttribute);
				break;
		}

		if (childID == ACC.CHILDID_SELF) {
			parameterizedAttributeNames = returnValue;
			parameterizedAttributeNames.retain();
			return retainedAutoreleased(parameterizedAttributeNames);
		} else {
			// Caller must retain if they want to keep it.
			return returnValue;
		}
	}

	/**
	 * Performs the specified action.
	 *
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. It is marked public only so that it can be shared
	 * within the packages provided by SWT. It is not available on all
	 * platforms and should never be accessed from application code.
	 * </p>
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	public boolean internal_accessibilityPerformAction(NSString action, int childID) {
		String actionName = action.getString();
		if (accessibleActionListenersSize() > 0) {
			AccessibleActionEvent event = new AccessibleActionEvent(this);
			for (int i = 0; i < accessibleActionListenersSize(); i++) {
				AccessibleActionListener listener = accessibleActionListeners.get(i);
				listener.getActionCount(event);
			}
			int index = -1;
			for (int i = 0; i < event.count; i++) {
				event.index = i;
				for (int j = 0; j < accessibleActionListenersSize(); j++) {
					AccessibleActionListener listener = accessibleActionListeners.get(j);
					listener.getName(event);
				}
				if (actionName.equals(event.result)) {
					index = i;
					break;
				}
			}
			if (index != -1) {
				event.index = index;
				event.result = null;
				for (int i = 0; i < accessibleActionListenersSize(); i++) {
					AccessibleActionListener listener = accessibleActionListeners.get(i);
					listener.doAction(event);
				}
				return ACC.OK.equals(event.result);
			}
		}
		return false;
	}

	/**
	 * Set the value of the specified attribute to the given value.
	 * Unsupported attributes are ignored.
	 *
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. It is marked public only so that it can be shared
	 * within the packages provided by SWT. It is not available on all
	 * platforms and should never be accessed from application code.
	 * </p>
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	public void internal_accessibilitySetValue_forAttribute(id value, NSString attribute, int childId) {
		if (attribute.isEqualToString(OS.NSAccessibilitySelectedTextRangeAttribute)) setSelectedTextRangeAttribute(value, childId);
		if (attribute.isEqualToString(OS.NSAccessibilitySelectedTextAttribute)) setSelectedTextAttribute(value, childId);
		if (attribute.isEqualToString(OS.NSAccessibilityVisibleCharacterRangeAttribute)) setVisibleCharacterRangeAttribute(value, childId);

		if (accessibleValueListenersSize() > 0) {
			AccessibleValueEvent event = new AccessibleValueEvent(this);
			NSNumber number = new NSNumber(value);
			event.value = new Double(number.doubleValue());
			for (int i = 0; i < accessibleValueListenersSize(); i++) {
				AccessibleValueListener listener = accessibleValueListeners.get(i);
				listener.setCurrentValue(event);
			}
		}
	}

	/**
	 * Disposes of the operating system resources associated with
	 * the receiver, and removes the receiver from its parent's
	 * list of children.
	 * <p>
	 * This method should be called when an accessible that was created
	 * with the public constructor <code>Accessible(Accessible parent)</code>
	 * is no longer needed. You do not need to call this when the receiver's
	 * control is disposed, because all <code>Accessible</code> instances
	 * associated with a control are released when the control is disposed.
	 * It is also not necessary to call this for instances of <code>Accessible</code>
	 * that were retrieved with <code>Control.getAccessible()</code>.
	 * </p>
	 *
	 * @since 3.6
	 */
	public void dispose () {
		if (parent == null) return;
		release(true);
		parent = null;
	}

	/**
	 * Returns the control for this Accessible object.
	 *
	 * @return the receiver's control
	 * @since 3.0
	 */
	public Control getControl() {
		return control;
	}

	/**
	 * Invokes platform specific functionality to dispose an accessible object.
	 * <p>
	 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
	 * API for <code>Accessible</code>. It is marked public only so that it
	 * can be shared within the packages provided by SWT. It is not
	 * available on all platforms, and should never be called from
	 * application code.
	 * </p>
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	public void internal_dispose_Accessible() {
		release(true);
	}

	id getAttributedStringForRangeParameterizedAttribute(id parameter, int childID) {
		if (accessibleAttributeListenersSize() == 0) return null;

		id stringFragment = getStringForRangeParameterizedAttribute(parameter, childID);
		NSMutableAttributedString attribString = (NSMutableAttributedString)new NSMutableAttributedString().alloc();
		attribString.initWithString(new NSString(stringFragment), null);
		attribString.autorelease();

		// Parameter is an NSRange wrapped in an NSValue.
		NSValue parameterObject = new NSValue(parameter.id);
		NSRange range = parameterObject.rangeValue();

		AccessibleTextAttributeEvent event = new AccessibleTextAttributeEvent(this);

		event.offset = (int) /*64*/ range.location;
		event.start = event.end = -1;

		NSRange attributeRange = new NSRange();

		while (event.offset < range.location + range.length) {
			for (int i = 0; i < accessibleAttributeListenersSize(); i++) {
				AccessibleAttributeListener listener = accessibleAttributeListeners.get(i);
				listener.getTextAttributes(event);
			}

			if (event.start == -1 && event.end == -1) return stringFragment;

			// The returned attributed string must have zero-based attributes.
			attributeRange.location = event.start - range.location;
			attributeRange.length = event.end - event.start;

			// attributeRange.location can be negative if the start of the requested range falls in the middle of a style run.
			// If that happens, clamp to zero and adjust the length by the amount of adjustment.
			if (attributeRange.location < 0) {
				attributeRange.length -= -attributeRange.location;
				attributeRange.location = 0;
			}

			// Likewise, make sure the last attribute set does not run past the end of the requested range.
			if (attributeRange.location + attributeRange.length > range.length) {
				attributeRange.length = range.length - attributeRange.location;
			}

			// Reset the offset so we pick up the next set of attributes that change.
			event.offset = event.end;

			if (event.textStyle != null) {
				TextStyle ts = event.textStyle;
				if (ts.font != null) {
					NSMutableDictionary fontInfoDict = NSMutableDictionary.dictionaryWithCapacity(4);

					NSFont fontUsed = ts.font.handle;
					// Get font name and size from NSFont
					NSString fontName = fontUsed.fontName();
					fontInfoDict.setValue(fontName, OS.NSAccessibilityFontNameKey);
					NSString familyName = fontUsed.familyName();
					fontInfoDict.setValue(familyName, OS.NSAccessibilityFontFamilyKey);
					NSString displayName = fontUsed.displayName();
					fontInfoDict.setValue(displayName, OS.NSAccessibilityVisibleNameKey);
					double /*float*/ fontSize = fontUsed.pointSize();
					fontInfoDict.setValue(NSNumber.numberWithDouble(fontSize), OS.NSAccessibilityFontSizeKey);

					attribString.addAttribute(OS.NSAccessibilityFontTextAttribute, fontInfoDict, attributeRange);
				}

				if (ts.foreground != null) {
					addCGColor(ts.foreground.handle, attribString, OS.NSAccessibilityForegroundColorTextAttribute, attributeRange);
				}

				if (ts.background != null) {
					addCGColor(ts.background.handle, attribString, OS.NSAccessibilityBackgroundColorTextAttribute, attributeRange);
				}

				if (ts.underline) {
					int style = ts.underlineStyle;
					NSString attribute = OS.NSAccessibilityUnderlineTextAttribute;
					NSNumber styleObj = null;
					switch (style) {
					case SWT.UNDERLINE_SINGLE:
						styleObj = NSNumber.numberWithInt(OS.kAXUnderlineStyleSingle);
						break;
					case SWT.UNDERLINE_DOUBLE:
						styleObj = NSNumber.numberWithInt(OS.kAXUnderlineStyleDouble);
						break;
					case SWT.UNDERLINE_SQUIGGLE:
						attribute = OS.NSAccessibilityMisspelledTextAttribute;
						styleObj = NSNumber.numberWithBool(true);
						break;
					default:
						styleObj = NSNumber.numberWithInt(OS.kAXUnderlineStyleNone);
					}

					attribString.addAttribute(attribute, styleObj, attributeRange);
				}

				if (ts.underlineColor != null) {
					addCGColor(ts.underlineColor.handle, attribString, OS.NSAccessibilityUnderlineColorTextAttribute, attributeRange);
				}

				if (ts.strikeout) {
					attribString.addAttribute(OS.NSAccessibilityStrikethroughTextAttribute, NSNumber.numberWithBool(true), attributeRange);

					if (ts.strikeoutColor != null) {
						addCGColor(ts.strikeoutColor.handle, attribString, OS.NSAccessibilityStrikethroughColorTextAttribute, attributeRange);
					}
				}

				if (ts.data != null) {
					if (ts.data instanceof URL) {
						URL dataAsURL = (URL)ts.data;
						NSURL linkURL = NSURL.URLWithString(NSString.stringWith(dataAsURL.toExternalForm()));
						attribString.addAttribute(OS.NSAccessibilityLinkTextAttribute, linkURL, attributeRange);
					}
				}
			}
		}

		// Now add the alignment, justification, and indent, if available.
		AccessibleAttributeEvent docAttributes = new AccessibleAttributeEvent(this);
		docAttributes.indent = Integer.MAX_VALUE; // if unchanged no listener filled it in.
		for (int i = 0; i < accessibleAttributeListenersSize(); i++) {
			AccessibleAttributeListener listener = accessibleAttributeListeners.get(i);
			listener.getAttributes(docAttributes);
		}

		if (docAttributes.indent != Integer.MAX_VALUE) {
			NSMutableDictionary paragraphDict = NSMutableDictionary.dictionaryWithCapacity(3);
			int osAlignment = 0;
			// FIXME: Doesn't account for right-to-left text?
			switch (docAttributes.alignment) {
			case SWT.CENTER:
				osAlignment = OS.NSCenterTextAlignment;
				break;
			case SWT.RIGHT:
				osAlignment = OS.NSRightTextAlignment;
				break;
			case SWT.LEFT:
			default:
				osAlignment = OS.NSLeftTextAlignment;
				break;
			}
			paragraphDict.setValue(NSNumber.numberWithInt(osAlignment), NSString.stringWith("AXTextAlignment"));
			range.location = 0;
			attribString.addAttribute(NSString.stringWith("AXParagraphStyle"), paragraphDict, range);
		}

		return attribString;
	}

	id getBoundsForRangeParameterizedAttribute(id parameter, int childID) {
		if (accessibleTextExtendedListenersSize() == 0) return null;

		id returnValue = null;
		NSValue parameterObject = new NSValue(parameter.id);
		NSRange range = parameterObject.rangeValue();
		NSRect rect = new NSRect();
		if (accessibleTextExtendedListenersSize() > 0) {
			AccessibleTextEvent event  = new AccessibleTextEvent(this);
			event.childID = childID;
			event.start = (int)/*64*/range.location;
			event.end = (int)/*64*/(range.location + range.length);
			for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
				AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
				listener.getTextBounds(event);
			}
			rect.x = event.x;

			// Flip y coordinate for Cocoa.
			NSArray screens = NSScreen.screens();
			NSScreen screen = new NSScreen(screens.objectAtIndex(0));
			NSRect frame = screen.frame();
			rect.y = frame.height - event.y - event.height;

			rect.width = event.width;
			rect.height = event.height;
			returnValue = NSValue.valueWithRect(rect);
		} else {
			//FIXME???
			//how to implement with old listener
		}
		return returnValue;
	}

	id getExpandedAttribute(int childID) {
		// TODO: May need to expand the API so the combo box state can be reported.
		return NSNumber.numberWithBool(false);
	}

	id getHelpAttribute (int childID) {
		id returnValue = null;
		AccessibleEvent event = new AccessibleEvent(this);
		event.childID = childID;
		for (int i = 0; i < accessibleListenersSize(); i++) {
			AccessibleListener listener = accessibleListeners.get(i);
			listener.getHelp(event);
		}

		if (event.result != null) {
			returnValue = NSString.stringWith(event.result);
		}

		return returnValue;
	}

	id getRangeForPositionParameterizedAttribute(id parameter, int childID) {
		id returnValue = null;
		NSValue parameterObject = new NSValue(parameter.id);
		NSPoint point = parameterObject.pointValue();
		NSRange range = new NSRange();
		if (accessibleTextExtendedListenersSize() > 0) {
			NSArray screens = NSScreen.screens();
			NSScreen screen = new NSScreen(screens.objectAtIndex(0));
			NSRect frame = screen.frame();
			point.y = frame.height - point.y;
			AccessibleTextEvent event  = new AccessibleTextEvent(this);
			event.childID = childID;
			event.x = (int)point.x;
			event.y = (int)point.y;
			for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
				AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
				listener.getOffsetAtPoint(event);
			}
			range.location = event.offset;
			range.length = 1;
		} else {
			//FIXME???
			//how to implement with old listener
		}
		returnValue = NSValue.valueWithRange(range);
		return returnValue;
	}

	NSString getRoleAttribute(int childID) {
		NSString returnValue = null;
		AccessibleControlEvent event = new AccessibleControlEvent(this);
		event.childID = childID;
		event.detail = -1;
		for (int i = 0; i < accessibleControlListenersSize(); i++) {
			AccessibleControlListener listener = accessibleControlListeners.get(i);
			listener.getRole(event);
		}
		if (event.detail != -1) {
			String appRole = roleToOs (event.detail);
			int index = appRole.indexOf(':');
			if (index != -1) appRole = appRole.substring(0, index);
			returnValue = NSString.stringWith(appRole);
		}

		return returnValue;
	}

	id getSubroleAttribute (int childID) {
		id returnValue = null;
		AccessibleControlEvent event = new AccessibleControlEvent(this);
		event.childID = childID;
		event.detail = -1;
		for (int i = 0; i < accessibleControlListenersSize(); i++) {
			AccessibleControlListener listener = accessibleControlListeners.get(i);
			listener.getRole(event);
		}
		if (event.detail != -1) {
			String appRole = roleToOs (event.detail);
			int index = appRole.indexOf(':');
			if (index != -1) {
				appRole = appRole.substring(index + 1);
				returnValue = NSString.stringWith(appRole);
			}
		}
		return returnValue;
	}

	id getRoleDescriptionAttribute (int childID) {
		id returnValue = null;
		AccessibleControlEvent event = new AccessibleControlEvent(this);
		event.childID = childID;
		event.detail = -1;
		for (int i = 0; i < accessibleControlListenersSize(); i++) {
			AccessibleControlListener listener = accessibleControlListeners.get(i);
			listener.getRole(event);
		}
		if (event.detail != -1) {
			if (event.detail == ACC.ROLE_TABITEM) {
				returnValue = new NSString(OS.NSAccessibilityRoleDescription (NSString.stringWith("AXTab").id, 0));
			} else {
				String appRole = roleToOs (event.detail);
				String appSubrole = null;
				int index = appRole.indexOf(':');
				if (index != -1) {
					appSubrole = appRole.substring(index + 1);
					appRole = appRole.substring(0, index);
				}
				NSString nsAppRole = NSString.stringWith(appRole);
				NSString nsAppSubrole = null;

				if (appSubrole != null) nsAppSubrole = NSString.stringWith(appSubrole);
				returnValue = new NSString(OS.NSAccessibilityRoleDescription (((nsAppRole != null) ? nsAppRole.id : 0), (nsAppSubrole != null) ? nsAppSubrole.id : 0));
			}
		}
		return returnValue;
	}

	id getTitleAttribute (int childID) {

		id returnValue = null;

		/*
		* Feature of the Macintosh.  The text of a Label is returned in its value,
		* not its title, so ensure that the role is not Label before asking for the title.
		*/
		AccessibleControlEvent roleEvent = new AccessibleControlEvent(this);
		roleEvent.childID = childID;
		roleEvent.detail = -1;
		for (int i = 0; i < accessibleControlListenersSize(); i++) {
			AccessibleControlListener listener = accessibleControlListeners.get(i);
			listener.getRole(roleEvent);
		}
		if (roleEvent.detail != ACC.ROLE_LABEL) {
			AccessibleEvent event = new AccessibleEvent(this);
			event.childID = childID;
			event.result = null;
			for (int i = 0; i < accessibleListenersSize(); i++) {
				AccessibleListener listener = accessibleListeners.get(i);
				listener.getName(event);
			}

			if (event.result != null)
				returnValue = NSString.stringWith(event.result);
		}
		return returnValue;
	}

	id getTitleUIElementAttribute(int childID) {
		id returnValue = null;
		Relation relation = relations[ACC.RELATION_LABELLED_BY];
		if (relation != null) {
			returnValue = relation.getTitleUIElement();
		}
		return returnValue;
	}

	id getValueAttribute (int childID) {
		id returnValue = null;
		if (accessibleValueListenersSize() > 0) {
			AccessibleValueEvent event = new AccessibleValueEvent(this);
			for (int i = 0; i < accessibleValueListenersSize(); i++) {
				AccessibleValueListener listener = accessibleValueListeners.get(i);
				listener.getCurrentValue(event);
			}
			returnValue = NSNumber.numberWithDouble(event.value.doubleValue());
		} else {
			AccessibleControlEvent event = new AccessibleControlEvent(this);
			event.childID = childID;
			event.detail = -1;
			event.result = null; //TODO: could pass the OS value to the app
			for (int i = 0; i < accessibleControlListenersSize(); i++) {
				AccessibleControlListener listener = accessibleControlListeners.get(i);
				listener.getRole(event);
				listener.getValue(event);
			}
			int role = event.detail;
			String value = event.result;

			switch (role) {
				case ACC.ROLE_RADIOBUTTON: // 1 = on, 0 = off
				case ACC.ROLE_CHECKBUTTON: // 1 = checked, 0 = unchecked, 2 = mixed
				case ACC.ROLE_SCROLLBAR: // numeric value representing the position of the scroller
				case ACC.ROLE_SLIDER: // the value associated with the position of the slider thumb
				case ACC.ROLE_PROGRESSBAR: // the value associated with the fill level of the progress bar
					if (value != null) {
						try {
							int number = Integer.parseInt(value);
							returnValue = NSNumber.numberWithBool(number == 0 ? false : true);
						} catch (NumberFormatException ex) {
							if (value.equalsIgnoreCase("true")) {
								returnValue = NSNumber.numberWithBool(true);
							} else if (value.equalsIgnoreCase("false")) {
								returnValue = NSNumber.numberWithBool(false);
							}
						}
					} else {
						returnValue = NSNumber.numberWithBool(false);
					}
					break;
				case ACC.ROLE_TABFOLDER: // the accessibility object representing the currently selected tab item
				case ACC.ROLE_TABITEM:  // 1 = selected, 0 = not selected
					AccessibleControlEvent ace = new AccessibleControlEvent(this);
					ace.childID = -4;
					for (int i = 0; i < accessibleControlListenersSize(); i++) {
						AccessibleControlListener listener = accessibleControlListeners.get(i);
						listener.getSelection(ace);
					}
					if (ace.childID >= ACC.CHILDID_SELF) {
						if (role == ACC.ROLE_TABITEM) {
					 		returnValue = NSNumber.numberWithBool(ace.childID == childID);
						} else {
							returnValue = new id(OS.NSAccessibilityUnignoredAncestor(childIDToOs(ace.childID).id));
						}
					} else {
				 		returnValue = NSNumber.numberWithBool(false);
					}
					break;
				case ACC.ROLE_COMBOBOX: // text of the currently selected item
				case ACC.ROLE_TEXT: // text in the text field
				case ACC.ROLE_PARAGRAPH: // text in the text field
				case ACC.ROLE_HEADING: // text in the text field
					if (value != null) returnValue = NSString.stringWith(value);
					break;
				case ACC.ROLE_TABLECELL: // text in the cell
				case ACC.ROLE_LABEL: // text in the label
					/* On a Mac, the 'value' of a label is the same as the 'name' of the label. */
					AccessibleEvent e = new AccessibleEvent(this);
					e.childID = childID;
					e.result = null;
					for (int i = 0; i < accessibleListenersSize(); i++) {
						AccessibleListener listener = accessibleListeners.get(i);
						listener.getName(e);
					}
					if (e.result != null) {
						returnValue = NSString.stringWith(e.result);
					} else {
						if (value != null) returnValue = NSString.stringWith(value);
					}
					returnValue = returnValue == null ? NSString.string() : returnValue;
					break;
			}
		}
		return returnValue;
	}

	id getEnabledAttribute (int childID) {
		AccessibleControlEvent event = new AccessibleControlEvent(this);
		event.detail = ACC.STATE_NORMAL;
		event.childID = childID;
		for (int i = 0; i < accessibleControlListenersSize(); i++) {
			AccessibleControlListener listener = accessibleControlListeners.get(i);
			listener.getState(event);
		}
		boolean enabled = (event.detail & ACC.STATE_DISABLED) == 0;
		if (!enabled && delegate == null) enabled = control.isEnabled();
		return NSNumber.numberWithBool(enabled);
	}

	id getFocusedAttribute (int childID) {
		AccessibleControlEvent event = new AccessibleControlEvent(this);
		event.childID = ACC.CHILDID_MULTIPLE; // set to invalid value, to test if the application sets it in getFocus()
		for (int i = 0; i < accessibleControlListenersSize(); i++) {
			AccessibleControlListener listener = accessibleControlListeners.get(i);
			listener.getFocus(event);
		}

		/* The application can optionally answer an accessible. */
		if (event.accessible != null) {
			boolean hasFocus = (event.accessible.index == childID) && (event.accessible.control == this.control);
			return NSNumber.numberWithBool(hasFocus);
		}

		/* Or the application can answer a valid child ID, including CHILDID_SELF and CHILDID_NONE. */
		if (event.childID == ACC.CHILDID_SELF) {
			return NSNumber.numberWithBool(true);
		}
		if (event.childID == ACC.CHILDID_NONE) {
			return NSNumber.numberWithBool(false);
		}
		if (event.childID != ACC.CHILDID_MULTIPLE) {
			/* Other valid childID. */
			return NSNumber.numberWithBool(event.childID == childID);
		}

		// Invalid childID at this point means the application did not implement getFocus, so
		// let the default handler return the native focus.
		return null;
	}

	id getParentAttribute (int childID) {
		id returnValue = null;
		if (childID == ACC.CHILDID_SELF) {
			if (parent != null) {
				if (parent.delegate != null) {
					returnValue = parent.delegate;
				} else {
					returnValue = new id(OS.NSAccessibilityUnignoredAncestor(accessibleHandle(parent).id));
				}
			} else {
				// Returning null here means 'let Cocoa figure it out.'
				returnValue = null;
			}
		} else {
			returnValue = new id(OS.NSAccessibilityUnignoredAncestor(accessibleHandle(this).id));
		}
		return returnValue;
	}

	id getChildrenAttribute (int childID, boolean visibleOnly) {
		id returnValue = null;
		if (childID == ACC.CHILDID_SELF) {
			// Test for a table first.
			if (currentRole == ACC.ROLE_TABLE) {
				// If the row count differs from the row elements returned,
				// we need to create our own adapter to map the cells onto
				// rows and columns.  The rows and columns attributes determine that for us.
				getRowsAttribute(childID);
				getColumnsAttribute(childID);
			}

			AccessibleControlEvent event = new AccessibleControlEvent(this);
			event.childID = childID;
			event.detail = -1; // set to impossible value to test if app resets
			for (int i = 0; i < accessibleControlListenersSize(); i++) {
				AccessibleControlListener listener = accessibleControlListeners.get(i);
				listener.getChildCount(event);
			}
			int childCount = event.detail;
			event.detail = (visibleOnly ? ACC.VISIBLE : 0);
			if (childCount >= 0) {
				for (int i = 0; i < accessibleControlListenersSize(); i++) {
					AccessibleControlListener listener = accessibleControlListeners.get(i);
					listener.getChildren(event);
				}
				Object[] children = event.children;
				childCount = children != null ? children.length : 0;
				NSMutableArray childArray = NSMutableArray.arrayWithCapacity(childCount);
				for (int i = 0; i < childCount; i++) {
					Object child = children[i];
					if (child instanceof Accessible) {
						Accessible accessible = (Accessible)child;
						if (accessible.delegate != null) {
							childArray.addObject(accessible.delegate);
						} else {
							childArray.addObject(accessibleHandle(accessible));
						}
					} else {
						if (child instanceof Integer) {
							id accChild = childIDToOs(((Integer)child).intValue());
							childArray.addObject(accChild);
						}
					}
				}
				returnValue = new id(OS.NSAccessibilityUnignoredChildren(childArray.id));
			}
		} else {
			// Lightweight children have no children of their own.
			// Don't return null if there are no children -- always return an empty array.
			returnValue = NSArray.array();
		}

		// Returning null here means we want the control itself to determine its children. If the accessible listener
		// implemented getChildCount/getChildren, references to those objects would have been returned above.
		return returnValue;
	}

	id getTabsAttribute (int childID) {
		id returnValue = null;
		if (childID == ACC.CHILDID_SELF) {
			AccessibleControlEvent event = new AccessibleControlEvent(this);
			event.childID = childID;
			event.detail = -1; // set to impossible value to test if app resets
			for (int i = 0; i < accessibleControlListenersSize(); i++) {
				AccessibleControlListener listener = accessibleControlListeners.get(i);
				listener.getChildCount(event);
			}
			if (event.detail > 0) {
				for (int i = 0; i < accessibleControlListenersSize(); i++) {
					AccessibleControlListener listener = accessibleControlListeners.get(i);
					listener.getChildren(event);
				}
				Object [] appChildren = event.children;
				if (appChildren != null && appChildren.length > 0) {
					/* return an NSArray of NSAccessible objects. */
					NSMutableArray childArray = NSMutableArray.arrayWithCapacity(appChildren.length);

					for (int i = 0; i < appChildren.length; i++) {
						Object child = appChildren[i];
						if (child instanceof Integer) {
							int subChildID = ((Integer)child).intValue();
							event.childID = subChildID;
							event.detail = -1;
							for (int j = 0; j < accessibleControlListenersSize(); j++) {
								AccessibleControlListener listener = accessibleControlListeners.get(j);
								listener.getRole(event);
							}

							if (event.detail == ACC.ROLE_TABITEM) {
								id accChild = childIDToOs(((Integer)child).intValue());
								childArray.addObject(accChild);
							}
						} else {
							childArray.addObject(((Accessible)child).control.view);
						}
					}

					returnValue = new id(OS.NSAccessibilityUnignoredChildren(childArray.id));
				}
			}
		} else {
			// Lightweight children have no children of their own.
			// Don't return null if there are no children -- always return an empty array.
			returnValue = NSArray.array();
		}

		// Returning null here means we want the control itself to determine its children. If the accessible listener
		// implemented getChildCount/getChildren, references to those objects would have been returned above.
		return returnValue;
	}

	id getWindowAttribute (int childID) {
		return control.view.window();
	}

	id getTopLevelUIElementAttribute (int childID) {
		return control.view.window();
	}

	id getPositionAttribute (int childID) {
		id returnValue = null;
		AccessibleControlEvent event = new AccessibleControlEvent(this);
		event.childID = childID;
		event.width = -1;

		for (int i = 0; i < accessibleControlListenersSize(); i++) {
			AccessibleControlListener listener = accessibleControlListeners.get(i);
			listener.getLocation(event);
		}

		Monitor primaryMonitor = Display.getCurrent().getPrimaryMonitor();

		NSPoint osPositionAttribute = new NSPoint ();
		if (event.width != -1) {
			// The point returned is the lower-left coordinate of the widget in lower-left relative screen coordinates.
			osPositionAttribute.x = event.x;
			osPositionAttribute.y = primaryMonitor.getBounds().height - event.y - event.height;
			returnValue = NSValue.valueWithPoint(osPositionAttribute);
		} else {
			if (childID != ACC.CHILDID_SELF) {
				Point pt = null;
				Rectangle location = control.getBounds();

				if (control.getParent() != null)
					pt = control.getParent().toDisplay(location.x, location.y);
				else
					pt = ((Shell)control).toDisplay(location.x, location.y);

				osPositionAttribute.x = pt.x;
				osPositionAttribute.y = pt.y;
				returnValue = NSValue.valueWithPoint(osPositionAttribute);
			}
		}

		return returnValue;
	}

	id getSizeAttribute (int childID) {
		id returnValue = null;
		AccessibleControlEvent event = new AccessibleControlEvent(this);
		event.childID = childID;
		event.width = -1;

		for (int i = 0; i < accessibleControlListenersSize(); i++) {
			AccessibleControlListener listener = accessibleControlListeners.get(i);
			listener.getLocation(event);
		}

		NSSize controlSize = new NSSize ();
		if (event.width != -1) {
			controlSize.width = event.width;
			controlSize.height = event.height;
			returnValue = NSValue.valueWithSize(controlSize);
		} else {
			if (childID != ACC.CHILDID_SELF) {
				controlSize.width = controlSize.height = 0;
				returnValue = NSValue.valueWithSize(controlSize);
			}
		}

		return returnValue;
	}

	id getCellForColumnAndRowParameter(id parameter, int childID) {
		id returnValue = null;
		NSArray parameterObject = new NSArray(parameter.id);
		if (parameterObject.count() == 2) {
			AccessibleTableEvent event = new AccessibleTableEvent(this);
			event.column = new NSNumber(parameterObject.objectAtIndex(0)).intValue();
			event.row = new NSNumber(parameterObject.objectAtIndex(1)).intValue();
			for (int i = 0; i < accessibleTableListenersSize(); i++) {
				AccessibleTableListener listener = accessibleTableListeners.get(i);
				listener.getCell(event);
				returnValue = event.accessible.delegate;
			}
		}
		return returnValue;
	}

	id getDescriptionAttribute (int childID) {
		AccessibleEvent event = new AccessibleEvent(this);
		event.childID = childID;
		event.result = null;
		id returnValue = null;
		for (int i = 0; i < accessibleListenersSize(); i++) {
			AccessibleListener listener = accessibleListeners.get(i);
			listener.getDescription(event);
		}

		returnValue = (event.result != null ? NSString.stringWith(event.result) : null);

		// If no description was provided, and this is a composite or canvas, return a blank string
		// -- otherwise, let the Cocoa control handle it.
		if (returnValue == null) {
			if (control instanceof Composite) returnValue = NSString.string();
		}

		return returnValue;
	}

	id getInsertionPointLineNumberAttribute (int childID) {
		id returnValue = null;
		if (accessibleTextExtendedListenersSize() > 0) {
			AccessibleTextEvent event  = new AccessibleTextEvent(this);
			event.childID = childID;
			for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
				AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
				listener.getCaretOffset(event);
			}
			int caretOffset = event.offset;
			event.start = caretOffset;
			event.end = caretOffset;
			event.count = Integer.MIN_VALUE;
			event.type = ACC.TEXT_BOUNDARY_LINE;
			for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
				AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
				listener.getText(event);
			}
			returnValue = NSNumber.numberWithInt(Math.max(0, -event.count));
		} else {
			AccessibleControlEvent controlEvent = new AccessibleControlEvent(this);
			controlEvent.childID = childID;
			controlEvent.result = null;
			for (int i = 0; i < accessibleControlListenersSize(); i++) {
				AccessibleControlListener listener = accessibleControlListeners.get(i);
				listener.getValue(controlEvent);
			}
			AccessibleTextEvent textEvent = new AccessibleTextEvent(this);
			textEvent.childID = childID;
			textEvent.offset = -1;
			for (int i = 0; i < accessibleTextListenersSize(); i++) {
				AccessibleTextListener listener = accessibleTextListeners.get(i);
				listener.getCaretOffset(textEvent);
			}
			if (controlEvent.result != null && textEvent.offset != -1) {
				int lineNumber = lineNumberForOffset (controlEvent.result, textEvent.offset);
				returnValue = NSNumber.numberWithInt(lineNumber);
			}
		}
		return returnValue;
	}

	id getLineForIndexParameterizedAttribute (id parameter, int childID) {
		id returnValue = null;
		NSNumber charNumberObj = new NSNumber(parameter.id);
		int charNumber = charNumberObj.intValue();
		if (accessibleTextExtendedListenersSize() > 0) {
			AccessibleTextEvent event = new AccessibleTextEvent(this);
			event.childID = childID;
			event.start = charNumber;
			event.end = charNumber;
			event.count = Integer.MIN_VALUE;
			event.type = ACC.TEXT_BOUNDARY_LINE;
			for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
				AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
				listener.getText(event);
			}
			returnValue = NSNumber.numberWithInt(Math.max(0, -event.count));
		} else {
			AccessibleControlEvent controlEvent = new AccessibleControlEvent(this);
			controlEvent.childID = childID;
			controlEvent.result = null;
			for (int i = 0; i < accessibleControlListenersSize(); i++) {
				AccessibleControlListener listener = accessibleControlListeners.get(i);
				listener.getValue(controlEvent);
			}
			String text = controlEvent.result;
			if (text != null) returnValue = NSNumber.numberWithInt(lineNumberForOffset(text, charNumber));
		}
		return returnValue;
	}

	id getMaxValueAttribute(int childID) {
		id returnValue = null;
		if (accessibleValueListenersSize() > 0) {
			AccessibleValueEvent event = new AccessibleValueEvent(this);
			for (int i = 0; i < accessibleValueListenersSize(); i++) {
				AccessibleValueListener listener = accessibleValueListeners.get(i);
				listener.getMaximumValue(event);
			}
			returnValue = NSNumber.numberWithDouble(event.value.doubleValue());
		}
		return returnValue;
	}

	id getMinValueAttribute(int childID) {
		id returnValue = null;
		if (accessibleValueListenersSize() > 0) {
			AccessibleValueEvent event = new AccessibleValueEvent(this);
			for (int i = 0; i < accessibleValueListenersSize(); i++) {
				AccessibleValueListener listener = accessibleValueListeners.get(i);
				listener.getMinimumValue(event);
			}
			returnValue = NSNumber.numberWithDouble(event.value.doubleValue());
		}
		return returnValue;
	}

	id getNumberOfCharactersAttribute (int childID) {
		id returnValue = null;
		AccessibleTextEvent event = new AccessibleTextEvent(this);
		event.count = -1;
		for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
			AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
			listener.getCharacterCount(event);
		}
		if (event.count != -1) {
			AccessibleControlEvent e = new AccessibleControlEvent(this);
			e.childID = ACC.CHILDID_SELF;
			for (int i = 0; i < accessibleControlListenersSize(); i++) {
				AccessibleControlListener listener = accessibleControlListeners.get(i);
				listener.getRole(e);
				listener.getValue(e);
			}
			// TODO: Consider passing the value through for other roles as well (i.e. combo, etc). Keep in sync with get_text.
			event.count = e.detail == ACC.ROLE_TEXT && e.result != null ? e.result.length() : 0;
			returnValue = NSNumber.numberWithInt(event.count);
		}
		return returnValue;
	}

	id getRangeForLineParameterizedAttribute (id parameter, int childID) {
		id returnValue = null;
		// The parameter is an NSNumber with the line number.
		NSNumber lineNumberObj = new NSNumber(parameter.id);
		int lineNumber = lineNumberObj.intValue();
		if (accessibleTextExtendedListenersSize() > 0) {
			AccessibleTextEvent event = new AccessibleTextEvent(this);
			event.childID = childID;
			event.start = event.end = 0;
			event.count = lineNumber;
			event.type = ACC.TEXT_BOUNDARY_LINE;
			for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
				AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
				listener.getText(event);
			}
			NSRange range = new NSRange();
			range.location = event.start;
			range.length = event.end - event.start;
			returnValue = NSValue.valueWithRange(range);
		} else if (accessibleControlListenersSize() > 0){
			AccessibleControlEvent event = new AccessibleControlEvent(this);
			event.childID = childID;
			event.result = null;
			for (int i = 0; i < accessibleControlListenersSize(); i++) {
				AccessibleControlListener listener = accessibleControlListeners.get(i);
				listener.getValue(event);
			}
			if (event.result != null) {
				NSRange range = rangeForLineNumber (lineNumber, event.result);
				if (range.location != -1) {
					returnValue = NSValue.valueWithRange(range);
				}
			}
		}
		return returnValue;
	}

	id getRangeForIndexParameterizedAttribute (id parameter, int childID) {
		id returnValue = null;
		// The parameter is an NSNumber with the character number.
		NSNumber charNumberObj = new NSNumber(parameter.id);
		int charNumber = charNumberObj.intValue();
		if (accessibleTextExtendedListenersSize() > 0) {
			AccessibleTextEvent event = new AccessibleTextEvent(this);
			event.childID = childID;
			event.start = event.end = 0;
			event.count = charNumber;
			event.type = ACC.TEXT_BOUNDARY_CHAR;
			for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
				AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
				listener.getText(event);
			}
			NSRange range = new NSRange();
			range.location = event.start;
			range.length = event.end - event.start;
			returnValue = NSValue.valueWithRange(range);
		} else if (accessibleControlListenersSize() > 0) {
//			AccessibleControlEvent event = new AccessibleControlEvent(this);
//			event.childID = childID;
//			event.result = null;
//			for (int i = 0; i < accessibleControlListenersSize(); i++) {
//				AccessibleControlListener listener = accessibleControlListeners.get(i);
//				listener.getValue(event);
//			}
//			if (event.result != null) {
//				NSRange range = rangeForLineNumber (lineNumber, event.result);
//				if (range.location != -1) {
//					returnValue = NSValue.valueWithRange(range);
//				}
//			}
		}
		return returnValue;
	}

	id getSelectedTextAttribute (int childID) {
		id returnValue = NSString.string();
		if (accessibleTextExtendedListenersSize() > 0) {
			AccessibleTextEvent event = new AccessibleTextEvent(this);
			event.childID = childID;
			event.index = 0;
			for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
				AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
				listener.getSelection(event);
			}
			int start = event.start;
			int end = event.end;
			if (start != end) {
				event.type = ACC.TEXT_BOUNDARY_ALL;
				for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
					AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
					listener.getText(event);
				}
			}
			String text = event.result;
			if (text != null) returnValue = NSString.stringWith(text);
		} else if (accessibleTextListenersSize() > 0) {
			AccessibleTextEvent event = new AccessibleTextEvent(this);
			event.childID = childID;
			event.offset = -1;
			event.length = -1;
			for (int i = 0; i < accessibleTextListenersSize(); i++) {
				AccessibleTextListener listener = accessibleTextListeners.get(i);
				listener.getSelectionRange(event);
			}
			int offset = event.offset;
			int length = event.length;
			if (offset != -1 && length != -1 && length != 0) {  // TODO: do we need the && length != 0 ?
				AccessibleControlEvent event2 = new AccessibleControlEvent(this);
				event2.childID = event.childID;
				event2.result = null;
				for (int i = 0; i < accessibleControlListenersSize(); i++) {
					AccessibleControlListener listener = accessibleControlListeners.get(i);
					listener.getValue(event2);
				}
				String appValue = event2.result;
				if (appValue != null) {
					returnValue = NSString.stringWith(appValue.substring(offset, offset + length));
				}
			}
		}
		return returnValue;
	}

	id getSelectedTextRangeAttribute (int childID) {
		id returnValue = null;
		if (accessibleTextExtendedListenersSize() > 0) {
			AccessibleTextEvent event = new AccessibleTextEvent(this);
			event.childID = childID;
			event.index = 0;
			for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
				AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
				listener.getSelection(event);
			}
			NSRange range = new NSRange();
			range.location = event.start;
			range.length = event.end - event.start;
			returnValue = NSValue.valueWithRange(range);
		} else if (accessibleTextExtendedListenersSize() > 0) {
			AccessibleTextEvent event = new AccessibleTextEvent(this);
			event.childID = childID;
			event.offset = -1;
			event.length = 0;
			for (int i = 0; i < accessibleTextListenersSize(); i++) {
				AccessibleTextListener listener = accessibleTextListeners.get(i);
				listener.getSelectionRange(event);
			}
			if (event.offset != -1) {
				NSRange range = new NSRange();
				range.location = event.offset;
				range.length = event.length;
				returnValue = NSValue.valueWithRange(range);
			}
		}
		return returnValue;
	}

	id getServesAsTitleForUIElementsAttribute(int childID) {
		id returnValue = null;
		Relation relation = relations[ACC.RELATION_LABEL_FOR];
		if (relation != null) returnValue = relation.getServesAsTitleForUIElements();
		return returnValue;
	}

	id getStringForRangeParameterizedAttribute (id parameter, int childID) {
		id returnValue = null;

		// Parameter is an NSRange wrapped in an NSValue.
		NSValue parameterObject = new NSValue(parameter.id);
		NSRange range = parameterObject.rangeValue();
		if (accessibleTextExtendedListenersSize() > 0) {
			AccessibleTextEvent event = new AccessibleTextEvent(this);
			event.childID = childID;
			event.start = (int) /*64*/ range.location;
			event.end = (int) /*64*/ (range.location + range.length);
			event.type = ACC.TEXT_BOUNDARY_ALL;
			for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
				AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
				listener.getText(event);
			}
			if (event.result != null) returnValue = NSString.stringWith(event.result);
		} else if (accessibleControlListenersSize() > 0) {
			AccessibleControlEvent event = new AccessibleControlEvent(this);
			event.childID = childID;
			event.result = null;
			for (int i = 0; i < accessibleControlListenersSize(); i++) {
				AccessibleControlListener listener = accessibleControlListeners.get(i);
				listener.getValue(event);
			}
			String appValue = event.result;

			if (appValue != null) {
				returnValue = NSString.stringWith(appValue.substring((int)/*64*/range.location, (int)/*64*/(range.location + range.length)));
			}
		}
		return returnValue;
	}

	id getSelectedTextRangesAttribute (int childID) {
		NSMutableArray returnValue = NSMutableArray.arrayWithCapacity(3);
		if (accessibleTextExtendedListenersSize() > 0) {
			AccessibleTextEvent event = new AccessibleTextEvent(this);
			event.childID = childID;
			for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
				AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
				listener.getSelectionCount(event);
			}
			if (event.count > 0) {
				for (int i = 0; i < event.count; i++) {
					event.index = i;
					for (int j = 0; j < accessibleTextExtendedListenersSize(); j++) {
						AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(j);
						listener.getSelection(event);
					}
					NSRange range = new NSRange();
					range.location = event.start;
					range.length = event.end - event.start;
					returnValue.addObject(NSValue.valueWithRange(range));
				}
			}
		} else if (accessibleTextListenersSize() > 0) {
			AccessibleTextEvent event = new AccessibleTextEvent(this);
			event.childID = childID;
			event.offset = -1;
			event.length = 0;

			for (int i = 0; i < accessibleTextListenersSize(); i++) {
				AccessibleTextListener listener = accessibleTextListeners.get(i);
				listener.getSelectionRange(event);
			}

			if (event.offset != -1) {
				NSRange range = new NSRange();
				range.location = event.offset;
				range.length = event.length;
				returnValue.addObject(NSValue.valueWithRange(range));
			}
		}
		if (returnValue.count() == 0) {
			returnValue.addObject(NSValue.valueWithRange(new NSRange()));
		}
		return returnValue;
	}

	id getStyleRangeForIndexAttribute (id parameter, int childID) {
		if (accessibleAttributeListenersSize() == 0) return null;

		// Parameter is an NSRange wrapped in an NSValue.
		NSNumber parameterObject = new NSNumber(parameter.id);
		int index = parameterObject.intValue();

		AccessibleTextAttributeEvent event = new AccessibleTextAttributeEvent(this);
		event.offset = (int) /*64*/ index;

		// Marker values -- if -1 after calling getTextAttributes, no one implemented it.
		event.start = event.end = -1;

		for (int i = 0; i < accessibleAttributeListenersSize(); i++) {
			AccessibleAttributeListener listener = accessibleAttributeListeners.get(i);
			listener.getTextAttributes(event);
		}

		NSRange range = new NSRange();
		if (event.start == -1 && event.end == -1) {
			range.location = index;
			range.length = 0;
		} else {
			range.location = event.start;
			range.length = event.end - event.start;
		}

		return NSValue.valueWithRange(range);
	}

	id getVisibleCharacterRangeAttribute (int childID) {
		NSRange range = null;
		if (accessibleTextExtendedListenersSize() > 0) {
			AccessibleTextEvent event = new AccessibleTextEvent(this);
			event.childID = childID;
			for (int i=0; i<accessibleTextExtendedListenersSize(); i++) {
				AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
				listener.getVisibleRanges(event);
			}
			range = new NSRange();
			range.location = event.start;
			range.length = event.end - event.start;
		} else if (accessibleControlListenersSize() > 0) {
			AccessibleControlEvent event = new AccessibleControlEvent(this);
			event.childID = childID;
			event.result = null;
			for (int i = 0; i < accessibleControlListenersSize(); i++) {
				AccessibleControlListener listener = accessibleControlListeners.get(i);
				listener.getValue(event);
			}
			if (event.result != null) {
				range = new NSRange();
				range.location = 0;
				range.length = event.result.length();
			}
		}

		return (range != null) ? NSValue.valueWithRange(range) : null;
	}

	int lineNumberForOffset (String text, int offset) {
		int lineNumber = 1;
		int length = text.length();
		for (int i = 0; i < offset; i++) {
			switch (text.charAt (i)) {
				case '\r':
					if (i + 1 < length) {
						if (text.charAt (i + 1) == '\n') ++i;
					}
					// FALL THROUGH
				case '\n':
					lineNumber++;
			}
		}
		return lineNumber;
	}

	NSRange rangeForLineNumber (int lineNumber, String text) {
		NSRange range = new NSRange();
		range.location = -1;
		int line = 1;
		int count = 0;
		int length = text.length ();
		for (int i = 0; i < length; i++) {
			if (line == lineNumber) {
				if (count == 0) {
					range.location = i;
				}
				count++;
			}
			if (line > lineNumber) break;
			switch (text.charAt (i)) {
				case '\r':
					if (i + 1 < length && text.charAt (i + 1) == '\n') i++;
					// FALL THROUGH
				case '\n':
					line++;
			}
		}
		range.length = count;
		return range;
	}

	/**
	 * Removes the listener from the collection of listeners who will
	 * be notified when an accessible client asks for certain strings,
	 * such as name, description, help, or keyboard shortcut.
	 *
	 * @param listener the listener that should no longer be notified when the receiver
	 * is asked for a name, description, help, or keyboard shortcut string
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleListener
	 * @see #addAccessibleListener
	 */
	public void removeAccessibleListener(AccessibleListener listener) {
		checkWidget();
		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleListeners != null) {
			accessibleListeners.remove(listener);
			if (accessibleListeners.isEmpty()) accessibleListeners = null;
		}
	}

	/**
	 * Removes the listener from the collection of listeners who will
	 * be notified when an accessible client asks for custom control
	 * specific information.
	 *
	 * @param listener the listener that should no longer be notified when the receiver
	 * is asked for custom control specific information
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleControlListener
	 * @see #addAccessibleControlListener
	 */
	public void removeAccessibleControlListener(AccessibleControlListener listener) {
		checkWidget();
		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleControlListeners != null) {
			accessibleControlListeners.remove(listener);
			if (accessibleControlListeners.isEmpty()) accessibleControlListeners = null;
		}
	}

	/**
	 * Removes the listener from the collection of listeners who will
	 * be notified when an accessible client asks for custom text control
	 * specific information.
	 *
	 * @param listener the listener that should no longer be notified when the receiver
	 * is asked for custom text control specific information
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleTextListener
	 * @see AccessibleTextExtendedListener
	 * @see #addAccessibleTextListener
	 *
	 * @since 3.0
	 */
	public void removeAccessibleTextListener (AccessibleTextListener listener) {
		checkWidget ();
		if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
		if (listener instanceof AccessibleTextExtendedListener) {
			if (accessibleTextExtendedListeners != null) {
				accessibleTextExtendedListeners.remove(listener);
				if (accessibleTextExtendedListeners.isEmpty()) accessibleTextExtendedListeners = null;
			}
		} else {
			if (accessibleTextListeners != null) {
				accessibleTextListeners.remove(listener);
				if (accessibleTextListeners.isEmpty()) accessibleTextListeners = null;
			}
		}
	}

	/**
	 * Removes the listener from the collection of listeners that will be
	 * notified when an accessible client asks for any of the properties
	 * defined in the <code>AccessibleActionListener</code> interface.
	 *
	 * @param listener the listener that should no longer be notified when the receiver
	 * is asked for <code>AccessibleActionListener</code> interface properties
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleActionListener
	 * @see #addAccessibleActionListener
	 *
	 * @since 3.6
	 */
	public void removeAccessibleActionListener(AccessibleActionListener listener) {
		checkWidget();
		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleActionListeners != null) {
			accessibleActionListeners.remove(listener);
			if (accessibleActionListeners.isEmpty()) accessibleActionListeners = null;
		}
	}

	/**
	 * Removes the listener from the collection of listeners that will be
	 * notified when an accessible client asks for any of the properties
	 * defined in the <code>AccessibleEditableTextListener</code> interface.
	 *
	 * @param listener the listener that should no longer be notified when the receiver
	 * is asked for <code>AccessibleEditableTextListener</code> interface properties
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleEditableTextListener
	 * @see #addAccessibleEditableTextListener
	 *
	 * @since 3.7
	 */
	public void removeAccessibleEditableTextListener(AccessibleEditableTextListener listener) {
	    checkWidget();
	    if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleEditableTextListeners != null) {
			accessibleEditableTextListeners.remove(listener);
			if (accessibleEditableTextListeners.isEmpty()) accessibleEditableTextListeners = null;
		}
	}

	/**
	 * Removes the listener from the collection of listeners that will be
	 * notified when an accessible client asks for any of the properties
	 * defined in the <code>AccessibleHyperlinkListener</code> interface.
	 *
	 * @param listener the listener that should no longer be notified when the receiver
	 * is asked for <code>AccessibleHyperlinkListener</code> interface properties
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleHyperlinkListener
	 * @see #addAccessibleHyperlinkListener
	 *
	 * @since 3.6
	 */
	public void removeAccessibleHyperlinkListener(AccessibleHyperlinkListener listener) {
		checkWidget();
		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleHyperlinkListeners != null) {
			accessibleHyperlinkListeners.remove(listener);
			if (accessibleHyperlinkListeners.isEmpty()) accessibleHyperlinkListeners = null;
		}
	}

	/**
	 * Removes the listener from the collection of listeners that will be
	 * notified when an accessible client asks for any of the properties
	 * defined in the <code>AccessibleTableListener</code> interface.
	 *
	 * @param listener the listener that should no longer be notified when the receiver
	 * is asked for <code>AccessibleTableListener</code> interface properties
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleTableListener
	 * @see #addAccessibleTableListener
	 *
	 * @since 3.6
	 */
	public void removeAccessibleTableListener(AccessibleTableListener listener) {
		checkWidget();
		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleTableListeners != null) {
			accessibleTableListeners.remove(listener);
			if (accessibleTableListeners.isEmpty()) accessibleTableListeners = null;
		}
	}

	/**
	 * Removes the listener from the collection of listeners that will be
	 * notified when an accessible client asks for any of the properties
	 * defined in the <code>AccessibleTableCellListener</code> interface.
	 *
	 * @param listener the listener that should no longer be notified when the receiver
	 * is asked for <code>AccessibleTableCellListener</code> interface properties
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleTableCellListener
	 * @see #addAccessibleTableCellListener
	 *
	 * @since 3.6
	 */
	public void removeAccessibleTableCellListener(AccessibleTableCellListener listener) {
		checkWidget();
		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleTableCellListeners != null) {
			accessibleTableCellListeners.remove(listener);
			if (accessibleTableCellListeners.isEmpty()) accessibleTableCellListeners = null;
		}
	}

	/**
	 * Removes the listener from the collection of listeners that will be
	 * notified when an accessible client asks for any of the properties
	 * defined in the <code>AccessibleValueListener</code> interface.
	 *
	 * @param listener the listener that should no longer be notified when the receiver
	 * is asked for <code>AccessibleValueListener</code> interface properties
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleValueListener
	 * @see #addAccessibleValueListener
	 *
	 * @since 3.6
	 */
	public void removeAccessibleValueListener(AccessibleValueListener listener) {
		checkWidget();
		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleValueListeners != null) {
			accessibleValueListeners.remove(listener);
			if (accessibleValueListeners.isEmpty()) accessibleValueListeners = null;
		}
	}

	/**
	 * Removes the listener from the collection of listeners that will be
	 * notified when an accessible client asks for any of the properties
	 * defined in the <code>AccessibleAttributeListener</code> interface.
	 *
	 * @param listener the listener that should no longer be notified when the receiver
	 * is asked for <code>AccessibleAttributeListener</code> interface properties
	 *
	 * @exception IllegalArgumentException <ul>
	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 * </ul>
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see AccessibleAttributeListener
	 * @see #addAccessibleAttributeListener
	 *
	 * @since 3.6
	 */
	public void removeAccessibleAttributeListener(AccessibleAttributeListener listener) {
		checkWidget();
		if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		if (accessibleAttributeListeners != null) {
			accessibleAttributeListeners.remove(listener);
			if (accessibleAttributeListeners.isEmpty()) accessibleAttributeListeners = null;
		}
	}

	/**
	 * Removes the relation with the specified type and target
	 * from the receiver's set of relations.
	 *
	 * @param type an <code>ACC</code> constant beginning with RELATION_* indicating the type of relation
	 * @param target the accessible that is the target for this relation
	 * @exception IllegalArgumentException ERROR_NULL_ARGUMENT - if the Accessible target is null
	 * 
	 * @since 3.6
	 */
	public void removeRelation(int type, Accessible target) {
		checkWidget();
		if (target == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
		if (relations[type] != null) {
			relations[type].removeTarget(target);
		}
	}

	void release(boolean destroy) {
		if (actionNames != null) actionNames.release();
		actionNames = null;
		if (attributeNames != null) attributeNames.release();
		attributeNames = null;
		if (parameterizedAttributeNames != null) parameterizedAttributeNames.release();
		parameterizedAttributeNames = null;
		if (delegate != null) {
			delegate.internal_dispose_SWTAccessibleDelegate();
			delegate.release();
		}
		delegate = null;
		relations = null;

		if (childToIdMap != null) {
			Collection delegates = childToIdMap.values();
			Iterator iter = delegates.iterator();
			while (iter.hasNext()) {
				SWTAccessibleDelegate childDelegate = (SWTAccessibleDelegate)iter.next();
				childDelegate.internal_dispose_SWTAccessibleDelegate();
				childDelegate.release();
			}
			childToIdMap.clear();
			childToIdMap = null;
		}

		if (tableDelegate != null) tableDelegate.release();
	}

	static NSArray retainedAutoreleased(NSArray inObject) {
		id temp = inObject.retain();
		id temp2 = new NSObject(temp.id).autorelease();
		return new NSArray(temp2.id);
	}

	/**
	 * Sends a message with event-specific data to accessible clients
	 * indicating that something has changed within a custom control.
	 *
	 * @param event an <code>ACC</code> constant beginning with EVENT_* indicating the message to send
	 * @param eventData an object containing event-specific data, or null if there is no event-specific data
	 * (eventData is specified in the documentation for individual ACC.EVENT_* constants)
	 *
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see ACC#EVENT_ACTION_CHANGED
	 * @see ACC#EVENT_ATTRIBUTE_CHANGED
	 * @see ACC#EVENT_DESCRIPTION_CHANGED
	 * @see ACC#EVENT_DOCUMENT_LOAD_COMPLETE
	 * @see ACC#EVENT_DOCUMENT_LOAD_STOPPED
	 * @see ACC#EVENT_DOCUMENT_RELOAD
	 * @see ACC#EVENT_HYPERLINK_ACTIVATED
	 * @see ACC#EVENT_HYPERLINK_ANCHOR_COUNT_CHANGED
	 * @see ACC#EVENT_HYPERLINK_END_INDEX_CHANGED
	 * @see ACC#EVENT_HYPERLINK_SELECTED_LINK_CHANGED
	 * @see ACC#EVENT_HYPERLINK_START_INDEX_CHANGED
	 * @see ACC#EVENT_HYPERTEXT_LINK_COUNT_CHANGED
	 * @see ACC#EVENT_HYPERTEXT_LINK_SELECTED
	 * @see ACC#EVENT_LOCATION_CHANGED
	 * @see ACC#EVENT_NAME_CHANGED
	 * @see ACC#EVENT_PAGE_CHANGED
	 * @see ACC#EVENT_SECTION_CHANGED
	 * @see ACC#EVENT_SELECTION_CHANGED
	 * @see ACC#EVENT_STATE_CHANGED
	 * @see ACC#EVENT_TABLE_CAPTION_CHANGED
	 * @see ACC#EVENT_TABLE_CHANGED
	 * @see ACC#EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED
	 * @see ACC#EVENT_TABLE_COLUMN_HEADER_CHANGED
	 * @see ACC#EVENT_TABLE_ROW_DESCRIPTION_CHANGED
	 * @see ACC#EVENT_TABLE_ROW_HEADER_CHANGED
	 * @see ACC#EVENT_TABLE_SUMMARY_CHANGED
	 * @see ACC#EVENT_TEXT_ATTRIBUTE_CHANGED
	 * @see ACC#EVENT_TEXT_CARET_MOVED
	 * @see ACC#EVENT_TEXT_CHANGED
	 * @see ACC#EVENT_TEXT_COLUMN_CHANGED
	 * @see ACC#EVENT_TEXT_SELECTION_CHANGED
	 * @see ACC#EVENT_VALUE_CHANGED
	 *
	 * @since 3.6
	 */
	public void sendEvent(int event, Object eventData) {
		checkWidget();

		id eventSource = accessibleHandle(this);
		if (DEBUG) System.out.println("sendEvent: 0x" + Integer.toHexString(event) + ", data = " + eventData + ", source = " + eventSource);

		switch (event) {
		case ACC.EVENT_TEXT_CHANGED:
		case ACC.EVENT_VALUE_CHANGED:
		case ACC.EVENT_STATE_CHANGED:
		case ACC.EVENT_PAGE_CHANGED:
		case ACC.EVENT_SECTION_CHANGED:
		case ACC.EVENT_ACTION_CHANGED:
		case ACC.EVENT_HYPERLINK_START_INDEX_CHANGED:
		case ACC.EVENT_HYPERLINK_END_INDEX_CHANGED:
		case ACC.EVENT_HYPERLINK_ANCHOR_COUNT_CHANGED:
		case ACC.EVENT_HYPERLINK_SELECTED_LINK_CHANGED:
		case ACC.EVENT_HYPERLINK_ACTIVATED:
		case ACC.EVENT_HYPERTEXT_LINK_COUNT_CHANGED:
		case ACC.EVENT_ATTRIBUTE_CHANGED:
		case ACC.EVENT_TABLE_CAPTION_CHANGED:
		case ACC.EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED:
		case ACC.EVENT_TABLE_COLUMN_HEADER_CHANGED:
		case ACC.EVENT_TABLE_ROW_DESCRIPTION_CHANGED:
		case ACC.EVENT_TABLE_ROW_HEADER_CHANGED:
		case ACC.EVENT_TABLE_SUMMARY_CHANGED:
		case ACC.EVENT_TEXT_ATTRIBUTE_CHANGED:
		case ACC.EVENT_TEXT_COLUMN_CHANGED:
			OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilityValueChangedNotification.id); break;

		case ACC.EVENT_SELECTION_CHANGED:
			OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilitySelectedChildrenChangedNotification.id); break;
		case ACC.EVENT_TEXT_SELECTION_CHANGED:
			OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilitySelectedTextChangedNotification.id); break;
		case ACC.EVENT_LOCATION_CHANGED:
			OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilityMovedNotification.id); break;
		case ACC.EVENT_NAME_CHANGED:
		case ACC.EVENT_DESCRIPTION_CHANGED:
			OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilityTitleChangedNotification.id); break;
		case ACC.EVENT_TEXT_CARET_MOVED:
			OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilitySelectedTextChangedNotification.id); break;
		case ACC.EVENT_TABLE_CHANGED:
			if (tableDelegate != null) {
				tableDelegate.reset();
				getRowsAttribute(ACC.CHILDID_SELF);
				getColumnsAttribute(ACC.CHILDID_SELF);
			}
			if (eventData != null) {
				int[] eventParams = (int[])eventData;
				// Slot 2 of the array is the number of rows that were either added or deleted. If non-zero, fire a notification.
				// Cocoa doesn't have a notification for a change in the number of columns.
				if (eventParams[2] != 0) OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilityRowCountChangedNotification.id);
			}
			break;

		// None of these correspond to anything in Cocoa.
		case ACC.EVENT_HYPERTEXT_LINK_SELECTED:
		case ACC.EVENT_DOCUMENT_LOAD_COMPLETE:
		case ACC.EVENT_DOCUMENT_LOAD_STOPPED:
		case ACC.EVENT_DOCUMENT_RELOAD:
			break;

		}
	}

	/**
	 * Sends a message with event-specific data and a childID
	 * to accessible clients, indicating that something has changed
	 * within a custom control.
	 *
	 * NOTE: This API is intended for applications that are still using childIDs.
	 * Moving forward, applications should use accessible objects instead of childIDs.
	 *
	 * @param event an <code>ACC</code> constant beginning with EVENT_* indicating the message to send
	 * @param eventData an object containing event-specific data, or null if there is no event-specific data
	 * (eventData is specified in the documentation for individual ACC.EVENT_* constants)
	 * @param childID an identifier specifying a child of the control
	 *
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see ACC#EVENT_DESCRIPTION_CHANGED
	 * @see ACC#EVENT_LOCATION_CHANGED
	 * @see ACC#EVENT_NAME_CHANGED
	 * @see ACC#EVENT_SELECTION_CHANGED
	 * @see ACC#EVENT_STATE_CHANGED
	 * @see ACC#EVENT_TEXT_SELECTION_CHANGED
	 * @see ACC#EVENT_VALUE_CHANGED
	 *
	 * @since 3.8
	 */
	public void sendEvent(int event, Object eventData, int childID) {
		checkWidget();

		id eventSource = childIDToOs(childID);
		if (DEBUG) System.out.println("sendEvent: 0x" + Integer.toHexString(event) + ", data = " + eventData + ", source = " + eventSource);

		switch (event) {
			case ACC.EVENT_VALUE_CHANGED:
			case ACC.EVENT_STATE_CHANGED:
			case ACC.EVENT_SELECTION_CHANGED:
				OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilitySelectedChildrenChangedNotification.id); break;
			case ACC.EVENT_TEXT_SELECTION_CHANGED:
				OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilitySelectedTextChangedNotification.id); break;
			case ACC.EVENT_LOCATION_CHANGED:
				OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilityMovedNotification.id); break;
			case ACC.EVENT_NAME_CHANGED:
			case ACC.EVENT_DESCRIPTION_CHANGED:
				OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilityTitleChangedNotification.id); break;
		}
	}

	/**
	 * Sends a message to accessible clients that the child selection
	 * within a custom container control has changed.
	 *
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @since 3.0
	 */
	public void selectionChanged () {
		checkWidget();
		id eventSource = accessibleHandle(this);
		if (DEBUG) System.out.println("selectionChanged on " + eventSource);
		if (currentRole == ACC.ROLE_TABLE) {
			OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilitySelectedRowsChangedNotification.id);
		} else {
			OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilitySelectedChildrenChangedNotification.id);
		}
	}

	/**
	 * Sends a message to accessible clients indicating that the focus
	 * has changed within a custom control.
	 *
	 * @param childID an identifier specifying a child of the control
	 *
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 */
	public void setFocus(int childID) {
		checkWidget();
		id accessible = childIDToOs(childID);
		if (DEBUG) System.out.println("setFocus on " + accessible);
		OS.NSAccessibilityPostNotification(accessible.id, OS.NSAccessibilityFocusedUIElementChangedNotification.id);
	}

	void setSelectedTextAttribute(id value, int childId) {
		NSString newText = new NSString(value.id);
		int rangeStart = 0;
		id charsValue = getNumberOfCharactersAttribute(childId);
		int rangeEnd = new NSNumber(charsValue).intValue();
		id rangeObj = getSelectedTextRangeAttribute(childId);

		if (rangeObj != null) {
			NSRange range = new NSValue(rangeObj).rangeValue();
			rangeStart = (int)/*64*/range.location;
			rangeEnd = (int)/*64*/(range.location + range.length);
		}

		if (accessibleEditableTextListenersSize() > 0) {
			AccessibleEditableTextEvent event = new AccessibleEditableTextEvent(this);
			event.start = rangeStart;
			event.end = rangeEnd;
			event.string = newText.getString();

			for (int i = 0; i < accessibleEditableTextListenersSize(); i++) {
				AccessibleEditableTextListener listener = (AccessibleEditableTextListener) accessibleEditableTextListeners.get(i);
				listener.replaceText(event);
			}
		}
	}

	void setSelectedTextRangeAttribute(id value, int childId) {
		NSRange newRange = new NSValue(value.id).rangeValue();
		if (accessibleTextExtendedListenersSize() > 0) {
			AccessibleTextEvent event = new AccessibleTextEvent(this);
			event.index = 0;
			event.start = (int)newRange.location;
			event.end = (int)(newRange.location + newRange.length);

			for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
				AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
				listener.removeSelection(event);
				listener.addSelection(event);
			}
		}
	}

	void setVisibleCharacterRangeAttribute(id value, int childId) {
		NSRange newRange = new NSValue(value.id).rangeValue();
		if (accessibleTextExtendedListenersSize() > 0) {
			AccessibleTextEvent event = new AccessibleTextEvent(this);
			event.type = ACC.SCROLL_TYPE_TOP_LEFT;
			event.start = (int)newRange.location;
			event.end = (int)(newRange.location + newRange.length);

			for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
				AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
				listener.scrollText(event);
			}
		}
	}

	/**
	 * Sends a message to accessible clients that the text
	 * caret has moved within a custom control.
	 *
	 * @param index the new caret index within the control
	 *
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @since 3.0
	 */
	public void textCaretMoved (int index) {
		checkWidget();
		OS.NSAccessibilityPostNotification(control.view.id, OS.NSAccessibilitySelectedTextChangedNotification.id);
	}

	/**
	 * Sends a message to accessible clients that the text
	 * within a custom control has changed.
	 *
	 * @param type the type of change, one of <code>ACC.TEXT_INSERT</code>
	 * or <code>ACC.TEXT_DELETE</code>
	 * @param startIndex the text index within the control where the insertion or deletion begins
	 * @param length the non-negative length in characters of the insertion or deletion
	 *
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @see ACC#TEXT_INSERT
	 * @see ACC#TEXT_DELETE
	 *
	 * @since 3.0
	 */
	public void textChanged (int type, int startIndex, int length) {
		checkWidget();
		OS.NSAccessibilityPostNotification(control.view.id, OS.NSAccessibilityValueChangedNotification.id);
	}

	/**
	 * Sends a message to accessible clients that the text
	 * selection has changed within a custom control.
	 *
	 * @exception SWTException <ul>
	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
	 * </ul>
	 *
	 * @since 3.0
	 */
	public void textSelectionChanged () {
		checkWidget();
		OS.NSAccessibilityPostNotification(control.view.id, OS.NSAccessibilitySelectedTextChangedNotification.id);
	}

	id childIDToOs(int childID) {
		if (childID == ACC.CHILDID_SELF) {
			return control.view;
		}

		/* Check cache for childID, if found, return corresponding osChildID. */
		SWTAccessibleDelegate childRef = (SWTAccessibleDelegate) childToIdMap.get(Integer.valueOf(childID));

		if (childRef == null) {
			childRef = new SWTAccessibleDelegate(this, childID);
			childToIdMap.put(Integer.valueOf(childID), childRef);
		}

		return childRef;
	}

	NSString concatStringsAsRole(NSString str1, NSString str2) {
		NSString returnValue = str1;
		returnValue = returnValue.stringByAppendingString(NSString.stringWith(":"));
		returnValue = returnValue.stringByAppendingString(str2);
		return returnValue;
	}

	String roleToOs(int role) {
		NSString nsReturnValue = null; //OS.NSAccessibilityUnknownRole;

		switch (role) {
			case ACC.ROLE_CLIENT_AREA: nsReturnValue = OS.NSAccessibilityGroupRole; break;
			case ACC.ROLE_WINDOW: nsReturnValue = OS.NSAccessibilityWindowRole; break;
			case ACC.ROLE_MENUBAR: nsReturnValue = OS.NSAccessibilityMenuBarRole; break;
			case ACC.ROLE_MENU: nsReturnValue = OS.NSAccessibilityMenuRole; break;
			case ACC.ROLE_MENUITEM: nsReturnValue = OS.NSAccessibilityMenuItemRole; break;
			case ACC.ROLE_SEPARATOR: nsReturnValue = OS.NSAccessibilitySplitterRole; break;
			case ACC.ROLE_TOOLTIP: nsReturnValue = OS.NSAccessibilityHelpTagRole; break;
			case ACC.ROLE_SCROLLBAR: nsReturnValue = OS.NSAccessibilityScrollBarRole; break;
			case ACC.ROLE_DIALOG: nsReturnValue = concatStringsAsRole(OS.NSAccessibilityWindowRole, OS.NSAccessibilityDialogSubrole); break;
			case ACC.ROLE_LABEL: nsReturnValue = OS.NSAccessibilityStaticTextRole; break;
			case ACC.ROLE_PUSHBUTTON: nsReturnValue = OS.NSAccessibilityButtonRole; break;
			case ACC.ROLE_CHECKBUTTON: nsReturnValue = OS.NSAccessibilityCheckBoxRole; break;
			case ACC.ROLE_RADIOBUTTON: nsReturnValue = OS.NSAccessibilityRadioButtonRole; break;
			case ACC.ROLE_SPLITBUTTON: nsReturnValue = OS.NSAccessibilityMenuButtonRole; break;
			case ACC.ROLE_COMBOBOX: nsReturnValue = OS.NSAccessibilityComboBoxRole; break;
			case ACC.ROLE_TEXT: {
				int style = control.getStyle();

				if ((style & SWT.MULTI) != 0) {
					nsReturnValue = OS.NSAccessibilityTextAreaRole;
				} else {
					nsReturnValue = OS.NSAccessibilityTextFieldRole;
				}

				break;
			}
			case ACC.ROLE_TOOLBAR: nsReturnValue = OS.NSAccessibilityToolbarRole; break;
			case ACC.ROLE_LIST: nsReturnValue = OS.NSAccessibilityOutlineRole; break;
			case ACC.ROLE_LISTITEM: nsReturnValue = OS.NSAccessibilityStaticTextRole; break;
			case ACC.ROLE_COLUMN: nsReturnValue =  OS.NSAccessibilityColumnRole; break;
			case ACC.ROLE_ROW: nsReturnValue =  concatStringsAsRole(OS.NSAccessibilityRowRole, OS.NSAccessibilityTableRowSubrole); break;
			case ACC.ROLE_TABLE: nsReturnValue = OS.NSAccessibilityTableRole; break;
			case ACC.ROLE_TABLECELL: nsReturnValue = OS.NSAccessibilityStaticTextRole; break;
			case ACC.ROLE_TABLECOLUMNHEADER: nsReturnValue = OS.NSAccessibilityGroupRole; break;
			case ACC.ROLE_TABLEROWHEADER: nsReturnValue = OS.NSAccessibilityGroupRole; break;
			case ACC.ROLE_TREE: nsReturnValue = OS.NSAccessibilityOutlineRole; break;
			case ACC.ROLE_TREEITEM: nsReturnValue = concatStringsAsRole(OS.NSAccessibilityOutlineRole, OS.NSAccessibilityOutlineRowSubrole); break;
			case ACC.ROLE_TABFOLDER: nsReturnValue = OS.NSAccessibilityTabGroupRole; break;
			case ACC.ROLE_TABITEM: nsReturnValue = OS.NSAccessibilityRadioButtonRole; break;
			case ACC.ROLE_PROGRESSBAR: nsReturnValue = OS.NSAccessibilityProgressIndicatorRole; break;
			case ACC.ROLE_SLIDER: nsReturnValue = OS.NSAccessibilitySliderRole; break;
			case ACC.ROLE_LINK: nsReturnValue = OS.NSAccessibilityLinkRole; break;

			//10.6 only -> case ACC.ROLE_CANVAS: nsReturnValue = OS.NSAccessibilityLayoutAreaRole; break;
			case ACC.ROLE_CANVAS: nsReturnValue = OS.NSAccessibilityGroupRole; break;
			case ACC.ROLE_GRAPHIC: nsReturnValue = OS.NSAccessibilityImageRole; break;

			//CLIENT_AREA uses NSAccessibilityGroupRole already
			case ACC.ROLE_GROUP: nsReturnValue = OS.NSAccessibilityGroupRole; break;
			//SPLIT_BUTTON uses NSAccessibilityMenuButtonRole already
			case ACC.ROLE_CHECKMENUITEM: nsReturnValue = OS.NSAccessibilityMenuButtonRole; break;
			case ACC.ROLE_RADIOMENUITEM: nsReturnValue = OS.NSAccessibilityMenuButtonRole; break;
			//don't know the right answer for these:
			case ACC.ROLE_FOOTER:
			case ACC.ROLE_HEADER:
			case ACC.ROLE_FORM:
			case ACC.ROLE_PAGE:
			case ACC.ROLE_SECTION:
				nsReturnValue = OS.NSAccessibilityGroupRole;
				break;
			case ACC.ROLE_HEADING:
			case ACC.ROLE_PARAGRAPH:
				nsReturnValue = OS.NSAccessibilityTextAreaRole;
				break;
			case ACC.ROLE_CLOCK:
			case ACC.ROLE_DATETIME:
			case ACC.ROLE_CALENDAR:
			case ACC.ROLE_ALERT:
			case ACC.ROLE_ANIMATION:
			case ACC.ROLE_DOCUMENT:
			case ACC.ROLE_SPINBUTTON:
			case ACC.ROLE_STATUSBAR:
				nsReturnValue = OS.NSAccessibilityUnknownRole;
		}

		return nsReturnValue.getString();
	}

	/* checkWidget was copied from Widget, and rewritten to work in this package */
	void checkWidget () {
		if (!isValidThread ()) SWT.error (SWT.ERROR_THREAD_INVALID_ACCESS);
		if (control.isDisposed ()) SWT.error (SWT.ERROR_WIDGET_DISPOSED);
	}

	/* isValidThread was copied from Widget, and rewritten to work in this package */
	boolean isValidThread () {
		return control.getDisplay ().getThread () == Thread.currentThread ();
	}

	/**
	 * Adds relationship attributes if needed to the property list.
	 * <p>
	 * <b>IMPORTANT:</b> This method is <em>not</em> part of the SWT
	 * public API. It is marked public only so that it can be shared
	 * within the packages provided by SWT. It is not available on all
	 * platforms and should never be accessed from application code.
	 * </p>
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	public long /*int*/ internal_addRelationAttributes(long /*int*/ defaultAttributes) {
		NSArray attributes = new NSArray(defaultAttributes);
		NSMutableArray returnArray = NSMutableArray.arrayWithCapacity(attributes.count());
		returnArray.addObjectsFromArray(attributes);

		if (getTitleAttribute(ACC.CHILDID_SELF) != null) {
			if (!returnArray.containsObject(OS.NSAccessibilityTitleAttribute)) returnArray.addObject(OS.NSAccessibilityTitleAttribute);
		}

		if (getDescriptionAttribute(ACC.CHILDID_SELF) != null) {
			if (!returnArray.containsObject(OS.NSAccessibilityDescriptionAttribute)) returnArray.addObject(OS.NSAccessibilityDescriptionAttribute);
		}

		// See if this object has a label or is a label for something else. If so, add that to the list.
		if (relations[ACC.RELATION_LABEL_FOR] != null) {
			if (!returnArray.containsObject(OS.NSAccessibilityServesAsTitleForUIElementsAttribute)) returnArray.addObject(OS.NSAccessibilityServesAsTitleForUIElementsAttribute);
			if (!returnArray.containsObject(OS.NSAccessibilityTitleAttribute)) returnArray.addObject(OS.NSAccessibilityTitleAttribute);
		} else {
			returnArray.removeObject(OS.NSAccessibilityServesAsTitleForUIElementsAttribute);
		}

		if (relations[ACC.RELATION_LABELLED_BY] != null) {
			if (!returnArray.containsObject(OS.NSAccessibilityTitleUIElementAttribute)) returnArray.addObject(OS.NSAccessibilityTitleUIElementAttribute);
		} else {
			returnArray.removeObject(OS.NSAccessibilityTitleUIElementAttribute);
		}

		return returnArray.id;
	}

}
