changeset 86:12b890a6392a

Work on databinding
author Frank Benoit <benoit@tionex.de>
date Sat, 18 Apr 2009 13:58:35 +0200
parents 6be48cf9f95c
children 8594250b1d1c
files org.eclipse.equinox.common/src/org/eclipse/core/runtime/Assert.d org.eclipse.jface/src/org/eclipse/jface/action/Action.d org.eclipse.jface/src/org/eclipse/jface/action/IContributionManagerOverrides.d org.eclipse.jface/src/org/eclipse/jface/dialogs/Dialog.d org.eclipse.jface/src/org/eclipse/jface/preference/ScaleFieldEditor.d org.eclipse.jface/src/org/eclipse/jface/viewers/ComboBoxCellEditor.d org.eclipse.osgi/osgi/src/org/osgi/framework/BundleActivator.d org.eclipse.osgi/osgi/src/org/osgi/framework/BundleContext.d org.eclipse.osgi/osgi/src/org/osgi/framework/BundleEvent.d org.eclipse.osgi/osgi/src/org/osgi/framework/BundleListener.d org.eclipse.osgi/osgi/src/org/osgi/framework/Filter.d org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkListener.d org.eclipse.osgi/osgi/src/org/osgi/framework/ServiceEvent.d org.eclipse.osgi/osgi/src/org/osgi/framework/ServiceListener.d org.eclipse.osgi/osgi/src/org/osgi/framework/ServiceReference.d org.eclipse.osgi/osgi/src/org/osgi/framework/ServiceRegistration.d org.eclipse.osgi/osgi/src/org/osgi/util/tracker/ServiceTracker.d org.eclipse.osgi/osgi/src/org/osgi/util/tracker/ServiceTrackerCustomizer.d org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/program/Program.d org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/accessibility/Accessible.d org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/printing/PrintDialog.d org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/widgets/Display.d rakefile
diffstat 23 files changed, 3252 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/org.eclipse.equinox.common/src/org/eclipse/core/runtime/Assert.d	Sat Apr 18 13:54:50 2009 +0200
+++ b/org.eclipse.equinox.common/src/org/eclipse/core/runtime/Assert.d	Sat Apr 18 13:58:35 2009 +0200
@@ -79,8 +79,11 @@
     public static void isNotNull(Object object) {
         isNotNull(object, ""); //$NON-NLS-1$
     }
