Modified dependency graph for:
- basedriver; dependency with extra bundle is not more needed. Now the basedriver directly exports the interfaces of the services it registers with the framework (DriverController.java and DevicesInfo.java)
- extra bundle provides only common utilities to write OSGi/UPnP Device services. It is used by the examples
- tv, clock and bynarylight use the extra packages (except for UPnpSubscriber; to do later)
- tester use the basedriver packages for forcing MSearch and Debugging and for resolving  relative URLs

Added thread name to TVFrame.class and ClockFrame.class

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@608127 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/upnp/basedriver/pom.xml b/upnp/basedriver/pom.xml
index a85f6e2..84ee971 100644
--- a/upnp/basedriver/pom.xml
+++ b/upnp/basedriver/pom.xml
@@ -1,4 +1,5 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+<project xmlns="http://maven.apache.org/POM/4.0.0"

+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <parent>
     <groupId>org.apache.felix</groupId>
@@ -18,16 +19,21 @@
       <id>snap.domoware.isti.cnr.it</id>
       <name>Domoware Snapshot Repository</name>
       <url>http://domoware.isti.cnr.it/maven2-snap</url>
-      <releases><enabled>false</enabled></releases>
+      <releases>
+        <enabled>false</enabled>

+      </releases>
     </repository>
     <!-- For release (no snapshots jars or non-apache jars)           -->
     <repository>
       <id>release.domoware.isti.cnr.it</id>
       <name>Domoware Release Repository</name>
       <url>http://domoware.isti.cnr.it/maven2</url>
-      <snapshots><enabled>false</enabled></snapshots>
+      <snapshots>
+        <enabled>false</enabled>

+      </snapshots>
     </repository>
-  </repositories>   <!-- <url>http://maven.apache.org</url> -->
+  </repositories>
+  <!-- <url>http://maven.apache.org</url> -->
 
   <profiles>
 
@@ -39,46 +45,57 @@
           <value>jdk13</value>
         </property>
       </activation>
-  <dependencies>
-    <dependency>
-      <groupId>it.cnr.isti.domoware.cyberdomo</groupId>
-      <artifactId>upnp-stack-jdk13</artifactId>
-      <version>1.8.0-SNAPSHOT</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <version>1.1.0-SNAPSHOT</version>
-        <extensions>true</extensions>
-        <configuration>
-          <instructions>
-            <Bundle-Name>${pom.name}</Bundle-Name>
-            <Bundle-Activator>org.apache.felix.upnp.basedriver.Activator</Bundle-Activator>
-            <Bundle-Vendor>Apache Software Foundation</Bundle-Vendor>
-            <Bundle-Author><![CDATA[Matteo Demuru <demuru@apache.org>,Francesco Furfari <furfari@apache.org>,Stefano "Kismet" Lenzi <lenzi@apache.org>]]></Bundle-Author>
-            <Bundle-Description>
-               	A Bundle implementation of the UPnP Service Specification R4
-            </Bundle-Description>
-            <Bundle-SymbolicName>org.apache.felix.upnp.basedriver</Bundle-SymbolicName>
-	    <!--Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
-	    <Embed-Transitive>true</Embed-Transitive-->
-	    <Export-Package>
-	      org.apache.felix.upnp.extra.*
-	    </Export-Package>
-            <Import-Package>
-              org.osgi.*
-            </Import-Package>
-            <Private-Package>
-              org.apache.felix.upnp.basedriver.*, org.kxml2.io, org.xmlpull.v1, org.cybergarage.*, org.apache.xerces.impl.dv.util
-            </Private-Package>
-          </instructions>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
+      <dependencies>
+        <dependency>
+          <groupId>it.cnr.isti.domoware.cyberdomo</groupId>
+          <artifactId>upnp-stack-jdk13</artifactId>
+          <version>1.8.0-SNAPSHOT</version>
+        </dependency>
+      </dependencies>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>maven-bundle-plugin</artifactId>
+            <version>1.1.0-SNAPSHOT</version>
+            <extensions>true</extensions>
+            <configuration>
+              <instructions>
+                <Bundle-Name>${pom.name}</Bundle-Name>
+                <Bundle-Activator>
+                  org.apache.felix.upnp.basedriver.Activator
+                </Bundle-Activator>
+                <Bundle-Vendor>
+                  Apache Software Foundation
+                </Bundle-Vendor>
+                <Bundle-Author>
+                  <![CDATA[Matteo Demuru <demuru@apache.org>,Francesco Furfari <furfari@apache.org>,Stefano "Kismet" Lenzi <lenzi@apache.org>]]>
+                </Bundle-Author>
+                <Bundle-Description>
+                  A Bundle implementation of the UPnP Service
+                  Specification R4
+                </Bundle-Description>
+                <Bundle-SymbolicName>
+                  org.apache.felix.upnp.basedriver
+                </Bundle-SymbolicName>
+                <!--Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>

+                  <Embed-Transitive>true</Embed-Transitive-->
+                <Export-Package>
+                  org.apache.felix.upnp.basedriver.controller.*,

+                  org.apache.felix.upnp.basedriver.util.*,

+                  org.apache.xerces.impl.dv.util.*

+                  

+                </Export-Package>
+                <Import-Package>org.osgi.*</Import-Package>
+                <Private-Package>
+                  org.apache.felix.upnp.basedriver.*, org.kxml2.io,
+                  org.xmlpull.v1, org.cybergarage.*
+                </Private-Package>
+              </instructions>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
     </profile>
 
     <profile>
