added Clock and BinaryLight UPnP examples

git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@399191 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/Activator.java b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/Activator.java
new file mode 100644
index 0000000..52fb38b
--- /dev/null
+++ b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/Activator.java
@@ -0,0 +1,64 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   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.
+ *
+ */
+
+package org.apache.felix.upnp.sample.binaryLight;
+
+import java.util.Dictionary;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.upnp.UPnPDevice;
+
+
+/* 
+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+*/
+
+public class Activator implements BundleActivator {
+
+	static BundleContext context;
+	private ServiceRegistration serviceRegistration;
+	private LightDevice light;
+	
+	/**
+	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		Activator.context = context;
+		doServiceRegistration();
+	}
+
+	private void doServiceRegistration() {
+		light = new LightDevice(context);
+		Dictionary dict = light.getDescriptions(null);
+				
+		serviceRegistration = context.registerService(
+				UPnPDevice.class.getName(),
+				light,
+				dict
+			);
+	}
+
+	/**
+	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		serviceRegistration.unregister();
+		light.close();
+	}
+}
diff --git a/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/EventSource.java b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/EventSource.java
new file mode 100644
index 0000000..c0c56de
--- /dev/null
+++ b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/EventSource.java
@@ -0,0 +1,32 @@
+/*

+ *   Copyright 2006 The Apache Software Foundation

+ *

+ *   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.

+ *

+ */

+

+package org.apache.felix.upnp.sample.binaryLight;

+

+import java.beans.PropertyChangeListener;

+

+/* 

+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>

+*/

+

+public interface EventSource {

+	void addPropertyChangeListener(PropertyChangeListener listener);

+	void addPropertyChangeListener(String propertyName, PropertyChangeListener listener);

+	void removePropertyChangeListener(PropertyChangeListener listener);

+	void removePropertyChangeListener(String propertyName, PropertyChangeListener listener);

+}

+

diff --git a/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/GetStatusAction.java b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/GetStatusAction.java
new file mode 100644
index 0000000..746662b
--- /dev/null
+++ b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/GetStatusAction.java
@@ -0,0 +1,89 @@
+/*

+ *   Copyright 2006 The Apache Software Foundation

+ *

+ *   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.

+ *

+ */

+

+package org.apache.felix.upnp.sample.binaryLight;

+

+import java.util.Dictionary;

+import java.util.Hashtable;

+

+import org.osgi.service.upnp.UPnPAction;

+import org.osgi.service.upnp.UPnPStateVariable;

+

+/* 

+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>

+*/

+

+public class GetStatusAction implements UPnPAction {

+

+	final private String NAME = "GetStatus";

+	final private String RESULT_STATUS = "ResultStatus";

+	final private String[] OUT_ARG_NAMES = new String[]{RESULT_STATUS};

+	private UPnPStateVariable state;

+	private LightModel model;

+	

+	

+	public GetStatusAction(LightModel model,UPnPStateVariable state){

+		this.state = state;

+		this.model=model;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#getName()

+	 */

+	public String getName() {

+		return NAME;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#getReturnArgumentName()

+	 */

+	public String getReturnArgumentName() {

+		return null;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#getInputArgumentNames()

+	 */

+	public String[] getInputArgumentNames() {

+		

+		return null;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#getOutputArgumentNames()

+	 */

+	public String[] getOutputArgumentNames() {

+		return OUT_ARG_NAMES;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#getStateVariable(java.lang.String)

+	 */

+	public UPnPStateVariable getStateVariable(String argumentName) {

+		return state;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#invoke(java.util.Dictionary)

+	 */

+	public Dictionary invoke(Dictionary args) throws Exception {

+		boolean status = model.getStatus();

+		Hashtable result = new Hashtable();

+		result.put(RESULT_STATUS,new Boolean(status));

+		return result;

+	}

+}

diff --git a/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/GetTargetAction.java b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/GetTargetAction.java
new file mode 100644
index 0000000..eb55c06
--- /dev/null
+++ b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/GetTargetAction.java
@@ -0,0 +1,89 @@
+/*

+ *   Copyright 2006 The Apache Software Foundation

+ *

+ *   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.

+ *

+ */

+

+package org.apache.felix.upnp.sample.binaryLight;

+

+import java.util.Dictionary;

+import java.util.Hashtable;

+

+import org.osgi.service.upnp.UPnPAction;

+import org.osgi.service.upnp.UPnPStateVariable;

+

+/* 

+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>

+*/

+

+public class GetTargetAction implements UPnPAction {

+

+	final private String NAME = "GetTarget";

+	final private String RET_TARGET_VALUE = "RetTargetValue";

+	final private String[] OUT_ARG_NAMES = new String[]{RET_TARGET_VALUE};

+	private UPnPStateVariable state;

+	private LightModel model;

+	

+	

+	public GetTargetAction(LightModel model,UPnPStateVariable state){

+		this.state = state;

+		this.model=model;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#getName()

+	 */

+	public String getName() {

+		return NAME;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#getReturnArgumentName()

+	 */

+	public String getReturnArgumentName() {

+		return null;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#getInputArgumentNames()

+	 */

+	public String[] getInputArgumentNames() {

+		

+		return null;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#getOutputArgumentNames()

+	 */

+	public String[] getOutputArgumentNames() {

+		return OUT_ARG_NAMES;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#getStateVariable(java.lang.String)

+	 */

+	public UPnPStateVariable getStateVariable(String argumentName) {

+		return state;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#invoke(java.util.Dictionary)

+	 */

+	public Dictionary invoke(Dictionary args) throws Exception {

+		boolean target = model.getTarget();

+		Hashtable result = new Hashtable();

+		result.put(RET_TARGET_VALUE,new Boolean(target));

+		return result;

+	}

+}

diff --git a/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/LightDevice.java b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/LightDevice.java
new file mode 100644
index 0000000..1157a05
--- /dev/null
+++ b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/LightDevice.java
@@ -0,0 +1,123 @@
+/*

+ *   Copyright 2006 The Apache Software Foundation

+ *

+ *   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.

+ *

+ */

+

+package org.apache.felix.upnp.sample.binaryLight;

+

+import java.util.Dictionary;

+import java.util.Properties;

+

+import org.osgi.framework.BundleContext;

+import org.osgi.service.upnp.UPnPDevice;

+import org.osgi.service.upnp.UPnPIcon;

+import org.osgi.service.upnp.UPnPService;

+

+/* 

+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>

+*/

+

+public class LightDevice implements UPnPDevice {

+

+	final private String DEVICE_ID = "uuid:Felix-BinaryLight";

+	private BundleContext context;

+	private LightModel model;

+	private LightUI ui;

+	private PowerSwitchService powerSwitch;

+	private UPnPService[] services;

+	private Dictionary dictionary;

+	private UPnPEventNotifier notifier;

+	

+	public LightDevice(BundleContext context) {

+		this.context=context;

+		model = new LightModel();

+		ui = new LightUI(model);

+		powerSwitch = new PowerSwitchService(model);

+		services = new UPnPService[]{powerSwitch};

+		setupDeviceProperties();

+		buildEventNotifyer();

+	}

+

+	/**

+	 * 

+	 */

+	private void buildEventNotifyer() {

+		notifier = new UPnPEventNotifier(context,DEVICE_ID,powerSwitch,model);

+	}

+

+	private void setupDeviceProperties(){

+		dictionary = new Properties();

+		dictionary.put(UPnPDevice.UPNP_EXPORT,"");

+		dictionary.put(

+		        org.osgi.service

+		        	.device.Constants.DEVICE_CATEGORY,

+	        	new String[]{UPnPDevice.DEVICE_CATEGORY}

+	        );

+		//dictionary.put(UPnPDevice.DEVICE_CATEGORY,new String[]{UPnPDevice.DEVICE_CATEGORY});

+		dictionary.put(UPnPDevice.FRIENDLY_NAME,"Felix OSGi-UPnP BinaryLight");

+		dictionary.put(UPnPDevice.MANUFACTURER,"Apache Software Foundation");

+		dictionary.put(UPnPDevice.MANUFACTURER_URL,"http://incubator.apache.org/felix/");

+		dictionary.put(UPnPDevice.MODEL_DESCRIPTION,"A BinaryLight device to test OSGi to UPnP service export");

+		dictionary.put(UPnPDevice.MODEL_NAME,"Lucciola");

+		dictionary.put(UPnPDevice.MODEL_NUMBER,"1.0");

+		dictionary.put(UPnPDevice.MODEL_URL,"http://incubator.apache.org/felix/lucciola");

+		dictionary.put(UPnPDevice.PRESENTATION_URL,"http://incubator.apache.org/felix/lucciola/presentation");

+		dictionary.put(UPnPDevice.SERIAL_NUMBER,"123456789");

+		dictionary.put(UPnPDevice.TYPE,"urn:schemas-upnp-org:device:BinaryLight:1");

+		dictionary.put(UPnPDevice.UDN,DEVICE_ID);

+		//dictionary.put(UPnPDevice.ID,dictionary.get(UPnPDevice.UDN));

+		dictionary.put(UPnPDevice.UPC,"1213456789");

+	}

+	

+	

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPDevice#getService(java.lang.String)

+	 */

+	public UPnPService getService(String serviceId) {

+		if  (serviceId.equals(powerSwitch.getId())) return powerSwitch;

+		return null;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPDevice#getServices()

+	 */

+	public UPnPService[] getServices() {

+		return services;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPDevice#getIcons(java.lang.String)

+	 */

+	public UPnPIcon[] getIcons(String locale) {

+		UPnPIcon icon = new LightIcon();

+		return new UPnPIcon[]{icon} ;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPDevice#getDescriptions(java.lang.String)

+	 */

+	public Dictionary getDescriptions(String locale) {

+		return dictionary;

+	}

+

+	/**

+	 * 

+	 */

+	public void close() {

+		ui.dispose();

+		notifier.destroy();

+	}

+	

+}

diff --git a/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/LightIcon.java b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/LightIcon.java
new file mode 100644
index 0000000..cef3a36
--- /dev/null
+++ b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/LightIcon.java
@@ -0,0 +1,71 @@
+/*

+ *   Copyright 2006 The Apache Software Foundation

+ *

+ *   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.

+ *

+ */

+

+package org.apache.felix.upnp.sample.binaryLight;

+import java.io.IOException;

+import java.io.InputStream;

+

+import org.osgi.service.upnp.UPnPIcon;

+

+/* 

+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>

+*/

+

+public class LightIcon implements UPnPIcon {

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPIcon#getMimeType()

+	 */

+	public String getMimeType() {

+		return "image/gif";

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPIcon#getWidth()

+	 */

+	public int getWidth() {

+		return 32;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPIcon#getHeight()

+	 */

+	public int getHeight() {

+		return 32;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPIcon#getSize()

+	 */

+	public int getSize() {

+		return 0;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPIcon#getDepth()

+	 */

+	public int getDepth() {

+		return 16;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPIcon#getInputStream()

+	 */

+	public InputStream getInputStream() throws IOException {

+		return LightIcon.class.getResourceAsStream("images/LightOn.gif");

+	}

+}

diff --git a/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/LightModel.java b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/LightModel.java
new file mode 100644
index 0000000..4e512ca
--- /dev/null
+++ b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/LightModel.java
@@ -0,0 +1,106 @@
+/*

+ *   Copyright 2006 The Apache Software Foundation

+ *

+ *   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.

+ *

+ */

+

+package org.apache.felix.upnp.sample.binaryLight;

+

+import java.beans.PropertyChangeListener;

+import java.beans.PropertyChangeSupport;

+

+/* 

+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>

+*/

+

+public class LightModel implements EventSource{

+	

+	private boolean status = false;

+	private boolean target = false;

+	private boolean failure = false;

+	private PropertyChangeSupport propertySupport = new PropertyChangeSupport(this);

+	

+	public LightModel(){	

+	}

+	

+	public void addPropertyChangeListener(PropertyChangeListener listener){

+		propertySupport.addPropertyChangeListener(listener);

+	}

+	

+	public void removePropertyChangeListener(PropertyChangeListener listener){

+		propertySupport.removePropertyChangeListener(listener);

+	}

+	public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {

+		propertySupport.addPropertyChangeListener(propertyName,listener);

+	}

+

+	public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {

+		propertySupport.removePropertyChangeListener(propertyName,listener);

+	}

+	

+	public void doSwitch(boolean value){

+		if (value) switchOn();

+		else switchOff();

+	}

+	

+	public void switchOn(){

+		target = true;

+		if(! failure) {

+			boolean oldStatus = status;

+			status = true;

+			propertySupport.firePropertyChange("Status",oldStatus,status);

+		}

+	}

+	

+	public void switchOff(){

+		target = false;

+		if(! failure) {

+			boolean oldStatus = status;

+			status = false;

+			propertySupport.firePropertyChange("Status",oldStatus,status);

+		}

+	}

+	

+	public void setFailure(boolean value){

+		boolean oldFailure = failure;

+		boolean oldStatus = status;

+		failure = value;

+		if (failure){

+			status = false;

+		}

+		else if (target){

+			status = true;

+		}

+		propertySupport.firePropertyChange("Status",oldStatus,status);

+		propertySupport.firePropertyChange("Failure",oldFailure,failure);

+	}

+	

+

+	/**

+	 * @return

+	 */

+	public boolean getTarget() {

+		return target;

+	}

+

+	/**

+	 * @return

+	 */

+	public boolean getStatus() {

+		return status;

+	}

+

+

+

+}

diff --git a/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/LightUI.java b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/LightUI.java
new file mode 100644
index 0000000..5f67ba7
--- /dev/null
+++ b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/LightUI.java
@@ -0,0 +1,150 @@
+/*

+ *   Copyright 2006 The Apache Software Foundation

+ *

+ *   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.

+ *

+ */

+

+package org.apache.felix.upnp.sample.binaryLight;

+

+import java.awt.BorderLayout;

+import java.awt.event.MouseAdapter;

+import java.awt.event.MouseEvent;

+import java.awt.event.WindowAdapter;

+import java.awt.event.WindowEvent;

+import java.beans.PropertyChangeEvent;

+import java.beans.PropertyChangeListener;

+import java.net.URL;

+

+import javax.swing.Icon;

+import javax.swing.ImageIcon;

+import javax.swing.JButton;

+import javax.swing.JFrame;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.SwingUtilities;

+

+import org.osgi.framework.BundleException;

+

+/* 

+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>

+*/

+

+public class LightUI extends JFrame implements PropertyChangeListener {

+    private final static ImageIcon LIGHT_ON = LightUI.loadIcon("LightOn.gif","ON");

+    private final static ImageIcon LIGHT_OFF = LightUI.loadIcon("LightOff.gif","OFF");

+    private final static ImageIcon LIGHT_FAIL = LightUI.loadIcon("LightFail.gif","FAILURE");

+	private final JLabel label = new JLabel();

+    private LightModel model;

+   

+	public LightUI(LightModel model)   {

+		super("Felix UPnP BinaryLight");

+		this.model = model;

+		setSize(150,150);

+		JPanel panel = new JPanel(new BorderLayout());

+		panel.add(doMainPanel(),BorderLayout.CENTER);

+		panel.add(doControlPanel(),BorderLayout.SOUTH);

+		getContentPane().add(panel);

+		model.addPropertyChangeListener(this);

+

+		addWindowListener(new WindowAdapter(){

+			public void windowClosing(WindowEvent e) 

+			{

+				try {

+					Activator.context.getBundle().stop();

+				} catch (BundleException ex) {

+					ex.printStackTrace();

+				}

+			}

+		});			

+	       try {

+	            URL eventIconUrl = LightUI.class.getResource("images/logo.gif");           

+	            ImageIcon icon=  new ImageIcon(eventIconUrl,"logo");

+	            setIconImage(icon.getImage());

+	       }

+	        catch (Exception ex){

+	                System.out.println("Resource: IMAGES/logo.gif not found : " + ex.toString());

+	        }

+	

+		pack();

+		show();

+    }

+	

+	private JPanel doMainPanel(){

+		JPanel panel = new JPanel();

+		label.setIcon(LIGHT_OFF);

+		//label.setSize(new Dimension(32,32));

+	    label.addMouseListener(new MouseAdapter(){          

+	          public void mouseClicked(MouseEvent e){

+	            if (SwingUtilities.isLeftMouseButton(e)){

+	              if (e.getClickCount()==1){

+	              Icon icon = label.getIcon();

+	              if (icon == LIGHT_ON)

+	                  model.switchOff();

+	              else 

+	                  model.switchOn();

+	              }

+	            }

+	          }

+	    });

+	    panel.add(label);

+	    return panel;

+	}

+	          

+	private JPanel doControlPanel(){

+		JPanel panel = new JPanel();

+		JButton btnSwitch = new JButton("On");

+		JButton btnFailure = new JButton("Failure");

+		panel.add(btnSwitch);

+		panel.add(btnFailure);

+		return panel;

+	}

+	

+    public  static ImageIcon loadIcon(String path,String title)

+    {

+        try {

+            URL eventIconUrl = LightUI.class.getResource("images/" + path);

+            return new ImageIcon(eventIconUrl,title);

+        }

+        catch (Exception ex){

+			System.out.println("Resource:" + path + " not found : " + ex.toString());

+            return null;

+        }

+    }

+

+	/* (non-Javadoc)

+	 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)

+	 */

+    public void propertyChange(PropertyChangeEvent evt) {

+    	String property = evt.getPropertyName();

+    	System.out.println("Light changed property::"+property);

+    	boolean value = ((Boolean) evt.getNewValue()).booleanValue();

+    	if (property.equals("Status")){

+    		if (value)

+    			label.setIcon(LIGHT_ON);

+    		else

+    			label.setIcon(LIGHT_OFF);

+    	}

+    	else if (property.equals("Failure")){            

+    		if (value)

+    			label.setIcon(LIGHT_FAIL);

+    		else

+    			label.setIcon(LIGHT_OFF);

+    	}

+    	getContentPane().validate();

+    	repaint();

+		

+	}

+

+	

+}

diff --git a/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/PowerSwitchService.java b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/PowerSwitchService.java
new file mode 100644
index 0000000..1d0989f
--- /dev/null
+++ b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/PowerSwitchService.java
@@ -0,0 +1,111 @@
+/*

+ *   Copyright 2006 The Apache Software Foundation

+ *

+ *   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.

+ *

+ */

+

+

+

+package org.apache.felix.upnp.sample.binaryLight;

+

+import java.util.HashMap;

+

+import org.osgi.service.upnp.UPnPAction;

+import org.osgi.service.upnp.UPnPService;

+import org.osgi.service.upnp.UPnPStateVariable;

+

+/* 

+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>

+*/

+

+public class PowerSwitchService implements UPnPService{

+	

+	final private String SERVICE_ID = "urn:upnp-org:serviceId:SwitchPower:1";

+	final private String SERVICE_TYPE = "urn:schemas-upnp-org:service:SwitchPower:1";

+	final private String VERSION ="1";

+

+	private LightModel model;

+	private UPnPStateVariable status,target;

+	private UPnPStateVariable[] states;

+	private HashMap actions = new HashMap();

+	

+	

+	public PowerSwitchService(LightModel model){

+		this.model = model;

+		status = new StatusStateVariable();

+		target = new TargetStateVariable();

+		this.states = new UPnPStateVariable[]{status,target};

+		

+		UPnPAction setTarget = new SetTargetAction(model,target);

+		UPnPAction getTarget = new GetTargetAction(model,target);

+		UPnPAction getStatus = new GetStatusAction(model,status);

+		actions.put(setTarget.getName(),setTarget);

+		actions.put(getTarget.getName(),getTarget);

+		actions.put(getStatus.getName(),getStatus);

+		

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPService#getId()

+	 */

+	public String getId() {

+		return SERVICE_ID;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPService#getType()

+	 */

+	public String getType() {

+		return SERVICE_TYPE;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPService#getVersion()

+	 */

+	public String getVersion() {

+		return VERSION;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPService#getAction(java.lang.String)

+	 */

+	public UPnPAction getAction(String name) {

+		return (UPnPAction)actions.get(name);

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPService#getActions()

+	 */

+	public UPnPAction[] getActions() {

+		return (UPnPAction[])(actions.values()).toArray(new UPnPAction[]{});

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPService#getStateVariables()

+	 */

+	public UPnPStateVariable[] getStateVariables() {

+		return states;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPService#getStateVariable(java.lang.String)

+	 */

+	public UPnPStateVariable getStateVariable(String name) {

+		if (name.equals("Status"))

+			return status;

+		else if (name.equals("Target"))

+			return target;

+		else return null;

+	}

+}

diff --git a/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/SetTargetAction.java b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/SetTargetAction.java
new file mode 100644
index 0000000..42fb290
--- /dev/null
+++ b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/SetTargetAction.java
@@ -0,0 +1,86 @@
+/*

+ *   Copyright 2006 The Apache Software Foundation

+ *

+ *   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.

+ *

+ */

+

+package org.apache.felix.upnp.sample.binaryLight;

+

+import java.util.Dictionary;

+

+import org.osgi.service.upnp.UPnPAction;

+import org.osgi.service.upnp.UPnPStateVariable;

+

+/* 

+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>

+*/

+

+public class SetTargetAction implements UPnPAction {

+

+	final private String NAME = "SetTarget";

+	final private String NEW_TARGET_VALUE = "NewTargetValue";

+	final private String[] IN_ARG_NAMES = new String[]{NEW_TARGET_VALUE};

+	private UPnPStateVariable state;

+	private LightModel model;

+	

+	

+	public SetTargetAction(LightModel model,UPnPStateVariable state){

+		this.state = state;

+		this.model=model;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#getName()

+	 */

+	public String getName() {

+		return NAME;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#getReturnArgumentName()

+	 */

+	public String getReturnArgumentName() {

+		return null;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#getInputArgumentNames()

+	 */

+	public String[] getInputArgumentNames() {

+		return IN_ARG_NAMES;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#getOutputArgumentNames()

+	 */

+	public String[] getOutputArgumentNames() {

+		return null;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#getStateVariable(java.lang.String)

+	 */

+	public UPnPStateVariable getStateVariable(String argumentName) {

+		return state;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPAction#invoke(java.util.Dictionary)

+	 */

+	public Dictionary invoke(Dictionary args) throws Exception {

+		Boolean value = (Boolean) args.get(NEW_TARGET_VALUE);

+		model.doSwitch(value.booleanValue());

+		return null;

+	}

+}

diff --git a/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/StatusStateVariable.java b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/StatusStateVariable.java
new file mode 100644
index 0000000..bf64539
--- /dev/null
+++ b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/StatusStateVariable.java
@@ -0,0 +1,95 @@
+/*

+ *   Copyright 2006 The Apache Software Foundation

+ *

+ *   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.

+ *

+ */

+

+package org.apache.felix.upnp.sample.binaryLight;

+import org.osgi.service.upnp.UPnPStateVariable;

+/* 

+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>

+*/

+

+public class StatusStateVariable implements UPnPStateVariable{

+	

+	final private String NAME = "Status";

+	final private Boolean DEFAULT_VALUE = Boolean.FALSE;

+	

+	

+	public StatusStateVariable(){

+	}

+	

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#getName()

+	 */

+	public String getName() {

+		return NAME;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#getJavaDataType()

+	 */

+	public Class getJavaDataType() {

+		return Boolean.class;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#getUPnPDataType()

+	 */

+	public String getUPnPDataType() {

+		return TYPE_BOOLEAN;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#getDefaultValue()

+	 */

+	public Object getDefaultValue() {

+		return DEFAULT_VALUE;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#getAllowedValues()

+	 */

+	public String[] getAllowedValues() {

+		return null;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#getMinimum()

+	 */

+	public Number getMinimum() {

+		return null;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#getMaximum()

+	 */

+	public Number getMaximum() {

+		return null;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#getStep()

+	 */

+	public Number getStep() {

+		return null;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#sendsEvents()

+	 */

+	public boolean sendsEvents() {

+		return true;

+	}

+}

diff --git a/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/TargetStateVariable.java b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/TargetStateVariable.java
new file mode 100644
index 0000000..7b792fd
--- /dev/null
+++ b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/TargetStateVariable.java
@@ -0,0 +1,95 @@
+/*

+ *   Copyright 2006 The Apache Software Foundation

+ *

+ *   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.

+ *

+ */

+

+package org.apache.felix.upnp.sample.binaryLight;

+import org.osgi.service.upnp.UPnPStateVariable;

+/* 

+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>

+*/

+

+public class TargetStateVariable implements UPnPStateVariable{

+	

+	final private String NAME = "Target";

+	final private Boolean DEFAULT_VALUE = Boolean.FALSE;

+	

+	

+	public TargetStateVariable(){

+	}

+	

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#getName()

+	 */

+	public String getName() {

+		return NAME;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#getJavaDataType()

+	 */

+	public Class getJavaDataType() {

+		return Boolean.class;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#getUPnPDataType()

+	 */

+	public String getUPnPDataType() {

+		return TYPE_BOOLEAN;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#getDefaultValue()

+	 */

+	public Object getDefaultValue() {

+		return DEFAULT_VALUE;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#getAllowedValues()

+	 */

+	public String[] getAllowedValues() {

+		return null;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#getMinimum()

+	 */

+	public Number getMinimum() {

+		return null;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#getMaximum()

+	 */

+	public Number getMaximum() {

+		return null;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#getStep()

+	 */

+	public Number getStep() {

+		return null;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.service.upnp.UPnPStateVariable#sendsEvents()

+	 */

+	public boolean sendsEvents() {

+		return false;

+	}

+}

diff --git a/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/UPnPEventNotifier.java b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/UPnPEventNotifier.java
new file mode 100644
index 0000000..65c771e
--- /dev/null
+++ b/org.apache.felix.upnp.sample.binaryLight/src/main/java/org/apache/felix/upnp/sample/binaryLight/UPnPEventNotifier.java
@@ -0,0 +1,181 @@
+/*

+ *   Copyright 2006 The Apache Software Foundation

+ *

+ *   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.

+ *

+ */

+

+package org.apache.felix.upnp.sample.binaryLight;

+

+import java.beans.PropertyChangeEvent;

+import java.beans.PropertyChangeListener;

+import java.util.Iterator;

+import java.util.Properties;

+import java.util.Vector;

+

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.Constants;

+import org.osgi.framework.Filter;

+import org.osgi.framework.ServiceEvent;

+import org.osgi.framework.ServiceListener;

+import org.osgi.framework.ServiceReference;

+import org.osgi.service.upnp.UPnPDevice;

+import org.osgi.service.upnp.UPnPEventListener;

+import org.osgi.service.upnp.UPnPService;

+import org.osgi.service.upnp.UPnPStateVariable;

+

+/* 

+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>

+*/

+

+public class UPnPEventNotifier implements PropertyChangeListener,ServiceListener {

+	BundleContext context;

+	String deviceId;

+	UPnPService service;

+	EventSource source;

+	

+	Properties UPnPTargetListener;

+	String serviceId;

+	Vector upnpListeners = new Vector();

+	

+	public UPnPEventNotifier(BundleContext context,String deviceId,UPnPService service,EventSource source){

+		this.context=context;

+		this.deviceId=deviceId;

+		this.service=service;

+		this.source=source;

+		this.serviceId=service.getId();

+		setupUPnPListenerHouseKeeping(deviceId);

+	}

+	

+	/**

+	 * @param deviceId

+	 */

+	private void setupUPnPListenerHouseKeeping(String deviceId) {

+		UPnPTargetListener = new Properties();

+		UPnPTargetListener.put(UPnPDevice.ID,deviceId);

+		UPnPTargetListener.put(UPnPService.ID,serviceId);

+		String ANY_UPnPEventListener = "("+Constants.OBJECTCLASS+"="+UPnPEventListener.class.getName()+")";

+		

+		ServiceReference[] listeners = null; 

+		try {

+			listeners = context.getServiceReferences(UPnPEventListener.class.getName(),null);

+			if (listeners != null){

+				for (int i = 0;i<listeners.length;i++){

+					ServiceReference sr = listeners[i];

+					Filter filter = (Filter) sr.getProperty(UPnPEventListener.UPNP_FILTER);

+					if (filter == null) upnpListeners.add(sr);

+					else {				

+						if (filter.match(UPnPTargetListener))

+							addNewListener(sr);

+					}

+				}

+			}

+		} catch (Exception ex) {

+			System.out.println(ex);

+		}

+		

+	    try {

+	    	//String filter = "(&" + ANY_UPnPEventListener + deviceId_Filter + ")";

+	    	String filter = ANY_UPnPEventListener;

+			context.addServiceListener(this,filter);

+		} catch (Exception ex) {

+			System.out.println(ex);

+		}

+		

+		if (source!=null){

+			UPnPStateVariable[] vars = service.getStateVariables();

+			if (vars != null){

+				for (int i=0;i<vars.length;i++)

+					if(vars[i].sendsEvents())

+						source.addPropertyChangeListener(vars[i].getName(),this);

+			}

+		}

+		

+		

+	}

+

+	/* (non-Javadoc)

+	 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)

+	 */

+	public void propertyChange(PropertyChangeEvent evt) {

+		Iterator list = upnpListeners.iterator();

+		String property = evt.getPropertyName();

+		Object value = evt.getNewValue();

+		String valueString = value.toString();

+		final Properties events = new Properties();

+		events.put(property,valueString);

+		while (list.hasNext()){

+			final ServiceReference sr = (ServiceReference)list.next();

+			String[] props =sr.getPropertyKeys();

+			new Thread(null,null,"Notifier"){

+				public void run(){

+					try {

+						UPnPEventListener listener = (UPnPEventListener) context.getService(sr);

+						listener.notifyUPnPEvent(deviceId,serviceId,events);

+						context.ungetService(sr);

+					} catch (Exception ex){

+						System.out.println("UPnPEventNotifier Err: " +ex);

+					}

+				}

+			}.start();						

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)

+	 */

+	public void serviceChanged(ServiceEvent e) {

+		switch(e.getType()){

+			case ServiceEvent.REGISTERED:{

+			    System.out.println();

+				ServiceReference sr = e.getServiceReference();

+			    System.out.println(sr);

+				Filter filter = (Filter) sr.getProperty(UPnPEventListener.UPNP_FILTER);

+			    System.out.println(filter);

+				if (filter == null) addNewListener(sr);

+				else {				

+					if (filter.match(UPnPTargetListener))

+						addNewListener(sr);

+				}

+			};break;

+			

+			case ServiceEvent.MODIFIED:{				

+			};break;

+			

+			case ServiceEvent.UNREGISTERING:{	

+				removeListener(e.getServiceReference());

+			};break;

+				

+		}

+		

+	}

+

+	/**

+	 * @param reference

+	 */

+	private void removeListener(ServiceReference reference) {

+		upnpListeners.remove(reference);		

+	}

+

+	/**

+	 * @param reference

+	 */

+	private void addNewListener(ServiceReference reference) {

+		upnpListeners.add(reference);	

+	}

+	

+	public void destroy(){

+		context.removeServiceListener(this);

+		upnpListeners.removeAllElements();

+	}

+}