-    public static void isNotNull(String object) {
-        isTrue(object.ptr !is null); //$NON-NLS-1$
+    public static void isNotNull(String str) {
+        isTrue(str.ptr !is null); //$NON-NLS-1$
+    }
+    public static void isNotNull(void* ptr) {
+        isTrue(ptr !is null); //$NON-NLS-1$
     }
 
     /** Asserts that the given object is not <code>null</code>. If this
@@ -94,6 +97,12 @@
         if (object is null)
             throw new AssertionFailedException("null argument:" ~ message); //$NON-NLS-1$
     }
+    public static void isNotNull(String str, String message) {
+        isTrue(str.ptr !is null, message ); //$NON-NLS-1$
+    }
+    public static void isNotNull(void* ptr, String message) {
+        isTrue(ptr !is null, message ); //$NON-NLS-1$
+    }
 
     /** Asserts that the given bool is <code>true</code>. If this
      * is not the case, some kind of unchecked exception is thrown.
--- a/org.eclipse.jface/src/org/eclipse/jface/action/Action.d	Sat Apr 18 13:54:50 2009 +0200
+++ b/org.eclipse.jface/src/org/eclipse/jface/action/Action.d	Sat Apr 18 13:58:35 2009 +0200
@@ -62,10 +62,10 @@
                 return null;
             }
         };
-        VAL_RADIO_BTN_OFF = new ValueWrapperInt(0);
-        VAL_RADIO_BTN_ON = new ValueWrapperInt(1);
-        VAL_TOGGLE_BTN_OFF = new ValueWrapperBool(false);
-        VAL_TOGGLE_BTN_ON = new ValueWrapperBool(true);
+        VAL_RADIO_BTN_OFF = new Integer(0);
+        VAL_RADIO_BTN_ON = new Integer(1);
+        VAL_TOGGLE_BTN_OFF = new Boolean(false);
+        VAL_TOGGLE_BTN_ON = new Boolean(true);
     }
 
     /*
@@ -74,13 +74,13 @@
      */
     private static const String VAL_PUSH_BTN = "PUSH_BTN"; //$NON-NLS-1$
 
-    private static const ValueWrapperInt VAL_RADIO_BTN_OFF;
+    private static const Integer VAL_RADIO_BTN_OFF;
 
-    private static const ValueWrapperInt VAL_RADIO_BTN_ON;
+    private static const Integer VAL_RADIO_BTN_ON;
 
-    private static const ValueWrapperBool VAL_TOGGLE_BTN_OFF;
+    private static const Boolean VAL_TOGGLE_BTN_OFF;
 
-    private static const ValueWrapperBool VAL_TOGGLE_BTN_ON;
+    private static const Boolean VAL_TOGGLE_BTN_ON;
 
     /**
      * Converts an accelerator key code to a string representation.
--- a/org.eclipse.jface/src/org/eclipse/jface/action/IContributionManagerOverrides.d	Sat Apr 18 13:54:50 2009 +0200
+++ b/org.eclipse.jface/src/org/eclipse/jface/action/IContributionManagerOverrides.d	Sat Apr 18 13:58:35 2009 +0200
@@ -57,7 +57,7 @@
      * @param item the contribution item for which the accelerator value is determined
      * @return the accelerator
      */
-    public ValueWrapperInt getAccelerator(IContributionItem item);
+    public Integer getAccelerator(IContributionItem item);
 
     /**
      * This is not intended to be called outside of the workbench. This method
--- a/org.eclipse.jface/src/org/eclipse/jface/dialogs/Dialog.d	Sat Apr 18 13:54:50 2009 +0200
+++ b/org.eclipse.jface/src/org/eclipse/jface/dialogs/Dialog.d	Sat Apr 18 13:58:35 2009 +0200
@@ -648,10 +648,10 @@
         Button button = new Button(parent, SWT.PUSH);
         button.setText(label);
         button.setFont(JFaceResources.getDialogFont());
-        button.setData(new ValueWrapperInt(id));
+        button.setData(new Integer(id));
         button.addSelectionListener(new class SelectionAdapter {
             public void widgetSelected(SelectionEvent event) {
-                buttonPressed((cast(ValueWrapperInt) event.widget.getData()).value);
+                buttonPressed((cast(Integer) event.widget.getData()).intValue());
             }
         });
         if (defaultButton) {
--- a/org.eclipse.jface/src/org/eclipse/jface/preference/ScaleFieldEditor.d	Sat Apr 18 13:54:50 2009 +0200
+++ b/org.eclipse.jface/src/org/eclipse/jface/preference/ScaleFieldEditor.d	Sat Apr 18 13:58:35 2009 +0200
@@ -379,8 +379,8 @@
         int newValue = scale.getSelection();
         if (newValue !is oldValue) {
             fireStateChanged(IS_VALID, false, true);
-            fireValueChanged(VALUE, new ValueWrapperInt(oldValue),
-                    new ValueWrapperInt(newValue));
+            fireValueChanged(VALUE, new Integer(oldValue),
+                    new Integer(newValue));
             oldValue = newValue;
         }
     }
--- a/org.eclipse.jface/src/org/eclipse/jface/viewers/ComboBoxCellEditor.d	Sat Apr 18 13:54:50 2009 +0200
+++ b/org.eclipse.jface/src/org/eclipse/jface/viewers/ComboBoxCellEditor.d	Sat Apr 18 13:58:35 2009 +0200
@@ -187,7 +187,7 @@
      *         <code>Integer</code>
      */
     protected override Object doGetValue() {
-        return new ValueWrapperInt(selection);
+        return new Integer(selection);
     }
 
     /*
@@ -229,8 +229,8 @@
      *            <code>Integer</code>
      */
     protected override void doSetValue(Object value) {
-        Assert.isTrue(comboBox !is null && (cast(ValueWrapperInt)value ));
-        selection = (cast(ValueWrapperInt) value).value;
+        Assert.isTrue(comboBox !is null && (cast(Integer)value ));
+        selection = (cast(Integer) value).intValue();
         comboBox.select(selection);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.osgi/osgi/src/org/osgi/framework/BundleActivator.d	Sat Apr 18 13:58:35 2009 +0200
@@ -0,0 +1,93 @@
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/BundleActivator.java,v 1.14 2007/02/21 16:49:05 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module org.osgi.framework.BundleActivator;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+import java.lang.all;
+
+/**
+ * Customizes the starting and stopping of a bundle.
+ * <p>
+ * <code>BundleActivator</code> is an interface that may be implemented when a
+ * bundle is started or stopped. The Framework can create instances of a
+ * bundle's <code>BundleActivator</code> as required. If an instance's
+ * <code>BundleActivator.start</code> method executes successfully, it is
+ * guaranteed that the same instance's <code>BundleActivator.stop</code>
+ * method will be called when the bundle is to be stopped. The Framework must
+ * not concurrently call a <code>BundleActivator</code> object.
+ * 
+ * <p>
+ * <code>BundleActivator</code> is specified through the
+ * <code>Bundle-Activator</code> Manifest header. A bundle can only specify a
+ * single <code>BundleActivator</code> in the Manifest file. Fragment bundles
+ * must not have a <code>BundleActivator</code>. The form of the Manifest
+ * header is:
+ * 
+ * <p>
+ * <code>Bundle-Activator: <i>class-name</i></code>
+ * 
+ * <p>
+ * where <code><i>class-name</i></code> is a fully qualified Java classname.
+ * <p>
+ * The specified <code>BundleActivator</code> class must have a public
+ * constructor that takes no parameters so that a <code>BundleActivator</code>
+ * object can be created by <code>Class.newInstance()</code>.
+ * 
+ * @NotThreadSafe
+ * @version $Revision: 1.14 $
+ */
+
+public interface BundleActivator {
+    /**
+     * Called when this bundle is started so the Framework can perform the
+     * bundle-specific activities necessary to start this bundle. This method
+     * can be used to register services or to allocate any resources that this
+     * bundle needs.
+     * 
+     * <p>
+     * This method must complete and return to its caller in a timely manner.
+     * 
+     * @param context The execution context of the bundle being started.
+     * @throws java.lang.Exception If this method throws an exception, this
+     *         bundle is marked as stopped and the Framework will remove this
+     *         bundle's listeners, unregister all services registered by this
+     *         bundle, and release all services used by this bundle.
+     */
+    public void start(BundleContext context);
+
+    /**
+     * Called when this bundle is stopped so the Framework can perform the
+     * bundle-specific activities necessary to stop the bundle. In general, this
+     * method should undo the work that the <code>BundleActivator.start</code>
+     * method started. There should be no active threads that were started by
+     * this bundle when this bundle returns. A stopped bundle must not call any
+     * Framework objects.
+     * 
+     * <p>
+     * This method must complete and return to its caller in a timely manner.
+     * 
+     * @param context The execution context of the bundle being stopped.
+     * @throws java.lang.Exception If this method throws an exception, the
+     *         bundle is still marked as stopped, and the Framework will remove
+     *         the bundle's listeners, unregister all services registered by the
+     *         bundle, and release all services used by the bundle.
+     */
+    public void stop(BundleContext context);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.osgi/osgi/src/org/osgi/framework/BundleContext.d	Sat Apr 18 13:58:35 2009 +0200
@@ -0,0 +1,830 @@
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/BundleContext.java,v 1.22 2007/02/21 16:49:05 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module org.osgi.framework.BundleContext;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.Filter;
+
+import java.lang.all;
+import java.io.File;
+import java.io.InputStream;
+import java.util.Dictionary;
+
+/**
+ * A bundle's execution context within the Framework. The context is used to
+ * grant access to other methods so that this bundle can interact with the
+ * Framework.
+ * 
+ * <p>
+ * <code>BundleContext</code> methods allow a bundle to:
+ * <ul>
+ * <li>Subscribe to events published by the Framework.
+ * <li>Register service objects with the Framework service registry.
+ * <li>Retrieve <code>ServiceReferences</code> from the Framework service
+ * registry.
+ * <li>Get and release service objects for a referenced service.
+ * <li>Install new bundles in the Framework.
+ * <li>Get the list of bundles installed in the Framework.
+ * <li>Get the {@link Bundle} object for a bundle.
+ * <li>Create <code>File</code> objects for files in a persistent storage
+ * area provided for the bundle by the Framework.
+ * </ul>
+ * 
+ * <p>
+ * A <code>BundleContext</code> object will be created and provided to the
+ * bundle associated with this context when it is started using the
+ * {@link BundleActivator#start} method. The same <code>BundleContext</code>
+ * object will be passed to the bundle associated with this context when it is
+ * stopped using the {@link BundleActivator#stop} method. A
+ * <code>BundleContext</code> object is generally for the private use of its
+ * associated bundle and is not meant to be shared with other bundles in the
+ * OSGi environment.
+ * 
+ * <p>
+ * The <code>Bundle</code> object associated with a <code>BundleContext</code>
+ * object is called the <em>context bundle</em>.
+ * 
+ * <p>
+ * The <code>BundleContext</code> object is only valid during the execution of
+ * its context bundle; that is, during the period from when the context bundle
+ * is in the <code>STARTING</code>, <code>STOPPING</code>, and
+ * <code>ACTIVE</code> bundle states. If the <code>BundleContext</code>
+ * object is used subsequently, an <code>IllegalStateException</code> must be
+ * thrown. The <code>BundleContext</code> object must never be reused after
+ * its context bundle is stopped.
+ * 
+ * <p>
+ * The Framework is the only entity that can create <code>BundleContext</code>
+ * objects and they are only valid within the Framework that created them.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 1.22 $
+ */
+
+public interface BundleContext {
+    /**
+     * Returns the value of the specified property. If the key is not found in
+     * the Framework properties, the system properties are then searched. The
+     * method returns <code>null</code> if the property is not found.
+     * 
+     * <p>
+     * The Framework defines the following standard property keys:
+     * </p>
+     * <ul>
+     * <li>{@link Constants#FRAMEWORK_VERSION} - The OSGi Framework version.
+     * </li>
+     * <li>{@link Constants#FRAMEWORK_VENDOR} - The Framework implementation
+     * vendor.</li>
+     * <li>{@link Constants#FRAMEWORK_LANGUAGE} - The language being used. See
+     * ISO 639 for possible values.</li>
+     * <li>{@link Constants#FRAMEWORK_OS_NAME} - The host computer operating
+     * system.</li>
+     * <li>{@link Constants#FRAMEWORK_OS_VERSION} - The host computer
+     * operating system version number.</li>
+     * <li>{@link Constants#FRAMEWORK_PROCESSOR} - The host computer processor
+     * name.</li>
+     * </ul>
+     * <p>
+     * All bundles must have permission to read these properties.
+     * 
+     * <p>
+     * Note: The last four standard properties are used by the
+     * {@link Constants#BUNDLE_NATIVECODE} <code>Manifest</code> header's
+     * matching algorithm for selecting native language code.
+     * 
+     * @param key The name of the requested property.
+     * @return The value of the requested property, or <code>null</code> if
+     *         the property is undefined.
+     * @throws java.lang.SecurityException If the caller does not have the
+     *         appropriate <code>PropertyPermission</code> to read the
+     *         property, and the Java Runtime Environment supports permissions.
+     */
+    public String getProperty(String key);
+
+    /**
+     * Returns the <code>Bundle</code> object associated with this
+     * <code>BundleContext</code>. This bundle is called the context bundle.
+     * 
+     * @return The <code>Bundle</code> object associated with this
+     *         <code>BundleContext</code>.
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     */
+    public Bundle getBundle();
+
+    /**
+     * Installs a bundle from the specified location string. A bundle is
+     * obtained from <code>location</code> as interpreted by the Framework in
+     * an implementation dependent manner.
+     * <p>
+     * Every installed bundle is uniquely identified by its location string,
+     * typically in the form of a URL.
+     * 
+     * <p>
+     * The following steps are required to install a bundle:
+     * <ol>
+     * <li>If a bundle containing the same location string is already
+     * installed, the <code>Bundle</code> object for that bundle is returned.
+     * 
+     * <li>The bundle's content is read from the location string. If this
+     * fails, a {@link BundleException} is thrown.
+     * 
+     * <li>The bundle's <code>Bundle-NativeCode</code> dependencies are
+     * resolved. If this fails, a <code>BundleException</code> is thrown.
+     * 
+     * <li>The bundle's associated resources are allocated. The associated
+     * resources minimally consist of a unique identifier and a persistent
+     * storage area if the platform has file system support. If this step fails,
+     * a <code>BundleException</code> is thrown.
+     * 
+     * <li>If the bundle has declared an Bundle-RequiredExecutionEnvironment
+     * header, then the listed execution environments must be verified against
+     * the installed execution environments. If none of the listed execution 
+     * environments match an installed execution environment, a
+     * <code>BundleException</code> must be thrown.
+     * 
+     * <li>The bundle's state is set to <code>INSTALLED</code>.
+     * 
+     * <li>A bundle event of type {@link BundleEvent#INSTALLED} is fired.
+     * 
+     * <li>The <code>Bundle</code> object for the newly or previously
+     * installed bundle is returned.
+     * </ol>
+     * 
+     * <b>Postconditions, no exceptions thrown </b>
+     * <ul>
+     * <li><code>getState()</code> in {<code>INSTALLED</code>,<code>RESOLVED</code>}.
+     * <li>Bundle has a unique ID.
+     * </ul>
+     * <b>Postconditions, when an exception is thrown </b>
+     * <ul>
+     * <li>Bundle is not installed and no trace of the bundle exists.
+     * </ul>
+     * 
+     * @param location The location identifier of the bundle to install.
+     * @return The <code>Bundle</code> object of the installed bundle.
+     * @throws BundleException If the installation failed.
+     * @throws java.lang.SecurityException If the caller does not have the
+     *         appropriate <code>AdminPermission[installed bundle,LIFECYCLE]</code>, and the
+     *         Java Runtime Environment supports permissions.
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     */
+    public Bundle installBundle(String location);
+
+    /**
+     * Installs a bundle from the specified <code>InputStream</code> object.
+     * 
+     * <p>
+     * This method performs all of the steps listed in
+     * <code>BundleContext.installBundle(String location)</code>, except that
+     * the bundle's content will be read from the <code>InputStream</code>
+     * object. The location identifier string specified will be used as the
+     * identity of the bundle.
+     * 
+     * <p>
+     * This method must always close the <code>InputStream</code> object, even
+     * if an exception is thrown.
+     * 
+     * @param location The location identifier of the bundle to install.
+     * @param input The <code>InputStream</code> object from which this bundle
+     *        will be read.
+     * @return The <code>Bundle</code> object of the installed bundle.
+     * @throws BundleException If the provided stream cannot be read or the
+     *         installation failed.
+     * @throws java.lang.SecurityException If the caller does not have the
+     *         appropriate <code>AdminPermission[installed bundle,LIFECYCLE]</code>, and the
+     *         Java Runtime Environment supports permissions.
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     * @see #installBundle(java.lang.String)
+     */
+    public Bundle installBundle(String location, InputStream input);
+
+    /**
+     * Returns the bundle with the specified identifier.
+     * 
+     * @param id The identifier of the bundle to retrieve.
+     * @return A <code>Bundle</code> object or <code>null</code> if the
+     *         identifier does not match any installed bundle.
+     */
+    public Bundle getBundle(long id);
+
+    /**
+     * Returns a list of all installed bundles.
+     * <p>
+     * This method returns a list of all bundles installed in the OSGi
+     * environment at the time of the call to this method. However, since the
+     * Framework is a very dynamic environment, bundles can be installed or
+     * uninstalled at anytime.
+     * 
+     * @return An array of <code>Bundle</code> objects, one object per
+     *         installed bundle.
+     */
+    public Bundle[] getBundles();
+
+    /**
+     * Adds the specified <code>ServiceListener</code> object with the
+     * specified <code>filter</code> to the context bundle's list of
+     * listeners. See {@link Filter} for a description of the filter syntax.
+     * <code>ServiceListener</code> objects are notified when a service has a
+     * lifecycle state change.
+     * 
+     * <p>
+     * If the context bundle's list of listeners already contains a listener
+     * <code>l</code> such that <code>(l==listener)</code>, then this
+     * method replaces that listener's filter (which may be <code>null</code>)
+     * with the specified one (which may be <code>null</code>).
+     * 
+     * <p>
+     * The listener is called if the filter criteria is met. To filter based
+     * upon the class of the service, the filter should reference the
+     * {@link Constants#OBJECTCLASS} property. If <code>filter</code> is
+     * <code>null</code>, all services are considered to match the filter.
+     * 
+     * <p>
+     * When using a <code>filter</code>, it is possible that the
+     * <code>ServiceEvent</code>s for the complete lifecycle of a service
+     * will not be delivered to the listener. For example, if the
+     * <code>filter</code> only matches when the property <code>x</code> has
+     * the value <code>1</code>, the listener will not be called if the
+     * service is registered with the property <code>x</code> not set to the
+     * value <code>1</code>. Subsequently, when the service is modified
+     * setting property <code>x</code> to the value <code>1</code>, the
+     * filter will match and the listener will be called with a
+     * <code>ServiceEvent</code> of type <code>MODIFIED</code>. Thus, the
+     * listener will not be called with a <code>ServiceEvent</code> of type
+     * <code>REGISTERED</code>.
+     * 
+     * <p>
+     * If the Java Runtime Environment supports permissions, the
+     * <code>ServiceListener</code> object will be notified of a service event
+     * only if the bundle that is registering it has the
+     * <code>ServicePermission</code> to get the service using at least one of
+     * the named classes the service was registered under.
+     * 
+     * @param listener The <code>ServiceListener</code> object to be added.
+     * @param filter The filter criteria.
+     * 
+     * @throws InvalidSyntaxException If <code>filter</code> contains an
+     *         invalid filter string that cannot be parsed.
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     * 
+     * @see ServiceEvent
+     * @see ServiceListener
+     * @see ServicePermission
+     */
+    public void addServiceListener(ServiceListener listener,
+            String filter);
+
+    /**
+     * Adds the specified <code>ServiceListener</code> object to the context
+     * bundle's list of listeners.
+     * 
+     * <p>
+     * This method is the same as calling
+     * <code>BundleContext.addServiceListener(ServiceListener listener,
+     * String filter)</code>
+     * with <code>filter</code> set to <code>null</code>.
+     * 
+     * @param listener The <code>ServiceListener</code> object to be added.
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     * 
+     * @see #addServiceListener(ServiceListener, String)
+     */
+    public void addServiceListener(ServiceListener listener);
+
+    /**
+     * Removes the specified <code>ServiceListener</code> object from the
+     * context bundle's list of listeners.
+     * 
+     * <p>
+     * If <code>listener</code> is not contained in this context bundle's list
+     * of listeners, this method does nothing.
+     * 
+     * @param listener The <code>ServiceListener</code> to be removed.
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     */
+    public void removeServiceListener(ServiceListener listener);
+
+    /**
+     * Adds the specified <code>BundleListener</code> object to the context
+     * bundle's list of listeners if not already present. BundleListener objects
+     * are notified when a bundle has a lifecycle state change.
+     * 
+     * <p>
+     * If the context bundle's list of listeners already contains a listener
+     * <code>l</code> such that <code>(l==listener)</code>, this method
+     * does nothing.
+     * 
+     * @param listener The <code>BundleListener</code> to be added.
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     * @throws java.lang.SecurityException If listener is a
+     *         <code>SynchronousBundleListener</code> and the caller does not
+     *         have the appropriate <code>AdminPermission[context bundle,LISTENER]</code>,
+     *         and the Java Runtime Environment supports permissions.
+     * 
+     * @see BundleEvent
+     * @see BundleListener
+     */
+    public void addBundleListener(BundleListener listener);
+
+    /**
+     * Removes the specified <code>BundleListener</code> object from the
+     * context bundle's list of listeners.
+     * 
+     * <p>
+     * If <code>listener</code> is not contained in the context bundle's list
+     * of listeners, this method does nothing.
+     * 
+     * @param listener The <code>BundleListener</code> object to be removed.
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     * @throws java.lang.SecurityException If listener is a
+     *         <code>SynchronousBundleListener</code> and the caller does not
+     *         have the appropriate <code>AdminPermission[context bundle,LISTENER]</code>,
+     *         and the Java Runtime Environment supports permissions.
+     */
+    public void removeBundleListener(BundleListener listener);
+
+    /**
+     * Adds the specified <code>FrameworkListener</code> object to the context
+     * bundle's list of listeners if not already present. FrameworkListeners are
+     * notified of general Framework events.
+     * 
+     * <p>
+     * If the context bundle's list of listeners already contains a listener
+     * <code>l</code> such that <code>(l==listener)</code>, this method
+     * does nothing.
+     * 
+     * @param listener The <code>FrameworkListener</code> object to be added.
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     * 
+     * @see FrameworkEvent
+     * @see FrameworkListener
+     */
+    public void addFrameworkListener(FrameworkListener listener);
+
+    /**
+     * Removes the specified <code>FrameworkListener</code> object from the
+     * context bundle's list of listeners.
+     * 
+     * <p>
+     * If <code>listener</code> is not contained in the context bundle's list
+     * of listeners, this method does nothing.
+     * 
+     * @param listener The <code>FrameworkListener</code> object to be
+     *        removed.
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     */
+    public void removeFrameworkListener(FrameworkListener listener);
+
+    /**
+     * Registers the specified service object with the specified properties
+     * under the specified class names into the Framework. A
+     * <code>ServiceRegistration</code> object is returned. The
+     * <code>ServiceRegistration</code> object is for the private use of the
+     * bundle registering the service and should not be shared with other
+     * bundles. The registering bundle is defined to be the context bundle.
+     * Other bundles can locate the service by using either the
+     * {@link #getServiceReferences} or {@link #getServiceReference} method.
+     * 
+     * <p>
+     * A bundle can register a service object that implements the
+     * {@link ServiceFactory} interface to have more flexibility in providing
+     * service objects to other bundles.
+     * 
+     * <p>
+     * The following steps are required to register a service:
+     * <ol>
+     * <li>If <code>service</code> is not a <code>ServiceFactory</code>,
+     * an <code>IllegalArgumentException</code> is thrown if
+     * <code>service</code> is not an <code>instanceof</code> all the
+     * classes named.
+     * <li>The Framework adds these service properties to the specified
+     * <code>Dictionary</code> (which may be <code>null</code>): a property
+     * named {@link Constants#SERVICE_ID} identifying the registration number of
+     * the service and a property named {@link Constants#OBJECTCLASS} containing
+     * all the specified classes. If any of these properties have already been
+     * specified by the registering bundle, their values will be overwritten by
+     * the Framework.
+     * <li>The service is added to the Framework service registry and may now
+     * be used by other bundles.
+     * <li>A service event of type {@link ServiceEvent#REGISTERED} is
+     * fired.
+     * <li>A <code>ServiceRegistration</code> object for this registration is
+     * returned.
+     * </ol>
+     * 
+     * @param clazzes The class names under which the service can be located.
+     *        The class names in this array will be stored in the service's
+     *        properties under the key {@link Constants#OBJECTCLASS}.
+     * @param service The service object or a <code>ServiceFactory</code>
+     *        object.
+     * @param properties The properties for this service. The keys in the
+     *        properties object must all be <code>String</code> objects. See
+     *        {@link Constants} for a list of standard service property keys.
+     *        Changes should not be made to this object after calling this
+     *        method. To update the service's properties the
+     *        {@link ServiceRegistration#setProperties} method must be called.
+     *        The set of properties may be <code>null</code> if the service
+     *        has no properties.
+     * 
+     * @return A <code>ServiceRegistration</code> object for use by the bundle
+     *         registering the service to update the service's properties or to
+     *         unregister the service.
+     * 
+     * @throws java.lang.IllegalArgumentException If one of the following is
+     *         true:
+     *         <ul>
+     *         <li><code>service</code> is <code>null</code>.
+     *         <li><code>service</code> is not a <code>ServiceFactory</code>
+     *         object and is not an instance of all the named classes in
+     *         <code>clazzes</code>.
+     *         <li><code>properties</code> contains case variants of the same
+     *         key name.
+     *         </ul>
+     * 
+     * @throws java.lang.SecurityException If the caller does not have the
+     *         <code>ServicePermission</code> to register the service for all
+     *         the named classes and the Java Runtime Environment supports
+     *         permissions.
+     * 
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     * 
+     * @see ServiceRegistration
+     * @see ServiceFactory
+     */
+    public ServiceRegistration registerService(String[] clazzes,
+            Object service, Dictionary properties);
+
+    /**
+     * Registers the specified service object with the specified properties
+     * under the specified class name with the Framework.
+     * 
+     * <p>
+     * This method is otherwise identical to
+     * {@link #registerService(java.lang.String[], java.lang.Object,
+     * java.util.Dictionary)} and is provided as a convenience when
+     * <code>service</code> will only be registered under a single class name.
+     * Note that even in this case the value of the service's
+     * {@link Constants#OBJECTCLASS} property will be an array of strings,
+     * rather than just a single string.
+     * 
+     * @param clazz The class name under which the service can be located.
+     * @param service The service object or a <code>ServiceFactory</code>
+     *        object.
+     * @param properties The properties for this service. 
+     * 
+     * @return A <code>ServiceRegistration</code> object for use by the bundle
+     *         registering the service to update the service's properties or to
+     *         unregister the service.
+     *         
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     * @see #registerService(java.lang.String[], java.lang.Object,
+     *      java.util.Dictionary)
+     */
+    public ServiceRegistration registerService(String clazz,
+            Object service, Dictionary properties);
+
+    /**
+     * Returns an array of <code>ServiceReference</code> objects. The returned
+     * array of <code>ServiceReference</code> objects contains services that
+     * were registered under the specified class, match the specified filter
+     * criteria, and the packages for the class names under which the services
+     * were registered match the context bundle's packages as defined in
+     * {@link ServiceReference#isAssignableTo(Bundle, String)}.
+     * 
+     * <p>
+     * The list is valid at the time of the call to this method, however since
+     * the Framework is a very dynamic environment, services can be modified or
+     * unregistered at anytime.
+     * 
+     * <p>
+     * <code>filter</code> is used to select the registered service whose
+     * properties objects contain keys and values which satisfy the filter. See
+     * {@link Filter} for a description of the filter string syntax.
+     * 
+     * <p>
+     * If <code>filter</code> is <code>null</code>, all registered services
+     * are considered to match the filter. If <code>filter</code> cannot be
+     * parsed, an {@link InvalidSyntaxException} will be thrown with a human
+     * readable message where the filter became unparsable.
+     * 
+     * <p>
+     * The following steps are required to select a set of
+     * <code>ServiceReference</code> objects:
+     * <ol>
+     * <li>If the filter string is not <code>null</code>, the filter string
+     * is parsed and the set <code>ServiceReference</code> objects of
+     * registered services that satisfy the filter is produced. If the filter
+     * string is <code>null</code>, then all registered services are
+     * considered to satisfy the filter.
+     * <li>If the Java Runtime Environment supports permissions, the set of
+     * <code>ServiceReference</code> objects produced by the previous step is
+     * reduced by checking that the caller has the
+     * <code>ServicePermission</code> to get at least one of the class names
+     * under which the service was registered. If the caller does not have the
+     * correct permission for a particular <code>ServiceReference</code>
+     * object, then it is removed from the set.
+     * <li>If <code>clazz</code> is not <code>null</code>, the set is
+     * further reduced to those services that are an <code>instanceof</code>
+     * and were registered under the specified class. The complete list of
+     * classes of which a service is an instance and which were specified when
+     * the service was registered is available from the service's
+     * {@link Constants#OBJECTCLASS} property.
+     * <li>The set is reduced one final time by cycling through each
+     * <code>ServiceReference</code> object and calling
+     * {@link ServiceReference#isAssignableTo(Bundle, String)} with the context
+     * bundle and each class name under which the <code>ServiceReference</code>
+     * object was registered. For any given <code>ServiceReference</code>
+     * object, if any call to
+     * {@link ServiceReference#isAssignableTo(Bundle, String)} returns
+     * <code>false</code>, then it is removed from the set of
+     * <code>ServiceReference</code> objects.
+     * <li>An array of the remaining <code>ServiceReference</code> objects is
+     * returned.
+     * </ol>
+     * 
+     * @param clazz The class name with which the service was registered or
+     *        <code>null</code> for all services.
+     * @param filter The filter criteria.
+     * @return An array of <code>ServiceReference</code> objects or
+     *         <code>null</code> if no services are registered which satisfy
+     *         the search.
+     * @throws InvalidSyntaxException If <code>filter</code> contains an
+     *         invalid filter string that cannot be parsed.
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     */
+    public ServiceReference[] getServiceReferences(String clazz,
+            String filter);
+
+    /**
+     * Returns an array of <code>ServiceReference</code> objects. The returned
+     * array of <code>ServiceReference</code> objects contains services that
+     * were registered under the specified class and match the specified filter
+     * criteria.
+     * 
+     * <p>
+     * The list is valid at the time of the call to this method, however since
+     * the Framework is a very dynamic environment, services can be modified or
+     * unregistered at anytime.
+     * 
+     * <p>
+     * <code>filter</code> is used to select the registered service whose
+     * properties objects contain keys and values which satisfy the filter. See
+     * {@link Filter} for a description of the filter string syntax.
+     * 
+     * <p>
+     * If <code>filter</code> is <code>null</code>, all registered services
+     * are considered to match the filter. If <code>filter</code> cannot be
+     * parsed, an {@link InvalidSyntaxException} will be thrown with a human
+     * readable message where the filter became unparsable.
+     * 
+     * <p>
+     * The following steps are required to select a set of
+     * <code>ServiceReference</code> objects:
+     * <ol>
+     * <li>If the filter string is not <code>null</code>, the filter string
+     * is parsed and the set <code>ServiceReference</code> objects of
+     * registered services that satisfy the filter is produced. If the filter
+     * string is <code>null</code>, then all registered services are
+     * considered to satisfy the filter.
+     * <li>If the Java Runtime Environment supports permissions, the set of
+     * <code>ServiceReference</code> objects produced by the previous step is
+     * reduced by checking that the caller has the
+     * <code>ServicePermission</code> to get at least one of the class names
+     * under which the service was registered. If the caller does not have the
+     * correct permission for a particular <code>ServiceReference</code>
+     * object, then it is removed from the set.
+     * <li>If <code>clazz</code> is not <code>null</code>, the set is
+     * further reduced to those services that are an <code>instanceof</code>
+     * and were registered under the specified class. The complete list of
+     * classes of which a service is an instance and which were specified when
+     * the service was registered is available from the service's
+     * {@link Constants#OBJECTCLASS} property.
+     * <li>An array of the remaining <code>ServiceReference</code> objects is
+     * returned.
+     * </ol>
+     * 
+     * @param clazz The class name with which the service was registered or
+     *        <code>null</code> for all services.
+     * @param filter The filter criteria.
+     * @return An array of <code>ServiceReference</code> objects or
+     *         <code>null</code> if no services are registered which satisfy
+     *         the search.
+     * @throws InvalidSyntaxException If <code>filter</code> contains an
+     *         invalid filter string that cannot be parsed.
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     * @since 1.3
+     */
+    public ServiceReference[] getAllServiceReferences(String clazz,
+            String filter);
+
+    /**
+     * Returns a <code>ServiceReference</code> object for a service that
+     * implements and was registered under the specified class.
+     * 
+     * <p>
+     * This <code>ServiceReference</code> object is valid at the time of the
+     * call to this method, however as the Framework is a very dynamic
+     * environment, services can be modified or unregistered at anytime.
+     * 
+     * <p>
+     * This method is the same as calling
+     * {@link BundleContext#getServiceReferences(String, String)} with a
+     * <code>null</code> filter string. It is provided as a convenience for
+     * when the caller is interested in any service that implements the
+     * specified class.
+     * <p>
+     * If multiple such services exist, the service with the highest ranking (as
+     * specified in its {@link Constants#SERVICE_RANKING} property) is returned.
+     * <p>
+     * If there is a tie in ranking, the service with the lowest service ID (as
+     * specified in its {@link Constants#SERVICE_ID} property); that is, the
+     * service that was registered first is returned.
+     * 
+     * @param clazz The class name with which the service was registered.
+     * @return A <code>ServiceReference</code> object, or <code>null</code>
+     *         if no services are registered which implement the named class.
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     * @see #getServiceReferences(String, String)
+     */
+    public ServiceReference getServiceReference(String clazz);
+
+    /**
+     * Returns the specified service object for a service.
+     * <p>
+     * A bundle's use of a service is tracked by the bundle's use count of that
+     * service. Each time a service's service object is returned by
+     * {@link #getService(ServiceReference)} the context bundle's use count for
+     * that service is incremented by one. Each time the service is released by
+     * {@link #ungetService(ServiceReference)} the context bundle's use count
+     * for that service is decremented by one.
+     * <p>
+     * When a bundle's use count for a service drops to zero, the bundle should
+     * no longer use that service.
+     * 
+     * <p>
+     * This method will always return <code>null</code> when the service
+     * associated with this <code>reference</code> has been unregistered.
+     * 
+     * <p>
+     * The following steps are required to get the service object:
+     * <ol>
+     * <li>If the service has been unregistered, <code>null</code> is
+     * returned.
+     * <li>The context bundle's use count for this service is incremented by
+     * one.
+     * <li>If the context bundle's use count for the service is currently one
+     * and the service was registered with an object implementing the
+     * <code>ServiceFactory</code> interface, the
+     * {@link ServiceFactory#getService(Bundle, ServiceRegistration)} method is
+     * called to create a service object for the context bundle. This service
+     * object is cached by the Framework. While the context bundle's use count
+     * for the service is greater than zero, subsequent calls to get the
+     * services's service object for the context bundle will return the cached
+     * service object. <br>
+     * If the service object returned by the <code>ServiceFactory</code>
+     * object is not an <code>instanceof</code> all the classes named when the
+     * service was registered or the <code>ServiceFactory</code> object throws
+     * an exception, <code>null</code> is returned and a Framework event of
+     * type {@link FrameworkEvent#ERROR} is fired.
+     * <li>The service object for the service is returned.
+     * </ol>
+     * 
+     * @param reference A reference to the service.
+     * @return A service object for the service associated with
+     *         <code>reference</code> or <code>null</code> if the service is
+     *         not registered or does not implement the classes under which it
+     *         was registered in the case of a <code>ServiceFactory</code>.
+     * @throws java.lang.SecurityException If the caller does not have the
+     *         <code>ServicePermission</code> to get the service using at
+     *         least one of the named classes the service was registered under
+     *         and the Java Runtime Environment supports permissions.
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     * @see #ungetService(ServiceReference)
+     * @see ServiceFactory
+     */
+    public Object getService(ServiceReference reference);
+
+    /**
+     * Releases the service object referenced by the specified
+     * <code>ServiceReference</code> object. If the context bundle's use count
+     * for the service is zero, this method returns <code>false</code>.
+     * Otherwise, the context bundle's use count for the service is decremented
+     * by one.
+     * 
+     * <p>
+     * The service's service object should no longer be used and all references
+     * to it should be destroyed when a bundle's use count for the service drops
+     * to zero.
+     * 
+     * <p>
+     * The following steps are required to unget the service object:
+     * <ol>
+     * <li>If the context bundle's use count for the service is zero or the
+     * service has been unregistered, <code>false</code> is returned.
+     * <li>The context bundle's use count for this service is decremented by
+     * one.
+     * <li>If the context bundle's use count for the service is currently zero
+     * and the service was registered with a <code>ServiceFactory</code>
+     * object, the
+     * {@link ServiceFactory#ungetService(Bundle, ServiceRegistration, Object)}
+     * method is called to release the service object for the context bundle.
+     * <li><code>true</code> is returned.
+     * </ol>
+     * 
+     * @param reference A reference to the service to be released.
+     * @return <code>false</code> if the context bundle's use count for the
+     *         service is zero or if the service has been unregistered;
+     *         <code>true</code> otherwise.
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     * @see #getService
+     * @see ServiceFactory
+     */
+    public bool ungetService(ServiceReference reference);
+
+    /**
+     * Creates a <code>File</code> object for a file in the persistent storage
+     * area provided for the bundle by the Framework. This method will return
+     * <code>null</code> if the platform does not have file system support.
+     * 
+     * <p>
+     * A <code>File</code> object for the base directory of the persistent
+     * storage area provided for the context bundle by the Framework can be
+     * obtained by calling this method with an empty string as
+     * <code>filename</code>.
+     * 
+     * <p>
+     * If the Java Runtime Environment supports permissions, the Framework will
+     * ensure that the bundle has the <code>java.io.FilePermission</code> with
+     * actions <code>read</code>,<code>write</code>,<code>delete</code>
+     * for all files (recursively) in the persistent storage area provided for
+     * the context bundle.
+     * 
+     * @param filename A relative name to the file to be accessed.
+     * @return A <code>File</code> object that represents the requested file
+     *         or <code>null</code> if the platform does not have file system
+     *         support.
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     */
+    public File getDataFile(String filename);
+
+    /**
+     * Creates a <code>Filter</code> object. This <code>Filter</code> object
+     * may be used to match a <code>ServiceReference</code> object or a
+     * <code>Dictionary</code> object.
+     * 
+     * <p>
+     * If the filter cannot be parsed, an {@link InvalidSyntaxException} will be
+     * thrown with a human readable message where the filter became unparsable.
+     * 
+     * @param filter The filter string.
+     * @return A <code>Filter</code> object encapsulating the filter string.
+     * @throws InvalidSyntaxException If <code>filter</code> contains an
+     *         invalid filter string that cannot be parsed.
+     * @throws NullPointerException If <code>filter</code> is null.
+     * @throws java.lang.IllegalStateException If this BundleContext is no
+     *         longer valid.
+     * 
+     * @since 1.1
+     * @see "Framework specification for a description of the filter string syntax."
+     * @see FrameworkUtil#createFilter(String)
+     */
+    public Filter createFilter(String filter);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.osgi/osgi/src/org/osgi/framework/BundleEvent.d	Sat Apr 18 13:58:35 2009 +0200
@@ -0,0 +1,218 @@
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/BundleEvent.java,v 1.19 2007/02/20 00:14:12 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module org.osgi.framework.BundleEvent;
+import org.osgi.framework.Bundle;
+
+import java.util.EventObject;
+
+/**
+ * An event from the Framework describing a bundle lifecycle change.
+ * <p>
+ * <code>BundleEvent</code> objects are delivered to
+ * <code>SynchronousBundleListener</code>s and <code>BundleListener</code>s
+ * when a change occurs in a bundle's lifecycle. A type code is used to identify
+ * the event type for future extendability.
+ * 
+ * <p>
+ * OSGi Alliance reserves the right to extend the set of types.
+ * 
+ * @Immutable
+ * @see BundleListener
+ * @see SynchronousBundleListener
+ * @version $Revision: 1.19 $
+ */
+
+public class BundleEvent : EventObject {
+    static final long       serialVersionUID    = 4080640865971756012L;
+    /**
+     * Bundle that had a change occur in its lifecycle.
+     */
+    private final Bundle    bundle;
+
+    /**
+     * Type of bundle lifecycle change.
+     */
+    private final int       type;
+
+    /**
+     * The bundle has been installed.
+     * <p>
+     * The value of <code>INSTALLED</code> is 0x00000001.
+     * 
+     * @see BundleContext#installBundle(String)
+     */
+    public final static int INSTALLED           = 0x00000001;
+
+    /**
+     * The bundle has been started.
+     * <p>
+     * The bundle's
+     * {@link BundleActivator#start(BundleContext) BundleActivator start} method
+     * has been executed if the bundle has a bundle activator class.
+     * <p>
+     * The value of <code>STARTED</code> is 0x00000002.
+     * 
+     * @see Bundle#start()
+     */
+    public final static int STARTED             = 0x00000002;
+
+    /**
+     * The bundle has been stopped.
+     * <p>
+     * The bundle's
+     * {@link BundleActivator#stop(BundleContext) BundleActivator stop} method
+     * has been executed if the bundle has a bundle activator class.
+     * <p>
+     * The value of <code>STOPPED</code> is 0x00000004.
+     * 
+     * @see Bundle#stop()
+     */
+    public final static int STOPPED             = 0x00000004;
+
+    /**
+     * The bundle has been updated.
+     * <p>
+     * The value of <code>UPDATED</code> is 0x00000008.
+     * 
+     * @see Bundle#update()
+     */
+    public final static int UPDATED             = 0x00000008;
+
+    /**
+     * The bundle has been uninstalled.
+     * <p>
+     * The value of <code>UNINSTALLED</code> is 0x00000010.
+     * 
+     * @see Bundle#uninstall
+     */
+    public final static int UNINSTALLED         = 0x00000010;
+
+    /**
+     * The bundle has been resolved.
+     * <p>
+     * The value of <code>RESOLVED</code> is 0x00000020.
+     * 
+     * @see Bundle#RESOLVED
+     * @since 1.3
+     */
+    public final static int RESOLVED            = 0x00000020;
+
+    /**
+     * The bundle has been unresolved.
+     * <p>
+     * The value of <code>UNRESOLVED</code> is 0x00000040.
+     * 
+     * @see Bundle#INSTALLED
+     * @since 1.3
+     */
+    public final static int UNRESOLVED          = 0x00000040;
+
+    /**
+     * The bundle is about to be activated.
+     * <p>
+     * The bundle's
+     * {@link BundleActivator#start(BundleContext) BundleActivator start} method
+     * is about to be called if the bundle has a bundle activator class. This
+     * event is only delivered to {@link SynchronousBundleListener}s. It is not
+     * delivered to <code>BundleListener</code>s.
+     * <p>
+     * The value of <code>STARTING</code> is 0x00000080.
+     * 
+     * @see Bundle#start()
+     * @since 1.3
+     */
+    public final static int STARTING            = 0x00000080;
+
+    /**
+     * The bundle is about to deactivated.
+     * <p>
+     * The bundle's
+     * {@link BundleActivator#stop(BundleContext) BundleActivator stop} method
+     * is about to be called if the bundle has a bundle activator class. This
+     * event is only delivered to {@link SynchronousBundleListener}s. It is not
+     * delivered to <code>BundleListener</code>s.
+     * <p>
+     * The value of <code>STOPPING</code> is 0x00000100.
+     * 
+     * @see Bundle#stop()
+     * @since 1.3
+     */
+    public final static int STOPPING            = 0x00000100;
+
+    /**
+     * The bundle will be lazily activated.
+     * <p>
+     * The bundle has a {@link Constants#ACTIVATION_LAZY lazy activation policy}
+     * and is waiting to be activated. It is now in the
+     * {@link Bundle#STARTING STARTING} state and has a valid
+     * <code>BundleContext</code>. This event is only delivered to
+     * {@link SynchronousBundleListener}s. It is not delivered to
+     * <code>BundleListener</code>s.
+     * <p>
+     * The value of <code>LAZY_ACTIVATION</code> is 0x00000200.
+     * 
+     * @since 1.4
+     */
+    public final static int LAZY_ACTIVATION     = 0x00000200;
+
+    /**
+     * Creates a bundle event of the specified type.
+     * 
+     * @param type The event type.
+     * @param bundle The bundle which had a lifecycle change.
+     */
+
+    public this(int type, Bundle bundle) {
+        super(cast(Object)bundle);
+        this.bundle = bundle;
+        this.type = type;
+    }
+
+    /**
+     * Returns the bundle which had a lifecycle change. This bundle is the
+     * source of the event.
+     * 
+     * @return The bundle that had a change occur in its lifecycle.
+     */
+    public Bundle getBundle() {
+        return bundle;
+    }
+
+    /**
+     * Returns the type of lifecyle event. The type values are:
+     * <ul>
+     * <li>{@link #INSTALLED}
+     * <li>{@link #RESOLVED}
+     * <li>{@link #LAZY_ACTIVATION}
+     * <li>{@link #STARTING}
+     * <li>{@link #STARTED}
+     * <li>{@link #STOPPING}
+     * <li>{@link #STOPPED}
+     * <li>{@link #UPDATED}
+     * <li>{@link #UNRESOLVED}
+     * <li>{@link #UNINSTALLED}
+     * </ul>
+     * 
+     * @return The type of lifecycle event.
+     */
+
+    public int getType() {
+        return type;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.osgi/osgi/src/org/osgi/framework/BundleListener.d	Sat Apr 18 13:58:35 2009 +0200
@@ -0,0 +1,51 @@
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/BundleListener.java,v 1.13 2007/02/21 16:49:05 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module org.osgi.framework.BundleListener;
+import org.osgi.framework.BundleEvent;
+
+import java.lang.all;
+import java.util.EventListener;
+
+/**
+ * A <code>BundleEvent</code> listener. <code>BundleListener</code> is a
+ * listener interface that may be implemented by a bundle developer. When a
+ * <code>BundleEvent</code> is fired, it is asynchronously delivered to a
+ * <code>BundleListener</code>. The Framework delivers
+ * <code>BundleEvent</code> objects to a <code>BundleListener</code> in
+ * order and must not concurrently call a <code>BundleListener</code>.
+ * <p>
+ * A <code>BundleListener</code> object is registered with the Framework using
+ * the {@link BundleContext#addBundleListener} method.
+ * <code>BundleListener</code>s are called with a <code>BundleEvent</code>
+ * object when a bundle has been installed, resolved, started, stopped, updated,
+ * unresolved, or uninstalled.
+ * 
+ * @see BundleEvent
+ * @NotThreadSafe
+ * @version $Revision: 1.13 $
+ */
+
+public interface BundleListener : EventListener {
+    /**
+     * Receives notification that a bundle has had a lifecycle change.
+     * 
+     * @param event The <code>BundleEvent</code>.
+     */
+    public void bundleChanged(BundleEvent event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.osgi/osgi/src/org/osgi/framework/Filter.d	Sat Apr 18 13:58:35 2009 +0200
@@ -0,0 +1,127 @@
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/Filter.java,v 1.16 2007/02/21 16:49:05 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+
+import java.lang.all;
+import java.util.Dictionary;
+
+/**
+ * An RFC 1960-based Filter.
+ * <p>
+ * <code>Filter</code> objects can be created by calling
+ * {@link BundleContext#createFilter} with the chosen filter string.
+ * <p>
+ * A <code>Filter</code> object can be used numerous times to determine if the
+ * match argument matches the filter string that was used to create the
+ * <code>Filter</code> object.
+ * <p>
+ * Some examples of LDAP filters are:
+ * 
+ * <pre>
+ *  &quot;(cn=Babs Jensen)&quot;
+ *  &quot;(!(cn=Tim Howes))&quot;
+ *  &quot;(&amp;(&quot; + Constants.OBJECTCLASS + &quot;=Person)(|(sn=Jensen)(cn=Babs J*)))&quot;
+ *  &quot;(o=univ*of*mich*)&quot;
+ * </pre>
+ * 
+ * @since 1.1
+ * @see "Core Specification, section 5.5, for a description of the filter string
+ *      syntax."
+ * @ThreadSafe
+ * @version $Revision: 1.16 $
+ */
+public interface Filter {
+    /**
+     * Filter using a service's properties.
+     * <p>
+     * The filter is executed using the keys and values of the referenced
+     * service's properties. The keys are case insensitively matched with the
+     * filter.
+     * 
+     * @param reference The reference to the service whose properties are used
+     *        in the match.
+     * 
+     * @return <code>true</code> if the service's properties match this
+     *         filter; <code>false</code> otherwise.
+     */
+    public bool match(ServiceReference reference);
+
+    /**
+     * Filter using a <code>Dictionary</code> object. The Filter is executed
+     * using the <code>Dictionary</code> object's keys and values. The keys
+     * are case insensitively matched with the filter.
+     * 
+     * @param dictionary The <code>Dictionary</code> object whose keys are
+     *        used in the match.
+     * 
+     * @return <code>true</code> if the <code>Dictionary</code> object's
+     *         keys and values match this filter; <code>false</code>
+     *         otherwise.
+     * 
+     * @throws IllegalArgumentException If <code>dictionary</code> contains
+     *         case variants of the same key name.
+     */
+    public bool match(Dictionary dictionary);
+
+    /**
+     * Returns this <code>Filter</code> object's filter string.
+     * <p>
+     * The filter string is normalized by removing whitespace which does not
+     * affect the meaning of the filter.
+     * 
+     * @return Filter string.
+     */
+    public String toString();
+
+    /**
+     * Compares this <code>Filter</code> object to another object.
+     * 
+     * @param obj The object to compare against this <code>Filter</code>
+     *        object.
+     * 
+     * @return If the other object is a <code>Filter</code> object, then
+     *         returns <code>this.toString().equals(obj.toString()</code>;<code>false</code>
+     *         otherwise.
+     */
+    public bool equals(Object obj);
+
+    /**
+     * Returns the hashCode for this <code>Filter</code> object.
+     * 
+     * @return The hashCode of the filter string; that is,
+     *         <code>this.toString().hashCode()</code>.
+     */
+    public int hashCode();
+
+    /**
+     * Filter with case sensitivity using a <code>Dictionary</code> object.
+     * The Filter is executed using the <code>Dictionary</code> object's keys
+     * and values. The keys are case sensitively matched with the filter.
+     * 
+     * @param dictionary The <code>Dictionary</code> object whose keys are
+     *        used in the match.
+     * 
+     * @return <code>true</code> if the <code>Dictionary</code> object's
+     *         keys and values match this filter; <code>false</code>
+     *         otherwise.
+     * 
+     * @since 1.3
+     */
+    public bool matchCase(Dictionary dictionary);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkListener.d	Sat Apr 18 13:58:35 2009 +0200
@@ -0,0 +1,53 @@
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/FrameworkListener.java,v 1.12 2007/02/21 16:49:05 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module org.osgi.framework.FrameworkListener;
+import org.osgi.framework.FrameworkEvent;
+
+import java.lang.all;
+import java.util.EventListener;
+
+/**
+ * A <code>FrameworkEvent</code> listener. <code>FrameworkListener</code> is
+ * a listener interface that may be implemented by a bundle developer. When a
+ * <code>FrameworkEvent</code> is fired, it is asynchronously delivered to a
+ * <code>FrameworkListener</code>. The Framework delivers
+ * <code>FrameworkEvent</code> objects to a <code>FrameworkListener</code>
+ * in order and must not concurrently call a <code>FrameworkListener</code>.
+ * 
+ * <p>
+ * A <code>FrameworkListener</code> object is registered with the Framework
+ * using the {@link BundleContext#addFrameworkListener} method.
+ * <code>FrameworkListener</code> objects are called with a
+ * <code>FrameworkEvent</code> objects when the Framework starts and when
+ * asynchronous errors occur.
+ * 
+ * @see FrameworkEvent
+ * @NotThreadSafe
+ * @version $Revision: 1.12 $
+ */
+
+public interface FrameworkListener : EventListener {
+
+    /**
+     * Receives notification of a general <code>FrameworkEvent</code> object.
+     * 
+     * @param event The <code>FrameworkEvent</code> object.
+     */
+    public void frameworkEvent(FrameworkEvent event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.osgi/osgi/src/org/osgi/framework/ServiceEvent.d	Sat Apr 18 13:58:35 2009 +0200
@@ -0,0 +1,140 @@
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceEvent.java,v 1.15 2007/02/20 00:14:12 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceReference;
+
+import java.lang.util;
+import java.util.EventObject;
+
+/**
+ * An event from the Framework describing a service lifecycle change.
+ * <p>
+ * <code>ServiceEvent</code> objects are delivered to
+ * <code>ServiceListener</code>s and <code>AllServiceListener</code>s when
+ * a change occurs in this service's lifecycle. A type code is used to identify
+ * the event type for future extendability.
+ * 
+ * <p>
+ * OSGi Alliance reserves the right to extend the set of types.
+ * 
+ * @Immutable
+ * @see ServiceListener
+ * @see AllServiceListener
+ * @version $Revision: 1.15 $
+ */
+
+public class ServiceEvent : EventObject {
+    static final long               serialVersionUID    = 8792901483909409299L;
+    /**
+     * Reference to the service that had a change occur in its lifecycle.
+     */
+    private final ServiceReference  reference;
+
+    /**
+     * Type of service lifecycle change.
+     */
+    private final int               type;
+
+    /**
+     * This service has been registered.
+     * <p>
+     * This event is synchronously delivered <strong>after</strong> the service
+     * has been registered with the Framework.
+     * 
+     * <p>
+     * The value of <code>REGISTERED</code> is 0x00000001.
+     * 
+     * @see BundleContext#registerService(String[],Object,java.util.Dictionary)
+     */
+    public final static int         REGISTERED          = 0x00000001;
+
+    /**
+     * The properties of a registered service have been modified.
+     * <p>
+     * This event is synchronously delivered <strong>after</strong> the service
+     * properties have been modified.
+     * 
+     * <p>
+     * The value of <code>MODIFIED</code> is 0x00000002.
+     * 
+     * @see ServiceRegistration#setProperties
+     */
+    public final static int         MODIFIED            = 0x00000002;
+
+    /**
+     * This service is in the process of being unregistered.
+     * <p>
+     * This event is synchronously delivered <strong>before</strong> the
+     * service has completed unregistering.
+     * 
+     * <p>
+     * If a bundle is using a service that is <code>UNREGISTERING</code>, the
+     * bundle should release its use of the service when it receives this event.
+     * If the bundle does not release its use of the service when it receives
+     * this event, the Framework will automatically release the bundle's use of
+     * the service while completing the service unregistration operation.
+     * 
+     * <p>
+     * The value of UNREGISTERING is 0x00000004.
+     * 
+     * @see ServiceRegistration#unregister
+     * @see BundleContext#ungetService
+     */
+    public final static int         UNREGISTERING       = 0x00000004;
+
+    /**
+     * Creates a new service event object.
+     * 
+     * @param type The event type.
+     * @param reference A <code>ServiceReference</code> object to the service
+     *        that had a lifecycle change.
+     */
+    public this(int type, ServiceReference reference) {
+        super(cast(Object)reference);
+        this.reference = reference;
+        this.type = type;
+    }
+
+    /**
+     * Returns a reference to the service that had a change occur in its
+     * lifecycle.
+     * <p>
+     * This reference is the source of the event.
+     * 
+     * @return Reference to the service that had a lifecycle change.
+     */
+    public ServiceReference getServiceReference() {
+        return reference;
+    }
+
+    /**
+     * Returns the type of event. The event type values are:
+     * <ul>
+     * <li>{@link #REGISTERED}
+     * <li>{@link #MODIFIED}
+     * <li>{@link #UNREGISTERING}
+     * </ul>
+     * 
+     * @return Type of service lifecycle change.
+     */
+
+    public int getType() {
+        return type;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.osgi/osgi/src/org/osgi/framework/ServiceListener.d	Sat Apr 18 13:58:35 2009 +0200
@@ -0,0 +1,68 @@
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceListener.java,v 1.15 2007/02/20 00:16:30 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceEvent;
+
+import java.lang.all;
+import java.util.EventListener;
+
+/**
+ * A <code>ServiceEvent</code> listener. <code>ServiceListener</code> is a
+ * listener interface that may be implemented by a bundle developer. When a
+ * <code>ServiceEvent</code> is fired, it is synchronously delivered to a
+ * <code>ServiceListener</code>. The Framework may deliver
+ * <code>ServiceEvent</code> objects to a <code>ServiceListener</code> out
+ * of order and may concurrently call and/or reenter a
+ * <code>ServiceListener</code>.
+ * 
+ * <p>
+ * A <code>ServiceListener</code> object is registered with the Framework
+ * using the <code>BundleContext.addServiceListener</code> method.
+ * <code>ServiceListener</code> objects are called with a
+ * <code>ServiceEvent</code> object when a service is registered, modified, or
+ * is in the process of unregistering.
+ * 
+ * <p>
+ * <code>ServiceEvent</code> object delivery to <code>ServiceListener</code>
+ * objects is filtered by the filter specified when the listener was registered.
+ * If the Java Runtime Environment supports permissions, then additional
+ * filtering is done. <code>ServiceEvent</code> objects are only delivered to
+ * the listener if the bundle which defines the listener object's class has the
+ * appropriate <code>ServicePermission</code> to get the service using at
+ * least one of the named classes under which the service was registered.
+ * 
+ * <p>
+ * <code>ServiceEvent</code> object delivery to <code>ServiceListener</code>
+ * objects is further filtered according to package sources as defined in
+ * {@link ServiceReference#isAssignableTo(Bundle, String)}.
+ * 
+ * @see ServiceEvent
+ * @see ServicePermission
+ * @ThreadSafe
+ * @version $Revision: 1.15 $
+ */
+
+public interface ServiceListener : EventListener {
+    /**
+     * Receives notification that a service has had a lifecycle change.
+     * 
+     * @param event The <code>ServiceEvent</code> object.
+     */
+    public void serviceChanged(ServiceEvent event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.osgi/osgi/src/org/osgi/framework/ServiceReference.d	Sat Apr 18 13:58:35 2009 +0200
@@ -0,0 +1,183 @@
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceReference.java,v 1.20 2007/02/21 16:49:05 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module org.osgi.framework.ServiceReference;
+import org.osgi.framework.Bundle;
+
+import java.lang.all;
+
+/**
+ * A reference to a service.
+ * 
+ * <p>
+ * The Framework returns <code>ServiceReference</code> objects from the
+ * <code>BundleContext.getServiceReference</code> and
+ * <code>BundleContext.getServiceReferences</code> methods.
+ * <p>
+ * A <code>ServiceReference</code> object may be shared between bundles and
+ * can be used to examine the properties of the service and to get the service
+ * object.
+ * <p>
+ * Every service registered in the Framework has a unique
+ * <code>ServiceRegistration</code> object and may have multiple, distinct
+ * <code>ServiceReference</code> objects referring to it.
+ * <code>ServiceReference</code> objects associated with a
+ * <code>ServiceRegistration</code> object have the same <code>hashCode</code>
+ * and are considered equal (more specifically, their <code>equals()</code>
+ * method will return <code>true</code> when compared).
+ * <p>
+ * If the same service object is registered multiple times,
+ * <code>ServiceReference</code> objects associated with different
+ * <code>ServiceRegistration</code> objects are not equal.
+ * 
+ * @see BundleContext#getServiceReference
+ * @see BundleContext#getServiceReferences
+ * @see BundleContext#getService
+ * @ThreadSafe
+ * @version $Revision: 1.20 $
+ */
+
+public interface ServiceReference : Comparable {
+    /**
+     * Returns the property value to which the specified property key is mapped
+     * in the properties <code>Dictionary</code> object of the service
+     * referenced by this <code>ServiceReference</code> object.
+     * 
+     * <p>
+     * Property keys are case-insensitive.
+     * 
+     * <p>
+     * This method must continue to return property values after the service has
+     * been unregistered. This is so references to unregistered services (for
+     * example, <code>ServiceReference</code> objects stored in the log) can
+     * still be interrogated.
+     * 
+     * @param key The property key.
+     * @return The property value to which the key is mapped; <code>null</code>
+     *         if there is no property named after the key.
+     */
+    public Object getProperty(String key);
+
+    /**
+     * Returns an array of the keys in the properties <code>Dictionary</code>
+     * object of the service referenced by this <code>ServiceReference</code>
+     * object.
+     * 
+     * <p>
+     * This method will continue to return the keys after the service has been
+     * unregistered. This is so references to unregistered services (for
+     * example, <code>ServiceReference</code> objects stored in the log) can
+     * still be interrogated.
+     * 
+     * <p>
+     * This method is <i>case-preserving </i>; this means that every key in the
+     * returned array must have the same case as the corresponding key in the
+     * properties <code>Dictionary</code> that was passed to the
+     * {@link BundleContext#registerService(String[],Object,java.util.Dictionary)}
+     * or {@link ServiceRegistration#setProperties} methods.
+     * 
+     * @return An array of property keys.
+     */
+    public String[] getPropertyKeys();
+
+    /**
+     * Returns the bundle that registered the service referenced by this
+     * <code>ServiceReference</code> object.
+     * 
+     * <p>
+     * This method must return <code>null</code> when the service has been
+     * unregistered. This can be used to determine if the service has been
+     * unregistered.
+     * 
+     * @return The bundle that registered the service referenced by this
+     *         <code>ServiceReference</code> object; <code>null</code> if
+     *         that service has already been unregistered.
+     * @see BundleContext#registerService(String[],Object,java.util.Dictionary)
+     */
+    public Bundle getBundle();
+
+    /**
+     * Returns the bundles that are using the service referenced by this
+     * <code>ServiceReference</code> object. Specifically, this method returns
+     * the bundles whose usage count for that service is greater than zero.
+     * 
+     * @return An array of bundles whose usage count for the service referenced
+     *         by this <code>ServiceReference</code> object is greater than
+     *         zero; <code>null</code> if no bundles are currently using that
+     *         service.
+     * 
+     * @since 1.1
+     */
+    public Bundle[] getUsingBundles();
+
+    /**
+     * Tests if the bundle that registered the service referenced by this
+     * <code>ServiceReference</code> and the specified bundle use the same
+     * source for the package of the specified class name.
+     * <p>
+     * This method performs the following checks:
+     * <ol>
+     * <li>Get the package name from the specified class name.</li>
+     * <li>For the bundle that registered the service referenced by this
+     * <code>ServiceReference</code> (registrant bundle); find the source for
+     * the package. If no source is found then return <code>true</code> if the
+     * registrant bundle is equal to the specified bundle; otherwise return
+     * <code>false</code>.</li>
+     * <li>If the package source of the registrant bundle is equal to the
+     * package source of the specified bundle then return <code>true</code>;
+     * otherwise return <code>false</code>.</li>
+     * </ol>
+     * 
+     * @param bundle The <code>Bundle</code> object to check.
+     * @param className The class name to check.
+     * @return <code>true</code> if the bundle which registered the service
+     *         referenced by this <code>ServiceReference</code> and the
+     *         specified bundle use the same source for the package of the
+     *         specified class name. Otherwise <code>false</code> is returned.
+     * 
+     * @since 1.3
+     */
+    public bool isAssignableTo(Bundle bundle, String className);
+
+    /**
+     * Compares this <code>ServiceReference</code> with the specified
+     * <code>ServiceReference</code> for order.
+     * 
+     * <p>
+     * If this <code>ServiceReference</code> and the specified
+     * <code>ServiceReference</code> have the same
+     * {@link Constants#SERVICE_ID service id} they are equal. This
+     * <code>ServiceReference</code> is less than the specified
+     * <code>ServiceReference</code> if it has a lower
+     * {@link Constants#SERVICE_RANKING service ranking} and greater if it has a
+     * higher service ranking. Otherwise, if this <code>ServiceReference</code>
+     * and the specified <code>ServiceReference</code> have the same
+     * {@link Constants#SERVICE_RANKING service ranking}, this
+     * <code>ServiceReference</code> is less than the specified
+     * <code>ServiceReference</code> if it has a higher
+     * {@link Constants#SERVICE_ID service id} and greater if it has a lower
+     * service id.
+     * 
+     * @param reference The <code>ServiceReference</code> to be compared.
+     * @return Returns a negative integer, zero, or a positive integer if this
+     *         <code>ServiceReference</code> is less than, equal to, or
+     *         greater than the specified <code>ServiceReference</code>.
+     * @since 1.4
+     */
+    public int compareTo(Object reference);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.osgi/osgi/src/org/osgi/framework/ServiceRegistration.d	Sat Apr 18 13:58:35 2009 +0200
@@ -0,0 +1,115 @@
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceRegistration.java,v 1.14 2007/02/21 16:49:05 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.ServiceReference;
+
+import java.lang.all;
+import java.util.Dictionary;
+
+/**
+ * A registered service.
+ * 
+ * <p>
+ * The Framework returns a <code>ServiceRegistration</code> object when a
+ * <code>BundleContext.registerService</code> method invocation is successful.
+ * The <code>ServiceRegistration</code> object is for the private use of the
+ * registering bundle and should not be shared with other bundles.
+ * <p>
+ * The <code>ServiceRegistration</code> object may be used to update the
+ * properties of the service or to unregister the service.
+ * 
+ * @see BundleContext#registerService(String[],Object,Dictionary)
+ * @ThreadSafe
+ * @version $Revision: 1.14 $
+ */
+
+public interface ServiceRegistration {
+    /**
+     * Returns a <code>ServiceReference</code> object for a service being
+     * registered.
+     * <p>
+     * The <code>ServiceReference</code> object may be shared with other
+     * bundles.
+     * 
+     * @throws java.lang.IllegalStateException If this
+     *         <code>ServiceRegistration</code> object has already been
+     *         unregistered.
+     * @return <code>ServiceReference</code> object.
+     */
+    public ServiceReference getReference();
+
+    /**
+     * Updates the properties associated with a service.
+     * 
+     * <p>
+     * The {@link Constants#OBJECTCLASS} and {@link Constants#SERVICE_ID} keys
+     * cannot be modified by this method. These values are set by the Framework
+     * when the service is registered in the OSGi environment.
+     * 
+     * <p>
+     * The following steps are required to modify service properties:
+     * <ol>
+     * <li>The service's properties are replaced with the provided properties.
+     * <li>A service event of type {@link ServiceEvent#MODIFIED} is
+     * fired.
+     * </ol>
+     * 
+     * @param properties The properties for this service. See {@link Constants}
+     *        for a list of standard service property keys. Changes should not
+     *        be made to this object after calling this method. To update the
+     *        service's properties this method should be called again.
+     * 
+     * @throws IllegalStateException If this <code>ServiceRegistration</code>
+     *         object has already been unregistered.
+     * @throws IllegalArgumentException If <code>properties</code> contains
+     *         case variants of the same key name.
+     */
+    public void setProperties(Dictionary properties);
+
+    /**
+     * Unregisters a service. Remove a <code>ServiceRegistration</code> object
+     * from the Framework service registry. All <code>ServiceReference</code>
+     * objects associated with this <code>ServiceRegistration</code> object
+     * can no longer be used to interact with the service.
+     * 
+     * <p>
+     * The following steps are required to unregister a service:
+     * <ol>
+     * <li>The service is removed from the Framework service registry so that
+     * it can no longer be used. <code>ServiceReference</code> objects for the
+     * service may no longer be used to get a service object for the service.
+     * <li>A service event of type {@link ServiceEvent#UNREGISTERING} is
+     * fired so that bundles using this service can release their
+     * use of it.
+     * <li>For each bundle whose use count for this service is greater than
+     * zero: <br>
+     * The bundle's use count for this service is set to zero. <br>
+     * If the service was registered with a {@link ServiceFactory} object, the
+     * <code>ServiceFactory.ungetService</code> method is called to release
+     * the service object for the bundle.
+     * </ol>
+     * 
+     * @throws java.lang.IllegalStateException If this
+     *         <code>ServiceRegistration</code> object has already been
+     *         unregistered.
+     * @see BundleContext#ungetService
+     * @see ServiceFactory#ungetService
+     */
+    public void unregister();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.osgi/osgi/src/org/osgi/util/tracker/ServiceTracker.d	Sat Apr 18 13:58:35 2009 +0200
@@ -0,0 +1,1230 @@
+/*
+ * $Header: /cvshome/build/org.osgi.util.tracker/src/org/osgi/util/tracker/ServiceTracker.java,v 1.22 2006/07/20 16:14:43 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+import java.lang.all;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.LinkedList;
+
+//FIXME tmp remove: import org.eclipse.osgi.framework.internal.core.FilterImpl;
+//FIXME tmp remove: import org.osgi.framework.AllServiceListener;
+import org.osgi.framework.BundleContext;
+//FIXME tmp remove: import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+//FIXME tmp remove: import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * The <code>ServiceTracker</code> class simplifies using services from the
+ * Framework's service registry.
+ * <p>
+ * A <code>ServiceTracker</code> object is constructed with search criteria
+ * and a <code>ServiceTrackerCustomizer</code> object. A
+ * <code>ServiceTracker</code> object can use the
+ * <code>ServiceTrackerCustomizer</code> object to customize the service
+ * objects to be tracked. The <code>ServiceTracker</code> object can then be
+ * opened to begin tracking all services in the Framework's service registry
+ * that match the specified search criteria. The <code>ServiceTracker</code>
+ * object correctly handles all of the details of listening to
+ * <code>ServiceEvent</code> objects and getting and ungetting services.
+ * <p>
+ * The <code>getServiceReferences</code> method can be called to get
+ * references to the services being tracked. The <code>getService</code> and
+ * <code>getServices</code> methods can be called to get the service objects
+ * for the tracked service.
+ * <p>
+ * The <code>ServiceTracker</code> class is thread-safe. It does not call a
+ * <code>ServiceTrackerCustomizer</code> object while holding any locks.
+ * <code>ServiceTrackerCustomizer</code> implementations must also be
+ * thread-safe.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 1.29 $
+ */
+
+/*
+ * This implementation has been customized to only work with the Equinox OSGi framework.
+ * In all cases a filter string containing objectClass is passed to BundleContext.addServiceListener
+ * to take advantage of the ServiceEvent delivery optimizations.
+ */
+
+public class ServiceTracker : ServiceTrackerCustomizer {
+    public this(BundleContext context, ServiceReference reference, ServiceTrackerCustomizer customizer) {
+        implMissing(__FILE__,__LINE__);
+    }
+    public this(BundleContext context, String clazz, ServiceTrackerCustomizer customizer) {
+        implMissing(__FILE__,__LINE__);
+    }
+    public this(BundleContext context, Filter filter, ServiceTrackerCustomizer customizer) {
+        implMissing(__FILE__,__LINE__);
+    }
+    public Object addingService(ServiceReference reference){
+        implMissing(__FILE__,__LINE__);
+        return null;
+    }
+    public void modifiedService(ServiceReference reference, Object service){
+        implMissing(__FILE__,__LINE__);
+    }
+    public void removedService(ServiceReference reference, Object service){
+        implMissing(__FILE__,__LINE__);
+    }
+    public void open() {
+        implMissing(__FILE__,__LINE__);
+    }
+    public void open( bool trackAll) {
+        implMissing(__FILE__,__LINE__);
+    }
+    public synchronized void close() {
+        implMissing(__FILE__,__LINE__);
+    }
+    public Object getService(ServiceReference reference) {
+        implMissing(__FILE__,__LINE__);
+        return null;
+    }
+    public Object getService() {
+        implMissing(__FILE__,__LINE__);
+        return null;
+    }
+}
+//FIXME Dummy class
+/+++
+public class ServiceTracker : ServiceTrackerCustomizer {
+    /* set this to true to compile in debug messages */
+    static final bool                DEBUG           = false;
+    /**
+     * Bundle context against which this <code>ServiceTracker</code> object is
+     * tracking.
+     */
+    protected final BundleContext       context;
+    /**
+     * Filter specifying search criteria for the services to track.
+     * 
+     * @since 1.1
+     */
+    protected final Filter              filter;
+    /**
+     * <code>ServiceTrackerCustomizer</code> object for this tracker.
+     */
+    final ServiceTrackerCustomizer      customizer;
+    /**
+     * Filter string for use when adding the ServiceListener.
+     */
+    private final String                listenerFilter;
+    /**
+     * Class name to be tracked. If this field is set, then we are tracking by
+     * class name.
+     */
+    private final String                trackClass;
+    /**
+     * Reference to be tracked. If this field is set, then we are tracking a
+     * single ServiceReference.
+     */
+    private final ServiceReference      trackReference;
+    /**
+     * True if no Filter object was supplied in a constructor or we are not
+     * using the supplied filter.
+     */
+    final bool                       noUserFilter;
+    /**
+     * Tracked services: <code>ServiceReference</code> object -> customized
+     * Object and <code>ServiceListener</code> object
+     */
+    private volatile Tracked            tracked;
+    /**
+     * Modification count. This field is initialized to zero by open, set to -1
+     * by close and incremented by modified.
+     * 
+     * This field is volatile since it is accessed by multiple threads.
+     */
+    private volatile int                trackingCount   = -1;
+    /**
+     * Cached ServiceReference for getServiceReference.
+     * 
+     * This field is volatile since it is accessed by multiple threads.
+     */
+    private volatile ServiceReference   cachedReference;
+    /**
+     * Cached service object for getService.
+     * 
+     * This field is volatile since it is accessed by multiple threads.
+     */
+    private volatile Object             cachedService;
+
+    /**
+     * Create a <code>ServiceTracker</code> object on the specified
+     * <code>ServiceReference</code> object.
+     * 
+     * <p>
+     * The service referenced by the specified <code>ServiceReference</code>
+     * object will be tracked by this <code>ServiceTracker</code> object.
+     * 
+     * @param context <code>BundleContext</code> object against which the
+     *        tracking is done.
+     * @param reference <code>ServiceReference</code> object for the service
+     *        to be tracked.
+     * @param customizer The customizer object to call when services are added,
+     *        modified, or removed in this <code>ServiceTracker</code> object.
+     *        If customizer is <code>null</code>, then this
+     *        <code>ServiceTracker</code> object will be used as the
+     *        <code>ServiceTrackerCustomizer</code> object and the
+     *        <code>ServiceTracker</code> object will call the
+     *        <code>ServiceTrackerCustomizer</code> methods on itself.
+     */
+    public this(BundleContext context, ServiceReference reference,
+            ServiceTrackerCustomizer customizer) {
+        this.context = context;
+        this.trackReference = reference;
+        this.trackClass = null;
+        this.customizer = (customizer == null) ? this : customizer;
+        this.listenerFilter = "(&(" + Constants.OBJECTCLASS + "=" + ((String[]) reference.getProperty(Constants.OBJECTCLASS))[0] //$NON-NLS-1$ //$NON-NLS-2$
+                + ")(" + Constants.SERVICE_ID + "=" + reference.getProperty(Constants.SERVICE_ID).toString() + "))" ; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        this.noUserFilter = true;
+        try {
+            this.filter = context.createFilter(listenerFilter);
+        }
+        catch (InvalidSyntaxException e) { // we could only get this exception
+            // if the ServiceReference was
+            // invalid
+            throw new IllegalArgumentException(
+                    "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Create a <code>ServiceTracker</code> object on the specified class
+     * name.
+     * 
+     * <p>
+     * Services registered under the specified class name will be tracked by
+     * this <code>ServiceTracker</code> object.
+     * 
+     * @param context <code>BundleContext</code> object against which the
+     *        tracking is done.
+     * @param clazz Class name of the services to be tracked.
+     * @param customizer The customizer object to call when services are added,
+     *        modified, or removed in this <code>ServiceTracker</code> object.
+     *        If customizer is <code>null</code>, then this
+     *        <code>ServiceTracker</code> object will be used as the
+     *        <code>ServiceTrackerCustomizer</code> object and the
+     *        <code>ServiceTracker</code> object will call the
+     *        <code>ServiceTrackerCustomizer</code> methods on itself.
+     */
+    public this(BundleContext context, String clazz,
+            ServiceTrackerCustomizer customizer) {
+        this.context = context;
+        this.trackReference = null;
+        this.trackClass = clazz;
+        this.customizer = (customizer == null) ? this : customizer;
+        this.listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz.toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        this.noUserFilter = true;
+        try {
+            this.filter = context.createFilter(listenerFilter);
+        }
+        catch (InvalidSyntaxException e) { // we could only get this exception
+            // if the clazz argument was
+            // malformed
+            throw new IllegalArgumentException(
+                    "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Create a <code>ServiceTracker</code> object on the specified
+     * <code>Filter</code> object.
+     * 
+     * <p>
+     * Services which match the specified <code>Filter</code> object will be
+     * tracked by this <code>ServiceTracker</code> object.
+     * 
+     * @param context <code>BundleContext</code> object against which the
+     *        tracking is done.
+     * @param filter <code>Filter</code> object to select the services to be
+     *        tracked.
+     * @param customizer The customizer object to call when services are added,
+     *        modified, or removed in this <code>ServiceTracker</code> object.
+     *        If customizer is null, then this <code>ServiceTracker</code>
+     *        object will be used as the <code>ServiceTrackerCustomizer</code>
+     *        object and the <code>ServiceTracker</code> object will call the
+     *        <code>ServiceTrackerCustomizer</code> methods on itself.
+     * @since 1.1
+     */
+    public this(BundleContext context, Filter filter,
+            ServiceTrackerCustomizer customizer) {
+        this.context = context;
+        this.trackReference = null;
+
+        // obtain a required objectClass from the user supplied filter
+        if (filter instanceof FilterImpl) {
+            this.trackClass = ((FilterImpl)filter).getRequiredObjectClass();
+        } else {
+            this.trackClass = null;
+        }
+        
+        if (this.trackClass != null) {
+            this.listenerFilter = FilterImpl.getObjectClassFilterString(this.trackClass);
+            //convert to track by class instead of filter if the user filter is in the form (objectClass=some.Clazz) 
+            this.noUserFilter = this.listenerFilter.equals(filter.toString()); 
+        } else {
+            this.listenerFilter = null;
+            this.noUserFilter = false;
+        }
+
+        this.filter = filter;
+        this.customizer = (customizer == null) ? this : customizer;
+        if ((context == null) || (filter == null)) { // we throw a NPE here
+            // to
+            // be consistent with the
+            // other constructors
+            throw new NullPointerException();
+        }
+    }
+
+    /**
+     * Open this <code>ServiceTracker</code> object and begin tracking
+     * services.
+     * 
+     * <p>
+     * This method calls <code>open(false)</code>.
+     * 
+     * @throws java.lang.IllegalStateException if the <code>BundleContext</code>
+     *         object with which this <code>ServiceTracker</code> object was
+     *         created is no longer valid.
+     * @see #open(bool)
+     */
+    public void open() {
+        open(false);
+    }
+
+    /**
+     * Open this <code>ServiceTracker</code> object and begin tracking
+     * services.
+     * 
+     * <p>
+     * Services which match the search criteria specified when this
+     * <code>ServiceTracker</code> object was created are now tracked by this
+     * <code>ServiceTracker</code> object.
+     * 
+     * @param trackAllServices If <code>true</code>, then this
+     *        <code>ServiceTracker</code> will track all matching services
+     *        regardless of class loader accessibility. If <code>false</code>,
+     *        then this <code>ServiceTracker</code> will only track matching
+     *        services which are class loader accessibile to the bundle whose
+     *        <code>BundleContext</code> is used by this
+     *        <code>ServiceTracker</code>.
+     * @throws java.lang.IllegalStateException if the <code>BundleContext</code>
+     *         object with which this <code>ServiceTracker</code> object was
+     *         created is no longer valid.
+     * @since 1.3
+     */
+    public synchronized void open(bool trackAllServices) {
+        if (tracked != null) {
+            return;
+        }
+        if (DEBUG) {
+            System.out.println("ServiceTracker.open: " + filter); //$NON-NLS-1$
+        }
+        tracked = trackAllServices ? new AllTracked() : new Tracked();
+        trackingCount = 0;
+        synchronized (tracked) {
+            try {
+                context.addServiceListener(tracked, listenerFilter);
+                ServiceReference[] references;
+                
+                if (trackReference != null) { // tracking a single reference 
+                    references = new ServiceReference[] {trackReference};
+                }
+                else { // tracking a set of references
+                    references = getInitialReferences(trackAllServices, trackClass,
+                            noUserFilter ? null: filter.toString());
+                }
+
+                tracked.setInitialServices(references); // set tracked with
+                // the initial
+                // references
+            }
+            catch (InvalidSyntaxException e) {
+                throw new RuntimeException(
+                        "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
+            }
+        }
+        /* Call tracked outside of synchronized region */
+        tracked.trackInitialServices(); // process the initial references
+    }
+
+    /**
+     * Returns the list of initial <code>ServiceReference</code> objects that
+     * will be tracked by this <code>ServiceTracker</code> object.
+     * 
+     * @param trackAllServices If true, use getAllServiceReferences.
+     * @param trackClass the class name with which the service was registered,
+     *        or null for all services.
+     * @param filterString the filter criteria or null for all services.
+     * @return the list of initial <code>ServiceReference</code> objects.
+     * @throws InvalidSyntaxException if the filter uses an invalid syntax.
+     */
+    private ServiceReference[] getInitialReferences(bool trackAllServices,
+            String trackClass, String filterString)
+            throws InvalidSyntaxException {
+        if (trackAllServices) {
+            return context.getAllServiceReferences(trackClass, filterString);
+        }
+        else {
+            return context.getServiceReferences(trackClass, filterString);
+        }
+    }
+
+    /**
+     * Close this <code>ServiceTracker</code> object.
+     * 
+     * <p>
+     * This method should be called when this <code>ServiceTracker</code>
+     * object should end the tracking of services.
+     */
+    public synchronized void close() {
+        if (tracked == null) {
+            return;
+        }
+        if (DEBUG) {
+            System.out.println("ServiceTracker.close: " + filter); //$NON-NLS-1$
+        }
+        tracked.close();
+        ServiceReference[] references = getServiceReferences();
+        Tracked outgoing = tracked;
+        tracked = null;
+        try {
+            context.removeServiceListener(outgoing);
+        }
+        catch (IllegalStateException e) {
+            /* In case the context was stopped. */
+        }
+        if (references != null) {
+            for (int i = 0; i < references.length; i++) {
+                outgoing.untrack(references[i]);
+            }
+        }
+        trackingCount = -1;
+        if (DEBUG) {
+            if ((cachedReference == null) && (cachedService == null)) {
+                System.out
+                        .println("ServiceTracker.close[cached cleared]: " + filter); //$NON-NLS-1$
+            }
+        }
+    }
+
+    /**
+     * Default implementation of the
+     * <code>ServiceTrackerCustomizer.addingService</code> method.
+     * 
+     * <p>
+     * This method is only called when this <code>ServiceTracker</code> object
+     * has been constructed with a <code>null ServiceTrackerCustomizer</code>
+     * argument.
+     * 
+     * The default implementation returns the result of calling
+     * <code>getService</code>, on the <code>BundleContext</code> object
+     * with which this <code>ServiceTracker</code> object was created, passing
+     * the specified <code>ServiceReference</code> object.
+     * <p>
+     * This method can be overridden in a subclass to customize the service
+     * object to be tracked for the service being added. In that case, take care
+     * not to rely on the default implementation of removedService that will
+     * unget the service.
+     * 
+     * @param reference Reference to service being added to this
+     *        <code>ServiceTracker</code> object.
+     * @return The service object to be tracked for the service added to this
+     *         <code>ServiceTracker</code> object.
+     * @see ServiceTrackerCustomizer
+     */
+    public Object addingService(ServiceReference reference) {
+        return context.getService(reference);
+    }
+
+    /**
+     * Default implementation of the
+     * <code>ServiceTrackerCustomizer.modifiedService</code> method.
+     * 
+     * <p>
+     * This method is only called when this <code>ServiceTracker</code> object
+     * has been constructed with a <code>null ServiceTrackerCustomizer</code>
+     * argument.
+     * 
+     * The default implementation does nothing.
+     * 
+     * @param reference Reference to modified service.
+     * @param service The service object for the modified service.
+     * @see ServiceTrackerCustomizer
+     */
+    public void modifiedService(ServiceReference reference, Object service) {
+    }
+
+    /**
+     * Default implementation of the
+     * <code>ServiceTrackerCustomizer.removedService</code> method.
+     * 
+     * <p>
+     * This method is only called when this <code>ServiceTracker</code> object
+     * has been constructed with a <code>null ServiceTrackerCustomizer</code>
+     * argument.
+     * 
+     * The default implementation calls <code>ungetService</code>, on the
+     * <code>BundleContext</code> object with which this
+     * <code>ServiceTracker</code> object was created, passing the specified
+     * <code>ServiceReference</code> object.
+     * <p>
+     * This method can be overridden in a subclass. If the default
+     * implementation of <code>addingService</code> method was used, this
+     * method must unget the service.
+     * 
+     * @param reference Reference to removed service.
+     * @param service The service object for the removed service.
+     * @see ServiceTrackerCustomizer
+     */
+    public void removedService(ServiceReference reference, Object service) {
+        context.ungetService(reference);
+    }
+
+    /**
+     * Wait for at least one service to be tracked by this
+     * <code>ServiceTracker</code> object.
+     * <p>
+     * It is strongly recommended that <code>waitForService</code> is not used
+     * during the calling of the <code>BundleActivator</code> methods.
+     * <code>BundleActivator</code> methods are expected to complete in a
+     * short period of time.
+     * 
+     * @param timeout time interval in milliseconds to wait. If zero, the method
+     *        will wait indefinately.
+     * @return Returns the result of <code>getService()</code>.
+     * @throws InterruptedException If another thread has interrupted the
+     *         current thread.
+     * @throws IllegalArgumentException If the value of timeout is negative.
+     */
+    public Object waitForService(long timeout) throws InterruptedException {
+        if (timeout < 0) {
+            throw new IllegalArgumentException("timeout value is negative"); //$NON-NLS-1$
+        }
+        Object object = getService();
+        while (object == null) {
+            Tracked tracked = this.tracked; /*
+                                             * use local var since we are not
+                                             * synchronized
+                                             */
+            if (tracked == null) { /* if ServiceTracker is not open */
+                return null;
+            }
+            synchronized (tracked) {
+                if (tracked.size() == 0) {
+                    tracked.wait(timeout);
+                }
+            }
+            object = getService();
+            if (timeout > 0) {
+                return object;
+            }
+        }
+        return object;
+    }
+
+    /**
+     * Return an array of <code>ServiceReference</code> objects for all
+     * services being tracked by this <code>ServiceTracker</code> object.
+     * 
+     * @return Array of <code>ServiceReference</code> objects or
+     *         <code>null</code> if no service are being tracked.
+     */
+    public ServiceReference[] getServiceReferences() {
+        Tracked tracked = this.tracked; /*
+                                         * use local var since we are not
+                                         * synchronized
+                                         */
+        if (tracked == null) { /* if ServiceTracker is not open */
+            return null;
+        }
+        synchronized (tracked) {
+            int length = tracked.size();
+            if (length == 0) {
+                return null;
+            }
+            ServiceReference[] references = new ServiceReference[length];
+            Enumeration keys = tracked.keys();
+            for (int i = 0; i < length; i++) {
+                references[i] = (ServiceReference) keys.nextElement();
+            }
+            return references;
+        }
+    }
+
+    /**
+     * Returns a <code>ServiceReference</code> object for one of the services
+     * being tracked by this <code>ServiceTracker</code> object.
+     * 
+     * <p>
+     * If multiple services are being tracked, the service with the highest
+     * ranking (as specified in its <code>service.ranking</code> property) is
+     * returned.
+     * 
+     * <p>
+     * If there is a tie in ranking, the service with the lowest service ID (as
+     * specified in its <code>service.id</code> property); that is, the
+     * service that was registered first is returned.
+     * <p>
+     * This is the same algorithm used by
+     * <code>BundleContext.getServiceReference</code>.
+     * 
+     * @return <code>ServiceReference</code> object or <code>null</code> if
+     *         no service is being tracked.
+     * @since 1.1
+     */
+    public ServiceReference getServiceReference() {
+        ServiceReference reference = cachedReference;
+        if (reference != null) {
+            if (DEBUG) {
+                System.out
+                        .println("ServiceTracker.getServiceReference[cached]: " + filter); //$NON-NLS-1$
+            }
+            return reference;
+        }
+        if (DEBUG) {
+            System.out.println("ServiceTracker.getServiceReference: " + filter); //$NON-NLS-1$
+        }
+        ServiceReference[] references = getServiceReferences();
+        int length = (references == null) ? 0 : references.length;
+        if (length == 0) /* if no service is being tracked */
+        {
+            return null;
+        }
+        int index = 0;
+        if (length > 1) /* if more than one service, select highest ranking */
+        {
+            int rankings[] = new int[length];
+            int count = 0;
+            int maxRanking = Integer.MIN_VALUE;
+            for (int i = 0; i < length; i++) {
+                Object property = references[i]
+                        .getProperty(Constants.SERVICE_RANKING);
+                int ranking = (property instanceof Integer) ? ((Integer) property)
+                        .intValue()
+                        : 0;
+                rankings[i] = ranking;
+                if (ranking > maxRanking) {
+                    index = i;
+                    maxRanking = ranking;
+                    count = 1;
+                }
+                else {
+                    if (ranking == maxRanking) {
+                        count++;
+                    }
+                }
+            }
+            if (count > 1) /* if still more than one service, select lowest id */
+            {
+                long minId = Long.MAX_VALUE;
+                for (int i = 0; i < length; i++) {
+                    if (rankings[i] == maxRanking) {
+                        long id = ((Long) (references[i]
+                                .getProperty(Constants.SERVICE_ID)))
+                                .longValue();
+                        if (id < minId) {
+                            index = i;
+                            minId = id;
+                        }
+                    }
+                }
+            }
+        }
+        return cachedReference = references[index];
+    }
+
+    /**
+     * Returns the service object for the specified
+     * <code>ServiceReference</code> object if the referenced service is being
+     * tracked by this <code>ServiceTracker</code> object.
+     * 
+     * @param reference Reference to the desired service.
+     * @return Service object or <code>null</code> if the service referenced
+     *         by the specified <code>ServiceReference</code> object is not
+     *         being tracked.
+     */
+    public Object getService(ServiceReference reference) {
+        Tracked tracked = this.tracked; /*
+                                         * use local var since we are not
+                                         * synchronized
+                                         */
+        if (tracked == null) { /* if ServiceTracker is not open */
+            return null;
+        }
+        synchronized (tracked) {
+            return tracked.get(reference);
+        }
+    }
+
+    /**
+     * Return an array of service objects for all services being tracked by this
+     * <code>ServiceTracker</code> object.
+     * 
+     * @return Array of service objects or <code>null</code> if no service are
+     *         being tracked.
+     */
+    public Object[] getServices() {
+        Tracked tracked = this.tracked; /*
+                                         * use local var since we are not
+                                         * synchronized
+                                         */
+        if (tracked == null) { /* if ServiceTracker is not open */
+            return null;
+        }
+        synchronized (tracked) {
+            ServiceReference[] references = getServiceReferences();
+            int length = (references == null) ? 0 : references.length;
+            if (length == 0) {
+                return null;
+            }
+            Object[] objects = new Object[length];
+            for (int i = 0; i < length; i++) {
+                objects[i] = getService(references[i]);
+            }
+            return objects;
+        }
+    }
+
+    /**
+     * Returns a service object for one of the services being tracked by this
+     * <code>ServiceTracker</code> object.
+     * 
+     * <p>
+     * If any services are being tracked, this method returns the result of
+     * calling <code>getService(getServiceReference())</code>.
+     * 
+     * @return Service object or <code>null</code> if no service is being
+     *         tracked.
+     */
+    public Object getService() {
+        Object service = cachedService;
+        if (service != null) {
+            if (DEBUG) {
+                System.out
+                        .println("ServiceTracker.getService[cached]: " + filter); //$NON-NLS-1$
+            }
+            return service;
+        }
+        if (DEBUG) {
+            System.out.println("ServiceTracker.getService: " + filter); //$NON-NLS-1$
+        }
+        ServiceReference reference = getServiceReference();
+        if (reference == null) {
+            return null;
+        }
+        return cachedService = getService(reference);
+    }
+
+    /**
+     * Remove a service from this <code>ServiceTracker</code> object.
+     * 
+     * The specified service will be removed from this
+     * <code>ServiceTracker</code> object. If the specified service was being
+     * tracked then the <code>ServiceTrackerCustomizer.removedService</code>
+     * method will be called for that service.
+     * 
+     * @param reference Reference to the service to be removed.
+     */
+    public void remove(ServiceReference reference) {
+        Tracked tracked = this.tracked; /*
+                                         * use local var since we are not
+                                         * synchronized
+                                         */
+        if (tracked == null) { /* if ServiceTracker is not open */
+            return;
+        }
+        tracked.untrack(reference);
+    }
+
+    /**
+     * Return the number of services being tracked by this
+     * <code>ServiceTracker</code> object.
+     * 
+     * @return Number of services being tracked.
+     */
+    public int size() {
+        Tracked tracked = this.tracked; /*
+                                         * use local var since we are not
+                                         * synchronized
+                                         */
+        if (tracked == null) { /* if ServiceTracker is not open */
+            return 0;
+        }
+        return tracked.size();
+    }
+
+    /**
+     * Returns the tracking count for this <code>ServiceTracker</code> object.
+     * 
+     * The tracking count is initialized to 0 when this
+     * <code>ServiceTracker</code> object is opened. Every time a service is
+     * added, modified or removed from this <code>ServiceTracker</code> object
+     * the tracking count is incremented.
+     * 
+     * <p>
+     * The tracking count can be used to determine if this
+     * <code>ServiceTracker</code> object has added, modified or removed a
+     * service by comparing a tracking count value previously collected with the
+     * current tracking count value. If the value has not changed, then no
+     * service has been added, modified or removed from this
+     * <code>ServiceTracker</code> object since the previous tracking count
+     * was collected.
+     * 
+     * @since 1.2
+     * @return The tracking count for this <code>ServiceTracker</code> object
+     *         or -1 if this <code>ServiceTracker</code> object is not open.
+     */
+    public int getTrackingCount() {
+        return trackingCount;
+    }
+
+    /**
+     * Called by the Tracked object whenever the set of tracked services is
+     * modified. Increments the tracking count and clears the cache.
+     * 
+     * @GuardedBy tracked
+     */
+    /*
+     * This method must not be synchronized since it is called by Tracked while
+     * Tracked is synchronized. We don't want synchronization interactions
+     * between the ServiceListener thread and the user thread.
+     */
+    void modified() {
+        trackingCount++; /* increment modification count */
+        cachedReference = null; /* clear cached value */
+        cachedService = null; /* clear cached value */
+        if (DEBUG) {
+            System.out.println("ServiceTracker.modified: " + filter); //$NON-NLS-1$
+        }
+    }
+
+
+    /**
+     * Inner class to track services. If a <code>ServiceTracker</code> object
+     * is reused (closed then reopened), then a new Tracked object is used. This
+     * class is a hashtable mapping <code>ServiceReference</code> object ->
+     * customized Object. This class is the <code>ServiceListener</code>
+     * object for the tracker. This class is used to synchronize access to the
+     * tracked services. This is not a public class. It is only for use by the
+     * implementation of the <code>ServiceTracker</code> class.
+     * 
+     * @ThreadSafe
+     */
+    class Tracked extends Hashtable implements ServiceListener {
+        static final long           serialVersionUID    = -7420065199791006079L;
+        /**
+         * List of ServiceReferences in the process of being added. This is used
+         * to deal with nesting of ServiceEvents. Since ServiceEvents are
+         * synchronously delivered, ServiceEvents can be nested. For example,
+         * when processing the adding of a service and the customizer causes the
+         * service to be unregistered, notification to the nested call to
+         * untrack that the service was unregistered can be made to the track
+         * method.
+         * 
+         * Since the ArrayList implementation is not synchronized, all access to
+         * this list must be protected by the same synchronized object for
+         * thread-safety.
+         * 
+         * @GuardedBy this
+         */
+        private final ArrayList     adding;
+
+        /**
+         * true if the tracked object is closed.
+         * 
+         * This field is volatile because it is set by one thread and read by
+         * another.
+         */
+        private volatile bool    closed;
+
+        /**
+         * Initial list of ServiceReferences for the tracker. This is used to
+         * correctly process the initial services which could become
+         * unregistered before they are tracked. This is necessary since the
+         * initial set of tracked services are not "announced" by ServiceEvents
+         * and therefore the ServiceEvent for unregistration could be delivered
+         * before we track the service.
+         * 
+         * A service must not be in both the initial and adding lists at the
+         * same time. A service must be moved from the initial list to the
+         * adding list "atomically" before we begin tracking it.
+         * 
+         * Since the LinkedList implementation is not synchronized, all access
+         * to this list must be protected by the same synchronized object for
+         * thread-safety.
+         * 
+         * @GuardedBy this
+         */
+        private final LinkedList    initial;
+
+        /**
+         * Tracked constructor.
+         */
+        protected Tracked() {
+            super();
+            closed = false;
+            adding = new ArrayList(6);
+            initial = new LinkedList();
+        }
+
+        /**
+         * Set initial list of services into tracker before ServiceEvents begin
+         * to be received.
+         * 
+         * This method must be called from ServiceTracker.open while
+         * synchronized on this object in the same synchronized block as the
+         * addServiceListener call.
+         * 
+         * @param references The initial list of services to be tracked.
+         * @GuardedBy this
+         */
+        protected void setInitialServices(ServiceReference[] references) {
+            if (references == null) {
+                return;
+            }
+            int size = references.length;
+            for (int i = 0; i < size; i++) {
+                if (DEBUG) {
+                    System.out
+                            .println("ServiceTracker.Tracked.setInitialServices: " + references[i]); //$NON-NLS-1$
+                }
+                initial.add(references[i]);
+            }
+        }
+
+        /**
+         * Track the initial list of services. This is called after
+         * ServiceEvents can begin to be received.
+         * 
+         * This method must be called from ServiceTracker.open while not
+         * synchronized on this object after the addServiceListener call.
+         * 
+         */
+        protected void trackInitialServices() {
+            while (true) {
+                ServiceReference reference;
+                synchronized (this) {
+                    if (initial.size() == 0) {
+                        /*
+                         * if there are no more inital services
+                         */
+                        return; /* we are done */
+                    }
+                    /*
+                     * move the first service from the initial list to the
+                     * adding list within this synchronized block.
+                     */
+                    reference = (ServiceReference) initial.removeFirst();
+                    if (this.get(reference) != null) {
+                        /* if we are already tracking this service */
+                        if (DEBUG) {
+                            System.out
+                                    .println("ServiceTracker.Tracked.trackInitialServices[already tracked]: " + reference); //$NON-NLS-1$
+                        }
+                        continue; /* skip this service */
+                    }
+                    if (adding.contains(reference)) {
+                        /*
+                         * if this service is already in the process of being
+                         * added.
+                         */
+                        if (DEBUG) {
+                            System.out
+                                    .println("ServiceTracker.Tracked.trackInitialServices[already adding]: " + reference); //$NON-NLS-1$
+                        }
+                        continue; /* skip this service */
+                    }
+                    adding.add(reference);
+                }
+                if (DEBUG) {
+                    System.out
+                            .println("ServiceTracker.Tracked.trackInitialServices: " + reference); //$NON-NLS-1$
+                }
+                trackAdding(reference); /*
+                                         * Begin tracking it. We call
+                                         * trackAdding since we have already put
+                                         * the reference in the adding list.
+                                         */
+            }
+        }
+
+        /**
+         * Called by the owning <code>ServiceTracker</code> object when it is
+         * closed.
+         */
+        protected void close() {
+            closed = true;
+        }
+
+        /**
+         * <code>ServiceListener</code> method for the
+         * <code>ServiceTracker</code> class. This method must NOT be
+         * synchronized to avoid deadlock potential.
+         * 
+         * @param event <code>ServiceEvent</code> object from the framework.
+         */
+        public void serviceChanged(ServiceEvent event) {
+            /*
+             * Check if we had a delayed call (which could happen when we
+             * close).
+             */
+            if (closed) {
+                return;
+            }
+            ServiceReference reference = event.getServiceReference();
+            if (DEBUG) {
+                System.out
+                        .println("ServiceTracker.Tracked.serviceChanged[" + event.getType() + "]: " + reference); //$NON-NLS-1$ //$NON-NLS-2$
+            }
+
+            switch (event.getType()) {
+                case ServiceEvent.REGISTERED :
+                case ServiceEvent.MODIFIED :
+                    if (noUserFilter) { // no user supplied filter to be checked
+                        track(reference);
+                        /*
+                         * If the customizer throws an unchecked exception, it
+                         * is safe to let it propagate
+                         */
+                    }
+                    else { // filter supplied by user must be checked
+                        if (filter.match(reference)) {
+                            track(reference);
+                            /*
+                             * If the customizer throws an unchecked exception,
+                             * it is safe to let it propagate
+                             */
+                        }
+                        else {
+                            untrack(reference);
+                            /*
+                             * If the customizer throws an unchecked exception,
+                             * it is safe to let it propagate
+                             */
+                        }
+                    }
+                    break;
+                case ServiceEvent.UNREGISTERING :
+                    untrack(reference);
+                    /*
+                     * If the customizer throws an unchecked exception, it is
+                     * safe to let it propagate
+                     */
+                    break;
+            }
+        }
+
+        /**
+         * Begin to track the referenced service.
+         * 
+         * @param reference Reference to a service to be tracked.
+         */
+        private void track(ServiceReference reference) {
+            Object object;
+            synchronized (this) {
+                object = this.get(reference);
+            }
+            if (object != null) /* we are already tracking the service */
+            {
+                if (DEBUG) {
+                    System.out
+                            .println("ServiceTracker.Tracked.track[modified]: " + reference); //$NON-NLS-1$
+                }
+                synchronized (this) {
+                    modified(); /* increment modification count */
+                }
+                /* Call customizer outside of synchronized region */
+                customizer.modifiedService(reference, object);
+                /*
+                 * If the customizer throws an unchecked exception, it is safe
+                 * to let it propagate
+                 */
+                return;
+            }
+            synchronized (this) {
+                if (adding.contains(reference)) { /*
+                                                     * if this service is
+                                                     * already in the process of
+                                                     * being added.
+                                                     */
+                    if (DEBUG) {
+                        System.out
+                                .println("ServiceTracker.Tracked.track[already adding]: " + reference); //$NON-NLS-1$
+                    }
+                    return;
+                }
+                adding.add(reference); /* mark this service is being added */
+            }
+
+            trackAdding(reference); /*
+                                     * call trackAdding now that we have put the
+                                     * reference in the adding list
+                                     */
+        }
+
+        /**
+         * Common logic to add a service to the tracker used by track and
+         * trackInitialServices. The specified reference must have been placed
+         * in the adding list before calling this method.
+         * 
+         * @param reference Reference to a service to be tracked.
+         */
+        private void trackAdding(ServiceReference reference) {
+            if (DEBUG) {
+                System.out
+                        .println("ServiceTracker.Tracked.trackAdding: " + reference); //$NON-NLS-1$
+            }
+            Object object = null;
+            bool becameUntracked = false;
+            /* Call customizer outside of synchronized region */
+            try {
+                object = customizer.addingService(reference);
+                /*
+                 * If the customizer throws an unchecked exception, it will
+                 * propagate after the finally
+                 */
+            }
+            finally {
+                synchronized (this) {
+                    if (adding.remove(reference)) { /*
+                                                     * if the service was not
+                                                     * untracked during the
+                                                     * customizer callback
+                                                     */
+                        if (object != null) {
+                            this.put(reference, object);
+                            modified(); /* increment modification count */
+                            notifyAll(); /*
+                                             * notify any waiters in
+                                             * waitForService
+                                             */
+                        }
+                    }
+                    else {
+                        becameUntracked = true;
+                    }
+                }
+            }
+            /*
+             * The service became untracked during the customizer callback.
+             */
+            if (becameUntracked) {
+                if (DEBUG) {
+                    System.out
+                            .println("ServiceTracker.Tracked.trackAdding[removed]: " + reference); //$NON-NLS-1$
+                }
+                /* Call customizer outside of synchronized region */
+                customizer.removedService(reference, object);
+                /*
+                 * If the customizer throws an unchecked exception, it is safe
+                 * to let it propagate
+                 */
+            }
+        }
+
+        /**
+         * Discontinue tracking the referenced service.
+         * 
+         * @param reference Reference to the tracked service.
+         */
+        protected void untrack(ServiceReference reference) {
+            Object object;
+            synchronized (this) {
+                if (initial.remove(reference)) { /*
+                                                     * if this service is
+                                                     * already in the list of
+                                                     * initial references to
+                                                     * process
+                                                     */
+                    if (DEBUG) {
+                        System.out
+                                .println("ServiceTracker.Tracked.untrack[removed from initial]: " + reference); //$NON-NLS-1$
+                    }
+                    return; /*
+                             * we have removed it from the list and it will not
+                             * be processed
+                             */
+                }
+
+                if (adding.remove(reference)) { /*
+                                                 * if the service is in the
+                                                 * process of being added
+                                                 */
+                    if (DEBUG) {
+                        System.out
+                                .println("ServiceTracker.Tracked.untrack[being added]: " + reference); //$NON-NLS-1$
+                    }
+                    return; /*
+                             * in case the service is untracked while in the
+                             * process of adding
+                             */
+                }
+                object = this.remove(reference); /*
+                                                     * must remove from tracker
+                                                     * before calling customizer
+                                                     * callback
+                                                     */
+                if (object == null) { /* are we actually tracking the service */
+                    return;
+                }
+                modified(); /* increment modification count */
+            }
+            if (DEBUG) {
+                System.out
+                        .println("ServiceTracker.Tracked.untrack[removed]: " + reference); //$NON-NLS-1$
+            }
+            /* Call customizer outside of synchronized region */
+            customizer.removedService(reference, object);
+            /*
+             * If the customizer throws an unchecked exception, it is safe to
+             * let it propagate
+             */
+        }
+    }
+
+    /**
+     * Subclass of Tracked which implements the AllServiceListener interface.
+     * This class is used by the ServiceTracker if open is called with true.
+     * 
+     * @since 1.3
+     * @ThreadSafe
+     */
+    class AllTracked extends Tracked implements AllServiceListener {
+        static final long   serialVersionUID    = 4050764875305137716L;
+
+        /**
+         * AllTracked constructor.
+         */
+        protected AllTracked() {
+            super();
+        }
+    }
+}
++++/
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.osgi/osgi/src/org/osgi/util/tracker/ServiceTrackerCustomizer.d	Sat Apr 18 13:58:35 2009 +0200
@@ -0,0 +1,98 @@
+/*
+ * $Header: /cvshome/build/org.osgi.util.tracker/src/org/osgi/util/tracker/ServiceTrackerCustomizer.java,v 1.13 2007/02/19 19:04:33 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+import java.lang.all;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * The <code>ServiceTrackerCustomizer</code> interface allows a
+ * <code>ServiceTracker</code> object to customize the service objects that
+ * are tracked. The <code>ServiceTrackerCustomizer</code> object is called
+ * when a service is being added to the <code>ServiceTracker</code> object.
+ * The <code>ServiceTrackerCustomizer</code> can then return an object for the
+ * tracked service. The <code>ServiceTrackerCustomizer</code> object is also
+ * called when a tracked service is modified or has been removed from the
+ * <code>ServiceTracker</code> object.
+ * 
+ * <p>
+ * The methods in this interface may be called as the result of a
+ * <code>ServiceEvent</code> being received by a <code>ServiceTracker</code>
+ * object. Since <code>ServiceEvent</code> s are synchronously delivered by
+ * the Framework, it is highly recommended that implementations of these methods
+ * do not register (<code>BundleContext.registerService</code>), modify (
+ * <code>ServiceRegistration.setProperties</code>) or unregister (
+ * <code>ServiceRegistration.unregister</code>) a service while being
+ * synchronized on any object.
+ * 
+ * <p>
+ * The <code>ServiceTracker</code> class is thread-safe. It does not call a
+ * <code>ServiceTrackerCustomizer</code> object while holding any locks.
+ * <code>ServiceTrackerCustomizer</code> implementations must also be
+ * thread-safe.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 1.13 $
+ */
+public interface ServiceTrackerCustomizer {
+    /**
+     * A service is being added to the <code>ServiceTracker</code> object.
+     * 
+     * <p>
+     * This method is called before a service which matched the search
+     * parameters of the <code>ServiceTracker</code> object is added to it.
+     * This method should return the service object to be tracked for this
+     * <code>ServiceReference</code> object. The returned service object is
+     * stored in the <code>ServiceTracker</code> object and is available from
+     * the <code>getService</code> and <code>getServices</code> methods.
+     * 
+     * @param reference Reference to service being added to the
+     *        <code>ServiceTracker</code> object.
+     * @return The service object to be tracked for the
+     *         <code>ServiceReference</code> object or <code>null</code> if
+     *         the <code>ServiceReference</code> object should not be tracked.
+     */
+    public Object addingService(ServiceReference reference);
+
+    /**
+     * A service tracked by the <code>ServiceTracker</code> object has been
+     * modified.
+     * 
+     * <p>
+     * This method is called when a service being tracked by the
+     * <code>ServiceTracker</code> object has had it properties modified.
+     * 
+     * @param reference Reference to service that has been modified.
+     * @param service The service object for the modified service.
+     */
+    public void modifiedService(ServiceReference reference, Object service);
+
+    /**
+     * A service tracked by the <code>ServiceTracker</code> object has been
+     * removed.
+     * 
+     * <p>
+     * This method is called after a service is no longer being tracked by the
+     * <code>ServiceTracker</code> object.
+     * 
+     * @param reference Reference to service that has been removed.
+     * @param service The service object for the removed service.
+     */
+    public void removedService(ServiceReference reference, Object service);
+}
--- a/org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/program/Program.d	Sat Apr 18 13:54:50 2009 +0200
+++ b/org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/program/Program.d	Sat Apr 18 13:58:35 2009 +0200
@@ -231,7 +231,7 @@
 /* Determine the desktop for the given display. */
 static int getDesktop(Display display) {
     if (display is null) return DESKTOP_UNKNOWN;
-    ValueWrapperInt desktopValue = cast(ValueWrapperInt)display.getData(DESKTOP_DATA);
+    Integer desktopValue = cast(Integer)display.getData(DESKTOP_DATA);
     if (desktopValue !is null) return desktopValue.value;
     int desktop = DESKTOP_UNKNOWN;
 
@@ -263,12 +263,12 @@
         if (gnome !is OS.None && (OS.GTK_VERSION >= OS.buildVERSION (2, 2, 0)) && gnome_init()) {
             desktop = DESKTOP_GNOME;
             int icon_theme = cast(int)GNOME.gnome_icon_theme_new();
-            display.setData(ICON_THEME_DATA, new ValueWrapperInt(icon_theme));
+            display.setData(ICON_THEME_DATA, new Integer(icon_theme));
             display.addListener(SWT.Dispose, new class(display) Listener {
                 Display display;
                 this( Display display ){ this.display = display; }
                 public void handleEvent(Event event) {
-                    ValueWrapperInt gnomeIconTheme = cast(ValueWrapperInt)display.getData(ICON_THEME_DATA);
+                    Integer gnomeIconTheme = cast(Integer)display.getData(ICON_THEME_DATA);
                     if (gnomeIconTheme is null) return;
                     display.setData(ICON_THEME_DATA, null);
                     /*
@@ -306,7 +306,7 @@
     }
 +/
 
-    display.setData(DESKTOP_DATA, new ValueWrapperInt(desktop));
+    display.setData(DESKTOP_DATA, new Integer(desktop));
     return desktop;
 }
 
@@ -688,7 +688,7 @@
         program.gnomeExpectUri = application.expects_uris is GNOME.GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS;
 
         buffer = (fromStringz( application.id) ~ '\0')._idup();
-        ValueWrapperInt gnomeIconTheme = cast(ValueWrapperInt)display.getData(ICON_THEME_DATA);
+        Integer gnomeIconTheme = cast(Integer)display.getData(ICON_THEME_DATA);
         char* icon_name = GNOME.gnome_icon_lookup( cast(GtkIconTheme*) gnomeIconTheme.value, null, null, cast(char*)buffer.ptr, null, mimeTypeBuffer,
                 GNOME.GNOME_ICON_LOOKUP_FLAGS_NONE, null);
         char* path = null;
--- a/org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/accessibility/Accessible.d	Sat Apr 18 13:54:50 2009 +0200
+++ b/org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/accessibility/Accessible.d	Sat Apr 18 13:58:35 2009 +0200
@@ -1141,8 +1141,8 @@
                 nextItems = new Object[endIndex - enumIndex + 1];
                 for (int i = 0; i < nextItems.length; i++) {
                     Object child = variants[enumIndex];
-                    if (auto val = cast(ValueWrapperInt)child ) {
-                        nextItems[i] = new ValueWrapperInt(childIDToOs(val.value));
+                    if (auto val = cast(Integer)child ) {
+                        nextItems[i] = new Integer(childIDToOs(val.intValue()));
                     } else {
                         nextItems[i] = child;
                     }
@@ -1153,8 +1153,8 @@
         if (nextItems !is null) {
             for (int i = 0; i < nextItems.length; i++) {
                 Object nextItem = nextItems[i];
-                if (auto val = cast(ValueWrapperInt)nextItem ) {
-                    int item = val.value;
+                if (auto val = cast(Integer)nextItem ) {
+                    int item = val.intValue();
                     rgvar[i].vt = COM.VT_I4;
                     rgvar[i].byRef = cast(void*)item;
                     COM.MoveMemory(rgvar + i * VARIANT.sizeof + 8, &item, 4);
--- a/org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/printing/PrintDialog.d	Sat Apr 18 13:54:50 2009 +0200
+++ b/org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/printing/PrintDialog.d	Sat Apr 18 13:58:35 2009 +0200
@@ -300,7 +300,7 @@
     PrinterData data = null;
     String key = "org.eclipse.swt.internal.win32.runMessagesInIdle"; //$NON-NLS-1$
     Object oldValue = display.getData(key);
-    display.setData(key, new ValueWrapperBool(true));
+    display.setData(key, new Boolean(true));
     bool success = cast(bool)OS.PrintDlg(&pd);
     display.setData(key, oldValue);
     if ((getStyle() & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) !is 0) {
--- a/org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/widgets/Display.d	Sat Apr 18 13:54:50 2009 +0200
+++ b/org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/widgets/Display.d	Sat Apr 18 13:58:35 2009 +0200
@@ -1654,7 +1654,7 @@
     // SWT extension: allow null string
     //if (key is null) error (SWT.ERROR_NULL_ARGUMENT);
     if (key ==/*eq*/RUN_MESSAGES_IN_IDLE_KEY) {
-        return new ValueWrapperBool(runMessagesInIdle);
+        return new Boolean(runMessagesInIdle);
     }
     if (key.equals (RUN_MESSAGES_IN_MESSAGE_PROC_KEY)) {
         return new Boolean (runMessagesInMessageProc);
@@ -4130,7 +4130,7 @@
     //if (key is null) error (SWT.ERROR_NULL_ARGUMENT);
 
     if (key ==/*eq*/RUN_MESSAGES_IN_IDLE_KEY) {
-        auto data = cast(ValueWrapperBool) value;
+        auto data = cast(Boolean) value;
         runMessagesInIdle = data !is null && data.value;
         return;
     }
--- a/rakefile	Sat Apr 18 13:54:50 2009 +0200
+++ b/rakefile	Sat Apr 18 13:58:35 2009 +0200
@@ -70,7 +70,7 @@
 
 end
 LIBNAMES_SWT        = [ BASEDIR_SWT ]
-LIBNAMES_EQUINOX    = [ "org.eclipse.osgi",
+LIBNAMES_EQUINOX    = [ "org.eclipse.osgi.osgi",
                         "org.eclipse.osgi.supplement",
                         "org.eclipse.equinox.common" ]
 
@@ -306,7 +306,7 @@
 
 desc "Build Equinox"
 task :equinox do
-    buildTree( "org.eclipse.osgi", "src", "res" )
+    buildTree( "org.eclipse.osgi", "osgi/src"      , "res", nil, "org.eclipse.osgi.osgi" )
     buildTree( "org.eclipse.osgi", "supplement/src", "res", nil, "org.eclipse.osgi.supplement")
     buildTree( "org.eclipse.equinox.common", "src", "res" )
 end
@@ -318,8 +318,13 @@
     buildTree( "org.eclipse.core.jobs", "src", "res" )
 end
 
+desc "Build Jface Databinding"
+task :jfacebind do
+    buildTree( "org.eclipse.jface.databinding", "src", "res" )
+end
 desc "Build Databinding"
 task :bind do
+    buildTree( "com.ibm.icu", "src", "res" )
     buildTree( "org.eclipse.core.databinding", "src", "res" )
     buildTree( "org.eclipse.jface.databinding", "src", "res" )
 end