@@ -86,45 +103,57 @@
       <activation>
         <activeByDefault>true</activeByDefault>
       </activation>
-  <dependencies>
-    <dependency>
-      <groupId>it.cnr.isti.domoware.cyberdomo</groupId>
-      <artifactId>upnp-stack</artifactId>
-      <version>1.8.0-SNAPSHOT</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <version>1.1.0-SNAPSHOT</version>
-        <extensions>true</extensions>
-        <configuration>
-          <instructions>
-            <Bundle-Name>${pom.name}</Bundle-Name>
-            <Bundle-Activator>org.apache.felix.upnp.basedriver.Activator</Bundle-Activator>
-            <Bundle-Vendor>Apache Software Foundation</Bundle-Vendor>
-            <Bundle-Author><![CDATA[Matteo Demuru <demuru@apache.org>,Francesco Furfari <furfari@apache.org>,Stefano "Kismet" Lenzi <lenzi@apache.org>]]></Bundle-Author>
-            <Bundle-Description>
-               	A Bundle implementation of the UPnP Service Specification R4
-            </Bundle-Description>
-            <Bundle-SymbolicName>org.apache.felix.upnp.basedriver</Bundle-SymbolicName>
-	    <Export-Package>
-	      org.apache.felix.upnp.extra.*
-	    </Export-Package>
-            <Import-Package>
-              org.osgi.*, javax.xml.parsers, org.w3c.dom, org.xml.sax
-            </Import-Package>
-            <Private-Package>
-              org.apache.felix.upnp.basedriver.*, org.cybergarage.*,org.apache.xerces.impl.dv.util
-            </Private-Package>
-          </instructions>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-
+      <dependencies>
+        <dependency>
+          <groupId>it.cnr.isti.domoware.cyberdomo</groupId>
+          <artifactId>upnp-stack</artifactId>
+          <version>1.8.0-SNAPSHOT</version>
+        </dependency>
+      </dependencies>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>maven-bundle-plugin</artifactId>
+            <version>1.1.0-SNAPSHOT</version>
+            <extensions>true</extensions>
+            <configuration>
+              <instructions>
+                <Bundle-Name>${pom.name}</Bundle-Name>
+                <Bundle-Activator>
+                  org.apache.felix.upnp.basedriver.Activator
+                </Bundle-Activator>
+                <Bundle-Vendor>
+                  Apache Software Foundation
+                </Bundle-Vendor>
+                <Bundle-Author>
+                  <![CDATA[Matteo Demuru <demuru@apache.org>,Francesco Furfari <furfari@apache.org>,Stefano "Kismet" Lenzi <lenzi@apache.org>]]>
+                </Bundle-Author>
+                <Bundle-Description>
+                  A Bundle implementation of the UPnP Service
+                  Specification R4
+                </Bundle-Description>
+                <Bundle-SymbolicName>
+                  org.apache.felix.upnp.basedriver
+                </Bundle-SymbolicName>
+                <Export-Package>
+                  org.apache.felix.upnp.basedriver.controller.*,

+                  org.apache.felix.upnp.basedriver.util.*,

+                  org.apache.xerces.impl.dv.util.*

+                </Export-Package>
+                <Import-Package>
+                  org.osgi.*, javax.xml.parsers, org.w3c.dom,
+                  org.xml.sax
+                </Import-Package>
+                <Private-Package>
+                  org.apache.felix.upnp.basedriver.*,
+                  org.cybergarage.*
+                </Private-Package>
+              </instructions>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
     </profile>
   </profiles>
 
@@ -142,10 +171,5 @@
       <version>0.9.0-SNAPSHOT</version>
       <scope>provided</scope>
     </dependency>
-    <dependency>
-      <groupId>org.apache.felix</groupId>
-      <artifactId>org.apache.felix.upnp.extra</artifactId>
-      <version>0.3.0-SNAPSHOT</version>      
-    </dependency>
   </dependencies>
 </project>
diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/Activator.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/Activator.java
index 63bc6de..284de3b 100644
--- a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/Activator.java
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/Activator.java
@@ -25,6 +25,8 @@
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 
+import org.apache.felix.upnp.basedriver.controller.DevicesInfo;
+import org.apache.felix.upnp.basedriver.controller.DriverController;
 import org.apache.felix.upnp.basedriver.controller.impl.DriverControllerImpl;
 import org.apache.felix.upnp.basedriver.export.RootDeviceExportingQueue;
 import org.apache.felix.upnp.basedriver.export.RootDeviceListener;
@@ -36,8 +38,6 @@
 import org.apache.felix.upnp.basedriver.importer.core.event.thread.Notifier;
 import org.apache.felix.upnp.basedriver.importer.core.event.thread.SubScriber;
 import org.apache.felix.upnp.basedriver.tool.Logger;
-import org.apache.felix.upnp.extra.controller.DevicesInfo;
-import org.apache.felix.upnp.extra.controller.DriverController;
 
 /* 
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/controller/DevicesInfo.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/controller/DevicesInfo.java
new file mode 100644
index 0000000..b11d133
--- /dev/null
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/controller/DevicesInfo.java
@@ -0,0 +1,57 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.basedriver.controller;
+
+/* 
+* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+*/
+public interface DevicesInfo{
+    /**
+     * 
+     * Allow you to get the URL that poinr to the XML description of
+     * a device specified by UUID. 
+     * 
+     * @param udn the UUID that identify a device
+     * @return The String that rappresent the URL that point to the description of the Device
+     */
+    public String getLocationURL(String udn);
+    
+    /**
+     * 
+     * Allow you to get the URL that poinr to the XML description of
+     * a service specified by ServiceId and UUID of the device that 
+     * contain the service 
+     * 
+     * @param udn the UUID of the device that contain the service
+     * @param serviceId the ServiceId of the service
+     * @return The String that rappresent the URL that point to the description of the Service
+     */
+    public String getSCPDURL(String udn,String serviceId);  
+    
+    /**
+     * Allow you to get the absolue URL of a link that is conatin in a device
+     * 
+     * @param udn the UUID of the UPnP Device 
+     * @param link the relative link that you want to resolve
+     * @return The String that rappresent the absolute URL to the resourse specified by link
+     */
+    public String resolveRelativeUrl(String udn, String link);
+    
+}
diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/controller/DriverController.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/controller/DriverController.java
new file mode 100644
index 0000000..176e6e5
--- /dev/null
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/controller/DriverController.java
@@ -0,0 +1,79 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.basedriver.controller;
+
+//import java.net.InetAddress;
+
+/* 
+* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+*/
+public interface DriverController {
+	/**
+	 * String for searching all the device on UPnP Network
+	 */
+    public final static String ALL_DEVICE = "ssdp:all";
+    
+    /**
+     * String for searching only root device on UPnP Network
+     */
+    public final static String ROOT_DEVICE = "upnp:rootdevice";
+    /*
+    public InetAddress[] getBindAddress();
+    
+    public void setBindAddress(InetAddress[] IPs);
+    */
+    
+    /**
+     * Set how much messages should be sent by UPnP Base Driver
+     * for debugging purpose
+     * 
+     * @param n the level of log that you want to set
+     */
+    public void setLogLevel(int n);
+    
+    /**
+     * 
+     * @return the actual value of log level
+     */
+    public int getLogLevel();
+    
+    /**
+     * Set if the message of the UPnP Stack should be reported or not
+     * 
+     * @param b true if you want show messages from UPnP Stack false otherwise 
+     */
+    public void setCyberDebug(boolean b);
+    
+    /**
+     * 
+     * @return true if the reporting of UPnP Stack message is active false otherwise
+     */
+    public boolean getCyberDebug();
+    
+    /**
+     * Sent a search message on the UPnP Network, and refresh the device 
+     * founded by UPnP Base Driver 
+     * 
+     * @param target The SSDP string used for the search
+     */
+    public void search(String target);
+
+
+}
diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/controller/impl/DriverControllerImpl.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/controller/impl/DriverControllerImpl.java
index bcd67e4..f54b4dc 100644
--- a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/controller/impl/DriverControllerImpl.java
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/controller/impl/DriverControllerImpl.java
@@ -25,8 +25,8 @@
 import org.apache.felix.upnp.basedriver.Activator;

 import org.apache.felix.upnp.basedriver.importer.core.MyCtrlPoint;

 import org.apache.felix.upnp.basedriver.tool.Logger;

-import org.apache.felix.upnp.extra.controller.DevicesInfo;

-import org.apache.felix.upnp.extra.controller.DriverController;

+import org.apache.felix.upnp.basedriver.controller.DevicesInfo;

+import org.apache.felix.upnp.basedriver.controller.DriverController;

 

 /* 

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

diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/BuildDevice.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/BuildDevice.java
index 599934d..cd718c4 100644
--- a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/BuildDevice.java
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/BuildDevice.java
@@ -40,7 +40,7 @@
 import org.osgi.service.upnp.UPnPStateVariable;

 

 import org.apache.felix.upnp.basedriver.Activator;

-import org.apache.felix.upnp.extra.util.Converter;

+import org.apache.felix.upnp.basedriver.util.Converter;

 /* 

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

 */

diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/ExporterUPnPEventListener.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/ExporterUPnPEventListener.java
index c463a50..7bea4fd 100644
--- a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/ExporterUPnPEventListener.java
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/ExporterUPnPEventListener.java
@@ -30,7 +30,7 @@
 
 import org.osgi.service.upnp.UPnPEventListener;
 
-import org.apache.felix.upnp.extra.util.Converter;
+import org.apache.felix.upnp.basedriver.util.Converter;
 
 /* 
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/GeneralActionListener.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/GeneralActionListener.java
index 2ecf042..0752ff2 100644
--- a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/GeneralActionListener.java
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/GeneralActionListener.java
@@ -40,7 +40,7 @@
 import org.osgi.service.upnp.UPnPService;
 
 import org.apache.felix.upnp.basedriver.Activator;
-import org.apache.felix.upnp.extra.util.Converter;
+import org.apache.felix.upnp.basedriver.util.Converter;
 
 /* 
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/MyCtrlPoint.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/MyCtrlPoint.java
index 59bc43d..7e5509a 100644
--- a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/MyCtrlPoint.java
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/MyCtrlPoint.java
@@ -65,7 +65,7 @@
 import org.apache.felix.upnp.basedriver.importer.core.upnp.UPnPDeviceImpl;

 import org.apache.felix.upnp.basedriver.importer.core.upnp.UPnPServiceImpl;

 import org.apache.felix.upnp.basedriver.importer.util.ParseUSN;

-import org.apache.felix.upnp.extra.util.Converter;

+import org.apache.felix.upnp.basedriver.util.Converter;

 

 /* 

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

@@ -88,7 +88,7 @@
     private final String EXPORT_FLTR =

         "(" + UPnPDevice.UPNP_EXPORT + "=*" + ")";

     private final String IMPORT_FLTR =

-        "(" + org.apache.felix.upnp.extra.util.Constants.UPNP_IMPORT + "=*" + ")";

+        "(" + org.apache.felix.upnp.basedriver.util.Constants.UPNP_IMPORT + "=*" + ")";

 

     

     public MyCtrlPoint(BundleContext context, SubscriptionQueue subQueue,

diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPActionImpl.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPActionImpl.java
index 40523b9..33b2837 100644
--- a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPActionImpl.java
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPActionImpl.java
@@ -32,7 +32,7 @@
 import org.osgi.service.upnp.UPnPException;

 import org.osgi.service.upnp.UPnPStateVariable;

 

-import org.apache.felix.upnp.extra.util.Converter;

+import org.apache.felix.upnp.basedriver.util.Converter;

 

 /* 

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

diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPStateVariableImpl.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPStateVariableImpl.java
index eac590d..e5b5f8d 100644
--- a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPStateVariableImpl.java
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPStateVariableImpl.java
@@ -29,7 +29,7 @@
 

 import org.osgi.service.upnp.UPnPStateVariable;

 

-import org.apache.felix.upnp.extra.util.Converter;

+import org.apache.felix.upnp.basedriver.util.Converter;

 

 /* 

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

diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/DeviceSetup.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/DeviceSetup.java
index ccb6ec4..e24e043 100644
--- a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/DeviceSetup.java
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/DeviceSetup.java
@@ -38,7 +38,7 @@
 

 import org.apache.felix.upnp.basedriver.importer.core.upnp.UPnPIconImpl;

 import org.apache.felix.upnp.basedriver.importer.core.upnp.UPnPServiceImpl;

-import org.apache.felix.upnp.extra.util.Constants;

+import org.apache.felix.upnp.basedriver.util.Constants;

 

 /* 

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

diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/util/Constants.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/util/Constants.java
new file mode 100644
index 0000000..133f4d2
--- /dev/null
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/util/Constants.java
@@ -0,0 +1,32 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.basedriver.util;
+/* 
+* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+*/
+public interface Constants {
+	/**
+	 * If this property is set on a UPnP Device means that the 
+	 * device service is been created by UPnP base Driver. <br>
+	 * The value of the does not carry any mean. <br>
+	 * The name of the property is "UPnP.device.import".
+	 */
+	public static final String UPNP_IMPORT = "UPnP.device.imported"; 
+}
diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/util/Converter.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/util/Converter.java
new file mode 100644
index 0000000..21a155b
--- /dev/null
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/util/Converter.java
@@ -0,0 +1,254 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.basedriver.util;

+

+import java.text.ParseException;

+import java.text.ParsePosition;

+import java.text.SimpleDateFormat;

+import java.util.Calendar;

+import java.util.Date;

+import java.util.TimeZone;

+

+import org.apache.xerces.impl.dv.util.Base64;

+import org.apache.xerces.impl.dv.util.HexBin;

+

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

+

+/** 

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

+*/

+public class Converter {

+	

+	/**

+	 * 

+	 * @param value Object that contain the value

+	 * @param upnpType String conating the UPnP Type of the Object

+	 * @return a String that contain the UPnP rappresentation of the value contained in Object

+	 * 		of type specified by typeUPnP

+	 */

+	public static String toString(Object value,String upnpType) throws Exception{

+		if((value==null)||(upnpType==null))

+			throw new NullPointerException("Must be specified a valid value and upnpType");

+		

+		if(value instanceof Number){

+			if(value instanceof Integer){

+				return value.toString();

+			}else if(value instanceof Float){

+				return value.toString();

+			}else if(value instanceof Long){

+				if(upnpType.equals(UPnPStateVariable.TYPE_TIME)){

+					long l = ((Long)value).longValue();

+					if(l<0) throw new IllegalArgumentException(l+ "Must be greater than 0");

+					Calendar c = Calendar.getInstance();

+					c.set(Calendar.HOUR_OF_DAY,(int) (l/3600000));					

+					int x=(int) (l % 3600000);

+					c.set(Calendar.MINUTE,(int) (x / 60000));

+					c.set(Calendar.SECOND,(x % 60000)/1000);

+					SimpleDateFormat sdt = new SimpleDateFormat("HH:mm:ss");

+					return sdt.format(c.getTime());

+				}else if(upnpType.equals(UPnPStateVariable.TYPE_TIME_TZ)){

+					long l = ((Long)value).longValue();

+					if(l<0) throw new IllegalArgumentException(l+ "Must be greater than 0");

+					Calendar c = Calendar.getInstance();

+					c.set(Calendar.HOUR_OF_DAY,(int) (l/3600000));					

+					int x=(int) (l % 3600000);

+					c.set(Calendar.MINUTE,(int) (x / 60000));

+					c.set(Calendar.SECOND,(x % 60000)/1000);

+					SimpleDateFormat sdt = new SimpleDateFormat("HH:mm:ssZ");

+					return sdt.format(c.getTime());

+				}else{

+					//Must be UPnPStateVariable.TYPE_UI4)

+					return value.toString();

+				}

+			}else if(value instanceof Double){

+				if(upnpType.equals(UPnPStateVariable.TYPE_FIXED_14_4)){

+					return Long.toString(((Double)value).longValue())+"."+

+						Integer.toString((int) (((((Double)value).doubleValue()*10000D) % 10000)));  

+				}else{

+					//Must be UPnPStateVariable.TYPE_R8 or UPnPStateVariable.TYPE_NUMBER

+					return value.toString();

+				}

+			}

+		}else if(value instanceof Date){

+			if(upnpType.equals("dateTime")){

+				SimpleDateFormat sdt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");

+				return sdt.format(value);				

+			}else if(upnpType.equals("dateTime.tz")){

+				SimpleDateFormat sdt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");

+				return sdt.format(value);								

+			}else if(upnpType.equals("date")){

+				SimpleDateFormat sdt = new SimpleDateFormat("yyyy-MM-dd");

+				return sdt.format(value);

+			}

+		}else if(value instanceof Boolean){

+			//Must be UPnPStateVariable.TYPE_BOOLEAN

+			if(((Boolean)value).booleanValue()){

+				return "1";

+			}else{

+				return "0";

+			}

+		}else if(value instanceof Character){

+			//Must be UPnPStateVariable.TYPE_CHAR

+			return value.toString();

+		}else if(value instanceof String){

+			return value.toString();

+			//Must be one of 

+			//	UPnPStateVariable.TYPE_STRING or 

+			//	UPnPStateVariable.TYPE_URI or 

+			//	UPnPStateVariable.TYPE_UUID

+		}else if(value instanceof byte[]){

+			if(upnpType.equals("bin.hex")){

+				return HexBin.encode((byte[]) value);				

+			}else if(upnpType.equals("bin.base64")){

+				return Base64.encode((byte[]) value);

+			}

+		}

+		throw new IllegalArgumentException("Invalid Binding");

+	}

+	

+	/**

+	 * 

+	 * @param value

+	 * @param upnpType

+	 * @return

+	 */

+	public static Object parseString(String value,String upnpType) throws Exception{

+		if (value ==null && upnpType.equals("string"))

+                value = "";

+        if((value==null)||(upnpType==null))

+				throw new NullPointerException("Must be specified a valid value and upnpType");

+		

+		if (upnpType.equals("ui1") || upnpType.equals("ui2")

+				|| upnpType.equals("i1") || upnpType.equals("i2")

+				|| upnpType.equals("i4") || upnpType.equals("int")) {

+			

+			return new Integer(value);

+		} else if (upnpType.equals("ui4")){			

+			return new Long(value);

+		} else if(upnpType.equals("time")){

+			String[] timeFormats=new String[]{"HH:mm:ss"};

+			Date d=getDateValue(value,timeFormats,timeFormats);

+			

+			Calendar c = Calendar.getInstance();

+			c.setTime(d);

+			return new Long(

+					c.get(Calendar.HOUR_OF_DAY)*3600000

+					+c.get(Calendar.MINUTE)*60000

+					+c.get(Calendar.SECOND)*1000

+			);

+		} else if(upnpType.equals("time.tz")) {

+			String[] timeFormats=new String[]{"HH:mm:ssZ","HH:mm:ss"};

+			Date d=getDateValue(value,timeFormats,timeFormats);

+			TimeZone tz = TimeZone.getDefault();			

+			Calendar c = Calendar.getInstance(tz);

+			c.setTime(d);

+			

+			if(timeFormats[0].equals("HH:mm:ssZ")&&(tz.inDaylightTime(d)))

+				c.add(Calendar.MILLISECOND,3600000);

+			return new Long(

+					c.get(Calendar.HOUR_OF_DAY)*3600000

+					+c.get(Calendar.MINUTE)*60000

+					+c.get(Calendar.SECOND)*1000					

+			);

+		} else if (upnpType.equals("r4") || upnpType.equals("float")) {				

+			return new Float(value);

+		} else if (upnpType.equals("r8") || upnpType.equals("number")

+			|| upnpType.equals("fixed.14.4")){			

+			return new Double(value);

+		} else if (upnpType.equals("char")) {			

+			return new Character(value.charAt(0));

+		} else if (upnpType.equals("string") || upnpType.equals("uri")

+				|| upnpType.equals("uuid")) {			

+			return value;

+		} else if (upnpType.equals("date")) {

+			String[] timeFormats=new String[]{"yyyy-MM-dd"};

+			

+			Date d=getDateValue(value,timeFormats,timeFormats);

+			return d;			

+		} else if (upnpType.equals("dateTime")) {

+			

+			String[] timeFormats=new String[]{

+					"yyyy-MM-dd",

+					"yyyy-MM-dd'T'HH:mm:ss"

+			};

+			

+			Date d=getDateValue(value,timeFormats,timeFormats);

+			return d;

+		} else if (upnpType.equals("dateTime.tz")) {

+			

+			String[] timeFormats=new String[]{

+					"yyyy-MM-dd",

+					"yyyy-MM-dd'T'HH:mm:ss",

+					"yyyy-MM-dd'T'HH:mm:ssZ"

+			};

+			

+			Date d=getDateValue(value,timeFormats,timeFormats);

+			return d;			

+		} else if (upnpType.equals("boolean")) {

+			if(value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("true")

+			|| value.equalsIgnoreCase("1"))

+				return new Boolean(true);

+			else

+				return new Boolean(false);					

+		} else if (upnpType.equals("bin.base64")) {

+			return Base64.decode(value);

+		} else if (upnpType.equals("bin.hex")) {

+			return HexBin.decode(value);

+		}

+		throw new IllegalArgumentException("Invalid Binding");		

+	}

+	

+	private static String normalizeTimeZone(String value){

+		if(value.endsWith("Z")){

+			value=value.substring(0,value.length()-1)+"+0000";

+		}else if((value.length()>7)

+			&&(value.charAt(value.length()-3)==':')

+			&&((value.charAt(value.length()-6)=='-')||(value.charAt(value.length()-6)=='+'))){

+			

+			value=value.substring(0,value.length()-3)+value.substring(value.length()-2);

+		}		

+		return value;

+	}

+	

+	/**

+	 * @param value

+	 * @param timeFormats

+	 * @param choosedIndex

+	 * @return

+	 * @throws ParseException

+	 */

+	private static Date getDateValue(String value, String[] timeFormats, String[] choosedIndex) throws ParseException {

+		ParsePosition position = null;

+		Date d;

+		value=normalizeTimeZone(value);

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

+			position =  new ParsePosition(0);

+			SimpleDateFormat  sdt = new SimpleDateFormat(timeFormats[i]);

+			d=sdt.parse(value,position);

+			if(d!=null){

+				if(position.getIndex()>=value.length()){

+					choosedIndex[0]=timeFormats[i];

+					return d;			

+				}

+			}

+		}

+		throw new ParseException("Error parsing "+value,position.getIndex());

+	}

+}

diff --git a/upnp/basedriver/src/main/java/org/apache/xerces/impl/dv/util/Base64.java b/upnp/basedriver/src/main/java/org/apache/xerces/impl/dv/util/Base64.java
new file mode 100644
index 0000000..8a15e63
--- /dev/null
+++ b/upnp/basedriver/src/main/java/org/apache/xerces/impl/dv/util/Base64.java
@@ -0,0 +1,307 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.xerces.impl.dv.util;
+
+/**
+ * This class provides encode/decode for RFC 2045 Base64 as
+ * defined by RFC 2045, N. Freed and N. Borenstein.
+ * RFC 2045: Multipurpose Internet Mail Extensions (MIME)
+ * Part One: Format of Internet Message Bodies. Reference
+ * 1996 Available at: http://www.ietf.org/rfc/rfc2045.txt
+ * This class is used by XML Schema binary format validation
+ *
+ * This implementation does not encode/decode streaming
+ * data. You need the data that you will encode/decode
+ * already on a byte arrray.
+ *
+ * @xerces.internal 
+ *
+ * @author Jeffrey Rodriguez
+ * @author Sandy Gao
+ * @version $Id: Base64.java,v 1.15 2004/10/14 15:20:18 mrglavas Exp $
+ */
+public final class  Base64 {
+
+    static private final int  BASELENGTH         = 128;
+    static private final int  LOOKUPLENGTH       = 64;
+    static private final int  TWENTYFOURBITGROUP = 24;
+    static private final int  EIGHTBIT           = 8;
+    static private final int  SIXTEENBIT         = 16;
+    static private final int  SIXBIT             = 6;
+    static private final int  FOURBYTE           = 4;
+    static private final int  SIGN               = -128;
+    static private final char PAD                = '=';
+    static private final boolean fDebug          = false;
+    static final private byte [] base64Alphabet        = new byte[BASELENGTH];
+    static final private char [] lookUpBase64Alphabet  = new char[LOOKUPLENGTH];
+
+    static {
+
+        for (int i = 0; i < BASELENGTH; ++i) {
+            base64Alphabet[i] = -1;
+        }
+        for (int i = 'Z'; i >= 'A'; i--) {
+            base64Alphabet[i] = (byte) (i-'A');
+        }
+        for (int i = 'z'; i>= 'a'; i--) {
+            base64Alphabet[i] = (byte) ( i-'a' + 26);
+        }
+
+        for (int i = '9'; i >= '0'; i--) {
+            base64Alphabet[i] = (byte) (i-'0' + 52);
+        }
+
+        base64Alphabet['+']  = 62;
+        base64Alphabet['/']  = 63;
+
+        for (int i = 0; i<=25; i++)
+            lookUpBase64Alphabet[i] = (char)('A'+i);
+
+        for (int i = 26,  j = 0; i<=51; i++, j++)
+            lookUpBase64Alphabet[i] = (char)('a'+ j);
+
+        for (int i = 52,  j = 0; i<=61; i++, j++)
+            lookUpBase64Alphabet[i] = (char)('0' + j);
+        lookUpBase64Alphabet[62] = (char)'+';
+        lookUpBase64Alphabet[63] = (char)'/';
+
+    }
+
+    protected static boolean isWhiteSpace(char octect) {
+        return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
+    }
+
+    protected static boolean isPad(char octect) {
+        return (octect == PAD);
+    }
+
+    protected static boolean isData(char octect) {
+        return (octect < BASELENGTH && base64Alphabet[octect] != -1);
+    }
+
+    protected static boolean isBase64(char octect) {
+        return (isWhiteSpace(octect) || isPad(octect) || isData(octect));
+    }
+
+    /**
+     * Encodes hex octects into Base64
+     *
+     * @param binaryData Array containing binaryData
+     * @return Encoded Base64 array
+     */
+    public static String encode(byte[] binaryData) {
+
+        if (binaryData == null)
+            return null;
+
+        int      lengthDataBits    = binaryData.length*EIGHTBIT;
+        if (lengthDataBits == 0) {
+            return "";
+        }
+        
+        int      fewerThan24bits   = lengthDataBits%TWENTYFOURBITGROUP;
+        int      numberTriplets    = lengthDataBits/TWENTYFOURBITGROUP;
+        int      numberQuartet     = fewerThan24bits != 0 ? numberTriplets+1 : numberTriplets;
+        char     encodedData[]     = null;
+
+        encodedData = new char[numberQuartet*4];
+
+        byte k=0, l=0, b1=0,b2=0,b3=0;
+
+        int encodedIndex = 0;
+        int dataIndex   = 0;
+        if (fDebug) {
+            System.out.println("number of triplets = " + numberTriplets );
+        }
+
+        for (int i=0; i<numberTriplets; i++) {
+            b1 = binaryData[dataIndex++];
+            b2 = binaryData[dataIndex++];
+            b3 = binaryData[dataIndex++];
+
+            if (fDebug) {
+                System.out.println( "b1= " + b1 +", b2= " + b2 + ", b3= " + b3 );
+            }
+
+            l  = (byte)(b2 & 0x0f);
+            k  = (byte)(b1 & 0x03);
+
+            byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
+
+            byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0);
+            byte val3 = ((b3 & SIGN)==0)?(byte)(b3>>6):(byte)((b3)>>6^0xfc);
+
+            if (fDebug) {
+                System.out.println( "val2 = " + val2 );
+                System.out.println( "k4   = " + (k<<4));
+                System.out.println( "vak  = " + (val2 | (k<<4)));
+            }
+
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[ val2 | ( k<<4 )];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[ (l <<2 ) | val3 ];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[ b3 & 0x3f ];
+        }
+
+        // form integral number of 6-bit groups
+        if (fewerThan24bits == EIGHTBIT) {
+            b1 = binaryData[dataIndex];
+            k = (byte) ( b1 &0x03 );
+            if (fDebug) {
+                System.out.println("b1=" + b1);
+                System.out.println("b1<<2 = " + (b1>>2) );
+            }
+            byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[ k<<4 ];
+            encodedData[encodedIndex++] = PAD;
+            encodedData[encodedIndex++] = PAD;
+        } else if (fewerThan24bits == SIXTEENBIT) {
+            b1 = binaryData[dataIndex];
+            b2 = binaryData[dataIndex +1 ];
+            l = ( byte ) ( b2 &0x0f );
+            k = ( byte ) ( b1 &0x03 );
+
+            byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
+            byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0);
+
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[ val2 | ( k<<4 )];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[ l<<2 ];
+            encodedData[encodedIndex++] = PAD;
+        }
+
+        return new String(encodedData);
+    }
+
+    /**
+     * Decodes Base64 data into octects
+     *
+     * @param encoded string containing Base64 data
+     * @return Array containind decoded data.
+     */
+    public static byte[] decode(String encoded) {
+
+        if (encoded == null)
+            return null;
+
+        char[] base64Data = encoded.toCharArray();
+        // remove white spaces
+        int len = removeWhiteSpace(base64Data);
+        
+        if (len%FOURBYTE != 0) {
+            return null;//should be divisible by four
+        }
+
+        int      numberQuadruple    = (len/FOURBYTE );
+
+        if (numberQuadruple == 0)
+            return new byte[0];
+
+        byte     decodedData[]      = null;
+        byte     b1=0,b2=0,b3=0,b4=0;
+        char     d1=0,d2=0,d3=0,d4=0;
+
+        int i = 0;
+        int encodedIndex = 0;
+        int dataIndex    = 0;
+        decodedData      = new byte[ (numberQuadruple)*3];
+
+        for (; i<numberQuadruple-1; i++) {
+
+            if (!isData( (d1 = base64Data[dataIndex++]) )||
+                !isData( (d2 = base64Data[dataIndex++]) )||
+                !isData( (d3 = base64Data[dataIndex++]) )||
+                !isData( (d4 = base64Data[dataIndex++]) ))
+                return null;//if found "no data" just return null
+
+            b1 = base64Alphabet[d1];
+            b2 = base64Alphabet[d2];
+            b3 = base64Alphabet[d3];
+            b4 = base64Alphabet[d4];
+
+            decodedData[encodedIndex++] = (byte)(  b1 <<2 | b2>>4 ) ;
+            decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
+            decodedData[encodedIndex++] = (byte)( b3<<6 | b4 );
+        }
+
+        if (!isData( (d1 = base64Data[dataIndex++]) ) ||
+            !isData( (d2 = base64Data[dataIndex++]) )) {
+            return null;//if found "no data" just return null
+        }
+
+        b1 = base64Alphabet[d1];
+        b2 = base64Alphabet[d2];
+
+        d3 = base64Data[dataIndex++];
+        d4 = base64Data[dataIndex++];
+        if (!isData( (d3 ) ) ||
+            !isData( (d4 ) )) {//Check if they are PAD characters
+            if (isPad( d3 ) && isPad( d4)) {               //Two PAD e.g. 3c[Pad][Pad]
+                if ((b2 & 0xf) != 0)//last 4 bits should be zero
+                    return null;
+                byte[] tmp = new byte[ i*3 + 1 ];
+                System.arraycopy( decodedData, 0, tmp, 0, i*3 );
+                tmp[encodedIndex]   = (byte)(  b1 <<2 | b2>>4 ) ;
+                return tmp;
+            } else if (!isPad( d3) && isPad(d4)) {               //One PAD  e.g. 3cQ[Pad]
+                b3 = base64Alphabet[ d3 ];
+                if ((b3 & 0x3 ) != 0)//last 2 bits should be zero
+                    return null;
+                byte[] tmp = new byte[ i*3 + 2 ];
+                System.arraycopy( decodedData, 0, tmp, 0, i*3 );
+                tmp[encodedIndex++] = (byte)(  b1 <<2 | b2>>4 );
+                tmp[encodedIndex]   = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
+                return tmp;
+            } else {
+                return null;//an error  like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
+            }
+        } else { //No PAD e.g 3cQl
+            b3 = base64Alphabet[ d3 ];
+            b4 = base64Alphabet[ d4 ];
+            decodedData[encodedIndex++] = (byte)(  b1 <<2 | b2>>4 ) ;
+            decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
+            decodedData[encodedIndex++] = (byte)( b3<<6 | b4 );
+
+        }
+
+        return decodedData;
+    }
+
+    /**
+     * remove WhiteSpace from MIME containing encoded Base64 data.
+     * 
+     * @param data  the byte array of base64 data (with WS)
+     * @return      the new length
+     */
+    protected static int removeWhiteSpace(char[] data) {
+        if (data == null)
+            return 0;
+
+        // count characters that's not whitespace
+        int newSize = 0;
+        int len = data.length;
+        for (int i = 0; i < len; i++) {
+            if (!isWhiteSpace(data[i]))
+                data[newSize++] = data[i];
+        }
+        return newSize;
+    }
+}
diff --git a/upnp/basedriver/src/main/java/org/apache/xerces/impl/dv/util/HexBin.java b/upnp/basedriver/src/main/java/org/apache/xerces/impl/dv/util/HexBin.java
new file mode 100644
index 0000000..8a9249d
--- /dev/null
+++ b/upnp/basedriver/src/main/java/org/apache/xerces/impl/dv/util/HexBin.java
@@ -0,0 +1,115 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.xerces.impl.dv.util;
+
+/**
+ * format validation
+ *
+ * This class encodes/decodes hexadecimal data
+ * 
+ * @xerces.internal  
+ * 
+ * @author Jeffrey Rodriguez
+ * @version $Id: HexBin.java,v 1.13 2004/10/14 15:20:18 mrglavas Exp $
+ */
+public final class  HexBin {
+    static private final int  BASELENGTH   = 128;
+    static private final int  LOOKUPLENGTH = 16;
+    static final private byte [] hexNumberTable    = new byte[BASELENGTH];
+    static final private char [] lookUpHexAlphabet = new char[LOOKUPLENGTH];
+
+
+    static {
+        for (int i = 0; i < BASELENGTH; i++ ) {
+            hexNumberTable[i] = -1;
+        }
+        for ( int i = '9'; i >= '0'; i--) {
+            hexNumberTable[i] = (byte) (i-'0');
+        }
+        for ( int i = 'F'; i>= 'A'; i--) {
+            hexNumberTable[i] = (byte) ( i-'A' + 10 );
+        }
+        for ( int i = 'f'; i>= 'a'; i--) {
+           hexNumberTable[i] = (byte) ( i-'a' + 10 );
+        }
+
+        for(int i = 0; i<10; i++ ) {
+            lookUpHexAlphabet[i] = (char)('0'+i);
+        }
+        for(int i = 10; i<=15; i++ ) {
+            lookUpHexAlphabet[i] = (char)('A'+i -10);
+        }
+    }
+
+    /**
+     * Encode a byte array to hex string
+     *
+     * @param binaryData array of byte to encode
+     * @return return encoded string
+     */
+    static public String encode(byte[] binaryData) {
+        if (binaryData == null)
+            return null;
+        int lengthData   = binaryData.length;
+        int lengthEncode = lengthData * 2;
+        char[] encodedData = new char[lengthEncode];
+        int temp;
+        for (int i = 0; i < lengthData; i++) {
+            temp = binaryData[i];
+            if (temp < 0)
+                temp += 256;
+            encodedData[i*2] = lookUpHexAlphabet[temp >> 4];
+            encodedData[i*2+1] = lookUpHexAlphabet[temp & 0xf];
+        }
+        return new String(encodedData);
+    }
+
+    /**
+     * Decode hex string to a byte array
+     *
+     * @param encoded encoded string
+     * @return return array of byte to encode
+     */
+    static public byte[] decode(String encoded) {
+        if (encoded == null)
+            return null;
+        int lengthData = encoded.length();
+        if (lengthData % 2 != 0)
+            return null;
+
+        char[] binaryData = encoded.toCharArray();
+        int lengthDecode = lengthData / 2;
+        byte[] decodedData = new byte[lengthDecode];
+        byte temp1, temp2;
+        char tempChar;
+        for( int i = 0; i<lengthDecode; i++ ){
+            tempChar = binaryData[i*2];
+            temp1 = (tempChar < BASELENGTH) ? hexNumberTable[tempChar] : -1;
+            if (temp1 == -1)
+                return null;
+            tempChar = binaryData[i*2+1];
+            temp2 = (tempChar < BASELENGTH) ? hexNumberTable[tempChar] : -1;
+            if (temp2 == -1)
+                return null;
+            decodedData[i] = (byte)((temp1 << 4) | temp2);
+        }
+        return decodedData;
+    }
+}