diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..fdbefb2
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,25 @@
+# Copyright 2011, The Android Open Source Project
+#
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := JmDNS
+LOCAL_MODULE_TAGS := optional
+LOCAL_SDK_VERSION := 8
+
+LOCAL_SRC_FILES := \
+    $(call all-java-files-under, src) \
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..8d1c8b6
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
@@ -0,0 +1 @@
+ 
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
diff --git a/README.android b/README.android
new file mode 100644
index 0000000..8190073
--- /dev/null
+++ b/README.android
@@ -0,0 +1,4 @@
+URL: http://jmdns.sourceforge.net/
+Version: this is a snapshot of the JmDNS tree between version 3.4.1 and 3.4.2
+License: Apache 2
+Description: "JmDNS is a Java implementation of multi-cast DNS"
diff --git a/src/javax/jmdns/JmDNS.java b/src/javax/jmdns/JmDNS.java
new file mode 100644
index 0000000..1c3285c
--- /dev/null
+++ b/src/javax/jmdns/JmDNS.java
@@ -0,0 +1,433 @@
+// /Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.Collection;
+import java.util.Map;
+
+import javax.jmdns.impl.JmDNSImpl;
+
+/**
+ * mDNS implementation in Java.
+ *
+ * @author Arthur van Hoff, Rick Blair, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Scott Lewis, Scott Cytacki
+ */
+public abstract class JmDNS implements Closeable {
+
+    /**
+     *
+     */
+    public static interface Delegate {
+
+        /**
+         * This method is called if JmDNS cannot recover from an I/O error.
+         *
+         * @param dns
+         *            target DNS
+         * @param infos
+         *            service info registered with the DNS
+         */
+        public void cannotRecoverFromIOError(JmDNS dns, Collection<ServiceInfo> infos);
+
+    }
+
+    /**
+     * The version of JmDNS.
+     */
+    public static final String VERSION = "3.4.2";
+
+    /**
+     * <p>
+     * Create an instance of JmDNS.
+     * </p>
+     * <p>
+     * <b>Note:</b> This is a convenience method. The preferred constructor is {@link #create(InetAddress, String)}.<br/>
+     * Check that your platform correctly handle the default localhost IP address and the local hostname. In doubt use the explicit constructor.<br/>
+     * This call is equivalent to <code>create(null, null)</code>.
+     * </p>
+     *
+     * @see #create(InetAddress, String)
+     * @return jmDNS instance
+     * @exception IOException
+     *                if an exception occurs during the socket creation
+     */
+    public static JmDNS create() throws IOException {
+        return new JmDNSImpl(null, null);
+    }
+
+    /**
+     * <p>
+     * Create an instance of JmDNS and bind it to a specific network interface given its IP-address.
+     * </p>
+     * <p>
+     * <b>Note:</b> This is a convenience method. The preferred constructor is {@link #create(InetAddress, String)}.<br/>
+     * Check that your platform correctly handle the default localhost IP address and the local hostname. In doubt use the explicit constructor.<br/>
+     * This call is equivalent to <code>create(addr, null)</code>.
+     * </p>
+     *
+     * @see #create(InetAddress, String)
+     * @param addr
+     *            IP address to bind to.
+     * @return jmDNS instance
+     * @exception IOException
+     *                if an exception occurs during the socket creation
+     */
+    public static JmDNS create(final InetAddress addr) throws IOException {
+        return new JmDNSImpl(addr, null);
+    }
+
+    /**
+     * <p>
+     * Create an instance of JmDNS.
+     * </p>
+     * <p>
+     * <b>Note:</b> This is a convenience method. The preferred constructor is {@link #create(InetAddress, String)}.<br/>
+     * Check that your platform correctly handle the default localhost IP address and the local hostname. In doubt use the explicit constructor.<br/>
+     * This call is equivalent to <code>create(null, name)</code>.
+     * </p>
+     *
+     * @see #create(InetAddress, String)
+     * @param name
+     *            name of the newly created JmDNS
+     * @return jmDNS instance
+     * @exception IOException
+     *                if an exception occurs during the socket creation
+     */
+    public static JmDNS create(final String name) throws IOException {
+        return new JmDNSImpl(null, name);
+    }
+
+    /**
+     * <p>
+     * Create an instance of JmDNS and bind it to a specific network interface given its IP-address.
+     * </p>
+     * If <code>addr</code> parameter is null this method will try to resolve to a local IP address of the machine using a network discovery:
+     * <ol>
+     * <li>Check the system property <code>net.mdns.interface</code></li>
+     * <li>Check the JVM local host</li>
+     * <li>Use the {@link NetworkTopologyDiscovery} to find a valid network interface and IP.</li>
+     * <li>In the last resort bind to the loopback address. This is non functional in most cases.</li>
+     * </ol>
+     * If <code>name</code> parameter is null will use the hostname. The hostname is determined by the following algorithm:
+     * <ol>
+     * <li>Get the hostname from the InetAdress obtained before.</li>
+     * <li>If the hostname is a reverse lookup default to <code>JmDNS name</code> or <code>computer</code> if null.</li>
+     * <li>If the name contains <code>'.'</code> replace them by <code>'-'</code></li>
+     * <li>Add <code>.local.</code> at the end of the name.</li>
+     * </ol>
+     * <p>
+     * <b>Note:</b> If you need to use a custom {@link NetworkTopologyDiscovery} it must be setup before any call to this method. This is done by setting up a {@link NetworkTopologyDiscovery.Factory.ClassDelegate} and installing it using
+     * {@link NetworkTopologyDiscovery.Factory#setClassDelegate(NetworkTopologyDiscovery.Factory.ClassDelegate)}. This must be done before creating a {@link JmDNS} or {@link JmmDNS} instance.
+     * </p>
+     *
+     * @param addr
+     *            IP address to bind to.
+     * @param name
+     *            name of the newly created JmDNS
+     * @return jmDNS instance
+     * @exception IOException
+     *                if an exception occurs during the socket creation
+     */
+    public static JmDNS create(final InetAddress addr, final String name) throws IOException {
+        return new JmDNSImpl(addr, name);
+    }
+
+    /**
+     * Return the name of the JmDNS instance. This is an arbitrary string that is useful for distinguishing instances.
+     *
+     * @return name of the JmDNS
+     */
+    public abstract String getName();
+
+    /**
+     * Return the HostName associated with this JmDNS instance. Note: May not be the same as what started. The host name is subject to negotiation.
+     *
+     * @return Host name
+     */
+    public abstract String getHostName();
+
+    /**
+     * Return the address of the interface to which this instance of JmDNS is bound.
+     *
+     * @return Internet Address
+     * @exception IOException
+     *                if there is an error in the underlying protocol, such as a TCP error.
+     */
+    public abstract InetAddress getInetAddress() throws IOException;
+
+    /**
+     * Return the address of the interface to which this instance of JmDNS is bound.
+     *
+     * @return Internet Address
+     * @exception IOException
+     *                if there is an error in the underlying protocol, such as a TCP error.
+     * @deprecated do not use this implementation yields unpredictable results use {@link #getInetAddress()}
+     */
+    @Deprecated
+    public abstract InetAddress getInterface() throws IOException;
+
+    /**
+     * Get service information. If the information is not cached, the method will block until updated information is received.
+     * <p/>
+     * Usage note: Do not call this method from the AWT event dispatcher thread. You will make the user interface unresponsive.
+     *
+     * @param type
+     *            fully qualified service type, such as <code>_http._tcp.local.</code> .
+     * @param name
+     *            unqualified service name, such as <code>foobar</code> .
+     * @return null if the service information cannot be obtained
+     */
+    public abstract ServiceInfo getServiceInfo(String type, String name);
+
+    /**
+     * Get service information. If the information is not cached, the method will block for the given timeout until updated information is received.
+     * <p/>
+     * Usage note: If you call this method from the AWT event dispatcher thread, use a small timeout, or you will make the user interface unresponsive.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code> .
+     * @param name
+     *            unqualified service name, such as <code>foobar</code> .
+     * @param timeout
+     *            timeout in milliseconds. Typical timeout should be 5s.
+     * @return null if the service information cannot be obtained
+     */
+    public abstract ServiceInfo getServiceInfo(String type, String name, long timeout);
+
+    /**
+     * Get service information. If the information is not cached, the method will block until updated information is received.
+     * <p/>
+     * Usage note: Do not call this method from the AWT event dispatcher thread. You will make the user interface unresponsive.
+     *
+     * @param type
+     *            fully qualified service type, such as <code>_http._tcp.local.</code> .
+     * @param name
+     *            unqualified service name, such as <code>foobar</code> .
+     * @param persistent
+     *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
+     * @return null if the service information cannot be obtained
+     */
+    public abstract ServiceInfo getServiceInfo(String type, String name, boolean persistent);
+
+    /**
+     * Get service information. If the information is not cached, the method will block for the given timeout until updated information is received.
+     * <p/>
+     * Usage note: If you call this method from the AWT event dispatcher thread, use a small timeout, or you will make the user interface unresponsive.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code> .
+     * @param name
+     *            unqualified service name, such as <code>foobar</code> .
+     * @param timeout
+     *            timeout in milliseconds. Typical timeout should be 5s.
+     * @param persistent
+     *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
+     * @return null if the service information cannot be obtained
+     */
+    public abstract ServiceInfo getServiceInfo(String type, String name, boolean persistent, long timeout);
+
+    /**
+     * Request service information. The information about the service is requested and the ServiceListener.resolveService method is called as soon as it is available.
+     * <p/>
+     * Usage note: Do not call this method from the AWT event dispatcher thread. You will make the user interface unresponsive.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code> .
+     * @param name
+     *            unqualified service name, such as <code>foobar</code> .
+     */
+    public abstract void requestServiceInfo(String type, String name);
+
+    /**
+     * Request service information. The information about the service is requested and the ServiceListener.resolveService method is called as soon as it is available.
+     * <p/>
+     * Usage note: Do not call this method from the AWT event dispatcher thread. You will make the user interface unresponsive.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code> .
+     * @param name
+     *            unqualified service name, such as <code>foobar</code> .
+     * @param persistent
+     *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
+     */
+    public abstract void requestServiceInfo(String type, String name, boolean persistent);
+
+    /**
+     * Request service information. The information about the service is requested and the ServiceListener.resolveService method is called as soon as it is available.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code> .
+     * @param name
+     *            unqualified service name, such as <code>foobar</code> .
+     * @param timeout
+     *            timeout in milliseconds
+     */
+    public abstract void requestServiceInfo(String type, String name, long timeout);
+
+    /**
+     * Request service information. The information about the service is requested and the ServiceListener.resolveService method is called as soon as it is available.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code> .
+     * @param name
+     *            unqualified service name, such as <code>foobar</code> .
+     * @param persistent
+     *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
+     * @param timeout
+     *            timeout in milliseconds
+     */
+    public abstract void requestServiceInfo(String type, String name, boolean persistent, long timeout);
+
+    /**
+     * Listen for service types.
+     *
+     * @param listener
+     *            listener for service types
+     * @exception IOException
+     *                if there is an error in the underlying protocol, such as a TCP error.
+     */
+    public abstract void addServiceTypeListener(ServiceTypeListener listener) throws IOException;
+
+    /**
+     * Remove listener for service types.
+     *
+     * @param listener
+     *            listener for service types
+     */
+    public abstract void removeServiceTypeListener(ServiceTypeListener listener);
+
+    /**
+     * Listen for services of a given type. The type has to be a fully qualified type name such as <code>_http._tcp.local.</code>.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code>.
+     * @param listener
+     *            listener for service updates
+     */
+    public abstract void addServiceListener(String type, ServiceListener listener);
+
+    /**
+     * Remove listener for services of a given type.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code>.
+     * @param listener
+     *            listener for service updates
+     */
+    public abstract void removeServiceListener(String type, ServiceListener listener);
+
+    /**
+     * Register a service. The service is registered for access by other jmdns clients. The name of the service may be changed to make it unique.<br>
+     * Note that the given {@code ServiceInfo} is bound to this {@code JmDNS} instance, and should not be reused for any other {@linkplain #registerService(ServiceInfo)}.
+     *
+     * @param info
+     *            service info to register
+     * @exception IOException
+     *                if there is an error in the underlying protocol, such as a TCP error.
+     */
+    public abstract void registerService(ServiceInfo info) throws IOException;
+
+    /**
+     * Unregister a service. The service should have been registered.
+     * <p>
+     * <b>Note:</b> Unregistered services will not disappear form the list of services immediately. According to the specification, when unregistering services we send goodbye packets and then wait <b>1s</b> before purging the cache.<br/>
+     * This is support for shared records that can be rescued by some other cooperation DNS.
+     *
+     * <pre>
+     * Clients receiving a Multicast DNS Response with a TTL of zero SHOULD NOT immediately delete the record from the cache, but instead record a TTL of 1 and then delete the record one second later.
+     * </pre>
+     *
+     * </p>
+     *
+     * @param info
+     *            service info to remove
+     */
+    public abstract void unregisterService(ServiceInfo info);
+
+    /**
+     * Unregister all services.
+     */
+    public abstract void unregisterAllServices();
+
+    /**
+     * Register a service type. If this service type was not already known, all service listeners will be notified of the new service type.
+     * <p>
+     * Service types are automatically registered as they are discovered.
+     * </p>
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code>.
+     * @return <code>true</code> if the type or subtype was added, <code>false</code> if the type was already registered.
+     */
+    public abstract boolean registerServiceType(String type);
+
+    /**
+     * List Services and serviceTypes. Debugging Only
+     *
+     * @deprecated since 3.2.2
+     */
+    @Deprecated
+    public abstract void printServices();
+
+    /**
+     * Returns a list of service infos of the specified type.
+     *
+     * @param type
+     *            Service type name, such as <code>_http._tcp.local.</code>.
+     * @return An array of service instance.
+     */
+    public abstract ServiceInfo[] list(String type);
+
+    /**
+     * Returns a list of service infos of the specified type.
+     *
+     * @param type
+     *            Service type name, such as <code>_http._tcp.local.</code>.
+     * @param timeout
+     *            timeout in milliseconds. Typical timeout should be 6s.
+     * @return An array of service instance.
+     */
+    public abstract ServiceInfo[] list(String type, long timeout);
+
+    /**
+     * Returns a list of service infos of the specified type sorted by subtype. Any service that do not register a subtype is listed in the empty subtype section.
+     *
+     * @param type
+     *            Service type name, such as <code>_http._tcp.local.</code>.
+     * @return A dictionary of service info by subtypes.
+     */
+    public abstract Map<String, ServiceInfo[]> listBySubtype(String type);
+
+    /**
+     * Returns a list of service infos of the specified type sorted by subtype. Any service that do not register a subtype is listed in the empty subtype section.
+     *
+     * @param type
+     *            Service type name, such as <code>_http._tcp.local.</code>.
+     * @param timeout
+     *            timeout in milliseconds. Typical timeout should be 6s.
+     * @return A dictionary of service info by subtypes.
+     */
+    public abstract Map<String, ServiceInfo[]> listBySubtype(String type, long timeout);
+
+    /**
+     * Returns the instance delegate
+     *
+     * @return instance delegate
+     */
+    public abstract Delegate getDelegate();
+
+    /**
+     * Sets the instance delegate
+     *
+     * @param value
+     *            new instance delegate
+     * @return previous instance delegate
+     */
+    public abstract Delegate setDelegate(Delegate value);
+
+}
diff --git a/src/javax/jmdns/JmmDNS.java b/src/javax/jmdns/JmmDNS.java
new file mode 100644
index 0000000..1d4d85a
--- /dev/null
+++ b/src/javax/jmdns/JmmDNS.java
@@ -0,0 +1,407 @@
+/**
+ *
+ */
+package javax.jmdns;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.jmdns.impl.JmmDNSImpl;
+
+/**
+ * <p>
+ * Java Multihomed Multicast DNS
+ * </p>
+ * Uses an underlying {@link JmDNS} instance for each {@link InetAddress} found on this computer.<br/>
+ * This class will monitor network topology changes, and will create or destroy JmDNS instances as required. It is your responsibility to maintain services registration (hint: use a {@link NetworkTopologyListener}).<br/>
+ * Most of this class methods have no notion of transaction: if an Exception is raised in the middle of execution, you may be in an incoherent state.
+ * <p>
+ * <b>Note:</b> This API is experimental and may change in the future please let us know what work and what does not work in you application.
+ * </p>
+ *
+ * @author C&eacute;drik Lime, Pierre Frisch
+ */
+public interface JmmDNS extends Closeable {
+
+    /**
+     * JmmDNS.Factory enable the creation of new instance of JmmDNS.
+     */
+    public static final class Factory {
+        private static volatile JmmDNS _instance;
+
+        /**
+         * This interface defines a delegate to the EOClassDescriptionRegister class to enable subclassing.
+         */
+        public static interface ClassDelegate {
+
+            /**
+             * Allows the delegate the opportunity to construct and return a different JmmDNS.
+             *
+             * @return Should return a new JmmDNS.
+             * @see #classDelegate()
+             * @see #setClassDelegate(ClassDelegate anObject)
+             */
+            public JmmDNS newJmmDNS();
+
+        }
+
+        private static final AtomicReference<ClassDelegate> _databaseClassDelegate = new AtomicReference<ClassDelegate>();
+
+        private Factory() {
+            super();
+        }
+
+        /**
+         * Assigns <code>delegate</code> as JmmDNS's class delegate. The class delegate is optional.
+         *
+         * @param delegate
+         *            The object to set as JmmDNS's class delegate.
+         * @see #classDelegate()
+         * @see JmmDNS.Factory.ClassDelegate
+         */
+        public static void setClassDelegate(ClassDelegate delegate) {
+            _databaseClassDelegate.set(delegate);
+        }
+
+        /**
+         * Returns JmmDNS's class delegate.
+         *
+         * @return JmmDNS's class delegate.
+         * @see #setClassDelegate(ClassDelegate anObject)
+         * @see JmmDNS.Factory.ClassDelegate
+         */
+        public static ClassDelegate classDelegate() {
+            return _databaseClassDelegate.get();
+        }
+
+        /**
+         * Returns a new instance of JmmDNS using the class delegate if it exists.
+         *
+         * @return new instance of JmmDNS
+         */
+        protected static JmmDNS newJmmDNS() {
+            JmmDNS dns = null;
+            ClassDelegate delegate = _databaseClassDelegate.get();
+            if (delegate != null) {
+                dns = delegate.newJmmDNS();
+            }
+            return (dns != null ? dns : new JmmDNSImpl());
+        }
+
+        /**
+         * Return the instance of the Multihommed Multicast DNS.
+         *
+         * @return the JmmDNS
+         */
+        public static JmmDNS getInstance() {
+            if (_instance == null) {
+                synchronized (Factory.class) {
+                    if (_instance == null) {
+                        _instance = JmmDNS.Factory.newJmmDNS();
+                    }
+                }
+            }
+            return _instance;
+        }
+    }
+
+    /**
+     * Return the names of the JmDNS instances.
+     *
+     * @return list of name of the JmDNS
+     * @see javax.jmdns.JmDNS#getName()
+     */
+    public abstract String[] getNames();
+
+    /**
+     * Return the list HostName associated with this JmmDNS instance.
+     *
+     * @return list of host names
+     * @see javax.jmdns.JmDNS#getHostName()
+     */
+    public abstract String[] getHostNames();
+
+    /**
+     * Return the list of addresses of the interface to which this instance of JmmDNS is bound.
+     *
+     * @return list of Internet Address
+     * @exception IOException
+     * @see javax.jmdns.JmDNS#getInetAddress()
+     */
+    public abstract InetAddress[] getInetAddresses() throws IOException;
+
+    /**
+     * Return the list of addresses of the interface to which this instance of JmmDNS is bound.
+     *
+     * @return list of Internet Address
+     * @exception IOException
+     * @see javax.jmdns.JmDNS#getInterface()
+     * @deprecated do not use this implementation yields unpredictable results use {@link #getInetAddresses()}
+     */
+    @Deprecated
+    public abstract InetAddress[] getInterfaces() throws IOException;
+
+    /**
+     * Get service information. If the information is not cached, the method will block until updated information is received on all DNS.
+     * <p/>
+     * Usage note: Do not call this method from the AWT event dispatcher thread. You will make the user interface unresponsive.
+     *
+     * @param type
+     *            fully qualified service type, such as <code>_http._tcp.local.</code> .
+     * @param name
+     *            unqualified service name, such as <code>foobar</code> .
+     * @return list of service info. If no service info is found the list is empty.
+     * @see javax.jmdns.JmDNS#getServiceInfo(java.lang.String, java.lang.String)
+     */
+    public abstract ServiceInfo[] getServiceInfos(String type, String name);
+
+    /**
+     * Get service information. If the information is not cached, the method will block until updated information is received on all DNS.
+     * <p/>
+     * Usage note: If you call this method from the AWT event dispatcher thread, use a small timeout, or you will make the user interface unresponsive.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code> .
+     * @param name
+     *            unqualified service name, such as <code>foobar</code> .
+     * @param timeout
+     *            timeout in milliseconds. Typical timeout should be 5s.
+     * @return list of service info. If no service info is found the list is empty.
+     * @see javax.jmdns.JmDNS#getServiceInfo(java.lang.String, java.lang.String, long)
+     */
+    public abstract ServiceInfo[] getServiceInfos(String type, String name, long timeout);
+
+    /**
+     * Get service information. If the information is not cached, the method will block until updated information is received on all DNS.
+     * <p/>
+     * Usage note: If you call this method from the AWT event dispatcher thread, use a small timeout, or you will make the user interface unresponsive.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code> .
+     * @param name
+     *            unqualified service name, such as <code>foobar</code> .
+     * @param persistent
+     *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
+     * @return list of service info. If no service info is found the list is empty.
+     * @see javax.jmdns.JmDNS#getServiceInfo(java.lang.String, java.lang.String, boolean)
+     */
+    public abstract ServiceInfo[] getServiceInfos(String type, String name, boolean persistent);
+
+    /**
+     * Get service information. If the information is not cached, the method will block until updated information is received on all DNS.
+     * <p/>
+     * Usage note: If you call this method from the AWT event dispatcher thread, use a small timeout, or you will make the user interface unresponsive.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code> .
+     * @param name
+     *            unqualified service name, such as <code>foobar</code> .
+     * @param timeout
+     *            timeout in milliseconds. Typical timeout should be 5s.
+     * @param persistent
+     *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
+     * @return list of service info. If no service info is found the list is empty.
+     * @see javax.jmdns.JmDNS#getServiceInfo(java.lang.String, java.lang.String, boolean, long)
+     */
+    public abstract ServiceInfo[] getServiceInfos(String type, String name, boolean persistent, long timeout);
+
+    /**
+     * Request service information. The information about the service is requested and the ServiceListener.resolveService method is called as soon as it is available.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code> .
+     * @param name
+     *            unqualified service name, such as <code>foobar</code> .
+     * @see javax.jmdns.JmDNS#requestServiceInfo(java.lang.String, java.lang.String)
+     */
+    public abstract void requestServiceInfo(String type, String name);
+
+    /**
+     * Request service information. The information about the service is requested and the ServiceListener.resolveService method is called as soon as it is available.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code> .
+     * @param name
+     *            unqualified service name, such as <code>foobar</code> .
+     * @param persistent
+     *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
+     * @see javax.jmdns.JmDNS#requestServiceInfo(java.lang.String, java.lang.String, boolean)
+     */
+    public abstract void requestServiceInfo(String type, String name, boolean persistent);
+
+    /**
+     * Request service information. The information about the service is requested and the ServiceListener.resolveService method is called as soon as it is available.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code> .
+     * @param name
+     *            unqualified service name, such as <code>foobar</code> .
+     * @param timeout
+     *            timeout in milliseconds
+     * @see javax.jmdns.JmDNS#requestServiceInfo(java.lang.String, java.lang.String, long)
+     */
+    public abstract void requestServiceInfo(String type, String name, long timeout);
+
+    /**
+     * Request service information. The information about the service is requested and the ServiceListener.resolveService method is called as soon as it is available.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code> .
+     * @param name
+     *            unqualified service name, such as <code>foobar</code> .
+     * @param persistent
+     *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
+     * @param timeout
+     *            timeout in milliseconds
+     * @see javax.jmdns.JmDNS#requestServiceInfo(java.lang.String, java.lang.String, boolean, long)
+     */
+    public abstract void requestServiceInfo(String type, String name, boolean persistent, long timeout);
+
+    /**
+     * Listen for service types.
+     *
+     * @param listener
+     *            listener for service types
+     * @exception IOException
+     * @see javax.jmdns.JmDNS#addServiceTypeListener(javax.jmdns.ServiceTypeListener)
+     */
+    public abstract void addServiceTypeListener(ServiceTypeListener listener) throws IOException;
+
+    /**
+     * Remove listener for service types.
+     *
+     * @param listener
+     *            listener for service types
+     * @see javax.jmdns.JmDNS#removeServiceTypeListener(javax.jmdns.ServiceTypeListener)
+     */
+    public abstract void removeServiceTypeListener(ServiceTypeListener listener);
+
+    /**
+     * Listen for services of a given type. The type has to be a fully qualified type name such as <code>_http._tcp.local.</code>.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code>.
+     * @param listener
+     *            listener for service updates
+     * @see javax.jmdns.JmDNS#addServiceListener(java.lang.String, javax.jmdns.ServiceListener)
+     */
+    public abstract void addServiceListener(String type, ServiceListener listener);
+
+    /**
+     * Remove listener for services of a given type.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code>.
+     * @param listener
+     *            listener for service updates
+     * @see javax.jmdns.JmDNS#removeServiceListener(java.lang.String, javax.jmdns.ServiceListener)
+     */
+    public abstract void removeServiceListener(String type, ServiceListener listener);
+
+    /**
+     * Register a service. The service is registered for access by other jmdns clients. The name of the service may be changed to make it unique.<br>
+     * <b>Note</b> the Service info is cloned for each network interface.
+     *
+     * @param info
+     *            service info to register
+     * @exception IOException
+     * @see javax.jmdns.JmDNS#registerService(javax.jmdns.ServiceInfo)
+     */
+    public abstract void registerService(ServiceInfo info) throws IOException;
+
+    /**
+     * Unregister a service. The service should have been registered.
+     *
+     * @param info
+     *            service info to remove
+     * @see javax.jmdns.JmDNS#unregisterService(javax.jmdns.ServiceInfo)
+     */
+    public abstract void unregisterService(ServiceInfo info);
+
+    /**
+     * Unregister all services.
+     *
+     * @see javax.jmdns.JmDNS#unregisterAllServices()
+     */
+    public abstract void unregisterAllServices();
+
+    /**
+     * Register a service type. If this service type was not already known, all service listeners will be notified of the new service type. Service types are automatically registered as they are discovered.
+     *
+     * @param type
+     *            full qualified service type, such as <code>_http._tcp.local.</code>.
+     * @see javax.jmdns.JmDNS#registerServiceType(java.lang.String)
+     */
+    public abstract void registerServiceType(String type);
+
+    /**
+     * Returns a list of service infos of the specified type.
+     *
+     * @param type
+     *            Service type name, such as <code>_http._tcp.local.</code>.
+     * @return An array of service instance.
+     * @see javax.jmdns.JmDNS#list(java.lang.String)
+     */
+    public abstract ServiceInfo[] list(String type);
+
+    /**
+     * Returns a list of service infos of the specified type.
+     *
+     * @param type
+     *            Service type name, such as <code>_http._tcp.local.</code>.
+     * @param timeout
+     *            timeout in milliseconds. Typical timeout should be 6s.
+     * @return An array of service instance.
+     * @see javax.jmdns.JmDNS#list(java.lang.String, long)
+     */
+    public abstract ServiceInfo[] list(String type, long timeout);
+
+    /**
+     * Returns a list of service infos of the specified type sorted by subtype. Any service that do not register a subtype is listed in the empty subtype section.
+     *
+     * @param type
+     *            Service type name, such as <code>_http._tcp.local.</code>.
+     * @return A dictionary of service info by subtypes.
+     * @see javax.jmdns.JmDNS#listBySubtype(java.lang.String)
+     */
+    public abstract Map<String, ServiceInfo[]> listBySubtype(String type);
+
+    /**
+     * Returns a list of service infos of the specified type sorted by subtype. Any service that do not register a subtype is listed in the empty subtype section.
+     *
+     * @param type
+     *            Service type name, such as <code>_http._tcp.local.</code>.
+     * @param timeout
+     *            timeout in milliseconds. Typical timeout should be 6s.
+     * @return A dictionary of service info by subtypes.
+     * @see javax.jmdns.JmDNS#listBySubtype(java.lang.String, long)
+     */
+    public abstract Map<String, ServiceInfo[]> listBySubtype(String type, long timeout);
+
+    /**
+     * Listen to network changes.
+     *
+     * @param listener
+     *            listener for network changes
+     */
+    public abstract void addNetworkTopologyListener(NetworkTopologyListener listener);
+
+    /**
+     * Remove listener for network changes.
+     *
+     * @param listener
+     *            listener for network changes
+     */
+    public abstract void removeNetworkTopologyListener(NetworkTopologyListener listener);
+
+    /**
+     * Returns list of network change listeners
+     *
+     * @return list of network change listeners
+     */
+    public abstract NetworkTopologyListener[] networkListeners();
+
+}
diff --git a/src/javax/jmdns/NetworkTopologyDiscovery.java b/src/javax/jmdns/NetworkTopologyDiscovery.java
new file mode 100644
index 0000000..05061db
--- /dev/null
+++ b/src/javax/jmdns/NetworkTopologyDiscovery.java
@@ -0,0 +1,164 @@
+package javax.jmdns;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.jmdns.impl.NetworkTopologyDiscoveryImpl;
+
+/**
+ * This class is used to resolve the list of Internet address to use when attaching JmDNS to the network.
+ * <p>
+ * To create you own filtering class for Internet Addresses you will need to implement the class and the factory delegate. These must be called before any other call to JmDNS.
+ *
+ * <pre>
+ * public static class MyNetworkTopologyDiscovery implements NetworkTopologyDiscovery {
+ *
+ *     &#064;Override
+ *     public InetAddress[] getInetAddresses() {
+ *         // TODO Auto-generated method stub
+ *         return null;
+ *     }
+ *
+ *     &#064;Override
+ *     public boolean useInetAddress(NetworkInterface networkInterface, InetAddress interfaceAddress) {
+ *         // TODO Auto-generated method stub
+ *         return false;
+ *     }
+ *
+ * }
+ *
+ * public static class MyClass implements NetworkTopologyDiscovery.Factory.ClassDelegate {
+ *     public MyClass() {
+ *         super();
+ *         NetworkTopologyDiscovery.Factory.setClassDelegate(this);
+ *
+ *         // Access JmDNS or JmmDNS
+ *     }
+ *
+ *     &#064;Override
+ *     public NetworkTopologyDiscovery newNetworkTopologyDiscovery() {
+ *         return new MyNetworkTopologyDiscovery();
+ *     }
+ *
+ * }
+ * </pre>
+ *
+ * </p>
+ *
+ * @author Pierre Frisch
+ */
+public interface NetworkTopologyDiscovery {
+
+    /**
+     * NetworkTopologyDiscovery.Factory enable the creation of new instance of NetworkTopologyDiscovery.
+     */
+    public static final class Factory {
+        private static volatile NetworkTopologyDiscovery _instance;
+
+        /**
+         * This interface defines a delegate to the NetworkTopologyDiscovery.Factory class to enable subclassing.
+         */
+        public static interface ClassDelegate {
+
+            /**
+             * Allows the delegate the opportunity to construct and return a different NetworkTopologyDiscovery.
+             *
+             * @return Should return a new NetworkTopologyDiscovery Object.
+             * @see #classDelegate()
+             * @see #setClassDelegate(ClassDelegate anObject)
+             */
+            public NetworkTopologyDiscovery newNetworkTopologyDiscovery();
+        }
+
+        private static final AtomicReference<Factory.ClassDelegate> _databaseClassDelegate = new AtomicReference<Factory.ClassDelegate>();
+
+        private Factory() {
+            super();
+        }
+
+        /**
+         * Assigns <code>delegate</code> as NetworkTopologyDiscovery's class delegate. The class delegate is optional.
+         *
+         * @param delegate
+         *            The object to set as NetworkTopologyDiscovery's class delegate.
+         * @see #classDelegate()
+         * @see JmmDNS.Factory.ClassDelegate
+         */
+        public static void setClassDelegate(Factory.ClassDelegate delegate) {
+            _databaseClassDelegate.set(delegate);
+        }
+
+        /**
+         * Returns NetworkTopologyDiscovery's class delegate.
+         *
+         * @return NetworkTopologyDiscovery's class delegate.
+         * @see #setClassDelegate(ClassDelegate anObject)
+         * @see JmmDNS.Factory.ClassDelegate
+         */
+        public static Factory.ClassDelegate classDelegate() {
+            return _databaseClassDelegate.get();
+        }
+
+        /**
+         * Returns a new instance of NetworkTopologyDiscovery using the class delegate if it exists.
+         *
+         * @return new instance of NetworkTopologyDiscovery
+         */
+        protected static NetworkTopologyDiscovery newNetworkTopologyDiscovery() {
+            NetworkTopologyDiscovery instance = null;
+            Factory.ClassDelegate delegate = _databaseClassDelegate.get();
+            if (delegate != null) {
+                instance = delegate.newNetworkTopologyDiscovery();
+            }
+            return (instance != null ? instance : new NetworkTopologyDiscoveryImpl());
+        }
+
+        /**
+         * Return the instance of the Multihommed Multicast DNS.
+         *
+         * @return the JmmDNS
+         */
+        public static NetworkTopologyDiscovery getInstance() {
+            if (_instance == null) {
+                synchronized (NetworkTopologyDiscovery.Factory.class) {
+                    if (_instance == null) {
+                        _instance = NetworkTopologyDiscovery.Factory.newNetworkTopologyDiscovery();
+                    }
+                }
+            }
+            return _instance;
+        }
+    }
+
+    /**
+     * Get all local Internet Addresses for the machine.
+     *
+     * @return Set of InetAddress
+     */
+    public abstract InetAddress[] getInetAddresses();
+
+    /**
+     * Check if a given InetAddress should be used for mDNS
+     *
+     * @param networkInterface
+     * @param interfaceAddress
+     * @return <code>true</code> is the address is to be used, <code>false</code> otherwise.
+     */
+    public boolean useInetAddress(NetworkInterface networkInterface, InetAddress interfaceAddress);
+
+    /**
+     * Locks the given InetAddress if the device requires it.
+     *
+     * @param interfaceAddress
+     */
+    public void lockInetAddress(InetAddress interfaceAddress);
+
+    /**
+     * Locks the given InetAddress if the device requires it.
+     *
+     * @param interfaceAddress
+     */
+    public void unlockInetAddress(InetAddress interfaceAddress);
+
+}
\ No newline at end of file
diff --git a/src/javax/jmdns/NetworkTopologyEvent.java b/src/javax/jmdns/NetworkTopologyEvent.java
new file mode 100644
index 0000000..16ef485
--- /dev/null
+++ b/src/javax/jmdns/NetworkTopologyEvent.java
@@ -0,0 +1,45 @@
+/**
+ *
+ */
+package javax.jmdns;
+
+import java.net.InetAddress;
+import java.util.EventObject;
+
+/**
+ * @author C&eacute;drik Lime, Pierre Frisch
+ */
+public abstract class NetworkTopologyEvent extends EventObject {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -8630033521752540987L;
+
+    /**
+     * Constructs a Service Event.
+     * 
+     * @param eventSource
+     *            The DNS on which the Event initially occurred.
+     * @exception IllegalArgumentException
+     *                if source is null.
+     */
+    protected NetworkTopologyEvent(final Object eventSource) {
+        super(eventSource);
+    }
+
+    /**
+     * Returns the JmDNS instance associated with the event or null if it is a generic event.
+     * 
+     * @return JmDNS instance
+     */
+    public abstract JmDNS getDNS();
+
+    /**
+     * The Internet address affected by this event.
+     * 
+     * @return InetAddress
+     */
+    public abstract InetAddress getInetAddress();
+
+}
diff --git a/src/javax/jmdns/NetworkTopologyListener.java b/src/javax/jmdns/NetworkTopologyListener.java
new file mode 100644
index 0000000..34ba415
--- /dev/null
+++ b/src/javax/jmdns/NetworkTopologyListener.java
@@ -0,0 +1,30 @@
+/**
+ *
+ */
+package javax.jmdns;
+
+import java.util.EventListener;
+
+/**
+ * Listener for network topology updates.
+ * 
+ * @author C&eacute;drik Lime, Pierre Frisch
+ */
+public interface NetworkTopologyListener extends EventListener {
+    /**
+     * A network address has been added.<br/>
+     * 
+     * @param event
+     *            The NetworkTopologyEvent providing the name and fully qualified type of the service.
+     */
+    void inetAddressAdded(NetworkTopologyEvent event);
+
+    /**
+     * A network address has been removed.
+     * 
+     * @param event
+     *            The NetworkTopologyEvent providing the name and fully qualified type of the service.
+     */
+    void inetAddressRemoved(NetworkTopologyEvent event);
+
+}
diff --git a/src/javax/jmdns/ServiceEvent.java b/src/javax/jmdns/ServiceEvent.java
new file mode 100644
index 0000000..d32df00
--- /dev/null
+++ b/src/javax/jmdns/ServiceEvent.java
@@ -0,0 +1,74 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns;
+
+import java.util.EventObject;
+
+/**
+ *
+ */
+public abstract class ServiceEvent extends EventObject implements Cloneable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -8558445644541006271L;
+
+    /**
+     * Constructs a Service Event.
+     * 
+     * @param eventSource
+     *            The object on which the Event initially occurred.
+     * @exception IllegalArgumentException
+     *                if source is null.
+     */
+    public ServiceEvent(final Object eventSource) {
+        super(eventSource);
+    }
+
+    /**
+     * Returns the JmDNS instance which originated the event.
+     * 
+     * @return JmDNS instance
+     */
+    public abstract JmDNS getDNS();
+
+    /**
+     * Returns the fully qualified type of the service.
+     * 
+     * @return type of the service.
+     */
+    public abstract String getType();
+
+    /**
+     * Returns the instance name of the service. Always returns null, if the event is sent to a service type listener.
+     * 
+     * @return name of the service
+     */
+    public abstract String getName();
+
+    /**
+     * Returns the service info record, or null if the service could not be resolved. Always returns null, if the event is sent to a service type listener.
+     * 
+     * @return service info record
+     * @see javax.jmdns.ServiceEvent#getInfo()
+     */
+    public abstract ServiceInfo getInfo();
+
+    /*
+     * (non-Javadoc)
+     * @see java.lang.Object#clone()
+     */
+    @Override
+    public ServiceEvent clone() {
+        try {
+            return (ServiceEvent) super.clone();
+        } catch (CloneNotSupportedException exception) {
+            // clone is supported
+            return null;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/src/javax/jmdns/ServiceInfo.java b/src/javax/jmdns/ServiceInfo.java
new file mode 100644
index 0000000..635f43a
--- /dev/null
+++ b/src/javax/jmdns/ServiceInfo.java
@@ -0,0 +1,727 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+package javax.jmdns;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.Enumeration;
+import java.util.Map;
+
+import javax.jmdns.impl.ServiceInfoImpl;
+
+/**
+ * <p>
+ * The fully qualified service name is build using up to 5 components with the following structure:
+ * 
+ * <pre>
+ *            &lt;app&gt;.&lt;protocol&gt;.&lt;servicedomain&gt;.&lt;parentdomain&gt;.<br/>
+ * &lt;Instance&gt;.&lt;app&gt;.&lt;protocol&gt;.&lt;servicedomain&gt;.&lt;parentdomain&gt;.<br/>
+ * &lt;sub&gt;._sub.&lt;app&gt;.&lt;protocol&gt;.&lt;servicedomain&gt;.&lt;parentdomain&gt;.
+ * </pre>
+ * 
+ * <ol>
+ * <li>&lt;servicedomain&gt;.&lt;parentdomain&gt;: This is the domain scope of the service typically "local.", but this can also be something similar to "in-addr.arpa." or "ip6.arpa."</li>
+ * <li>&lt;protocol&gt;: This is either "_tcp" or "_udp"</li>
+ * <li>&lt;app&gt;: This define the application protocol. Typical example are "_http", "_ftp", etc.</li>
+ * <li>&lt;Instance&gt;: This is the service name</li>
+ * <li>&lt;sub&gt;: This is the subtype for the application protocol</li>
+ * </ol>
+ * </p>
+ */
+public abstract class ServiceInfo implements Cloneable {
+
+    /**
+     * This is the no value text byte. According top the specification it is one byte with 0 value.
+     */
+    public static final byte[] NO_VALUE = new byte[0];
+
+    /**
+     * Fields for the fully qualified map.
+     */
+    public enum Fields {
+        /**
+         * Domain Field.
+         */
+        Domain,
+        /**
+         * Protocol Field.
+         */
+        Protocol,
+        /**
+         * Application Field.
+         */
+        Application,
+        /**
+         * Instance Field.
+         */
+        Instance,
+        /**
+         * Subtype Field.
+         */
+        Subtype
+    }
+
+    /**
+     * Construct a service description for registering with JmDNS.
+     * 
+     * @param type
+     *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
+     * @param name
+     *            unqualified service instance name, such as <code>foobar</code>
+     * @param port
+     *            the local port on which the service runs
+     * @param text
+     *            string describing the service
+     * @return new service info
+     */
+    public static ServiceInfo create(final String type, final String name, final int port, final String text) {
+        return new ServiceInfoImpl(type, name, "", port, 0, 0, false, text);
+    }
+
+    /**
+     * Construct a service description for registering with JmDNS.
+     * 
+     * @param type
+     *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
+     * @param name
+     *            unqualified service instance name, such as <code>foobar</code>
+     * @param subtype
+     *            service subtype see draft-cheshire-dnsext-dns-sd-06.txt chapter 7.1 Selective Instance Enumeration
+     * @param port
+     *            the local port on which the service runs
+     * @param text
+     *            string describing the service
+     * @return new service info
+     */
+    public static ServiceInfo create(final String type, final String name, final String subtype, final int port, final String text) {
+        return new ServiceInfoImpl(type, name, subtype, port, 0, 0, false, text);
+    }
+
+    /**
+     * Construct a service description for registering with JmDNS.
+     * 
+     * @param type
+     *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
+     * @param name
+     *            unqualified service instance name, such as <code>foobar</code>
+     * @param port
+     *            the local port on which the service runs
+     * @param weight
+     *            weight of the service
+     * @param priority
+     *            priority of the service
+     * @param text
+     *            string describing the service
+     * @return new service info
+     */
+    public static ServiceInfo create(final String type, final String name, final int port, final int weight, final int priority, final String text) {
+        return new ServiceInfoImpl(type, name, "", port, weight, priority, false, text);
+    }
+
+    /**
+     * Construct a service description for registering with JmDNS.
+     * 
+     * @param type
+     *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
+     * @param name
+     *            unqualified service instance name, such as <code>foobar</code>
+     * @param subtype
+     *            service subtype see draft-cheshire-dnsext-dns-sd-06.txt chapter 7.1 Selective Instance Enumeration
+     * @param port
+     *            the local port on which the service runs
+     * @param weight
+     *            weight of the service
+     * @param priority
+     *            priority of the service
+     * @param text
+     *            string describing the service
+     * @return new service info
+     */
+    public static ServiceInfo create(final String type, final String name, final String subtype, final int port, final int weight, final int priority, final String text) {
+        return new ServiceInfoImpl(type, name, subtype, port, weight, priority, false, text);
+    }
+
+    /**
+     * Construct a service description for registering with JmDNS. The properties hashtable must map property names to either Strings or byte arrays describing the property values.
+     * 
+     * @param type
+     *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
+     * @param name
+     *            unqualified service instance name, such as <code>foobar</code>
+     * @param port
+     *            the local port on which the service runs
+     * @param weight
+     *            weight of the service
+     * @param priority
+     *            priority of the service
+     * @param props
+     *            properties describing the service
+     * @return new service info
+     */
+    public static ServiceInfo create(final String type, final String name, final int port, final int weight, final int priority, final Map<String, ?> props) {
+        return new ServiceInfoImpl(type, name, "", port, weight, priority, false, props);
+    }
+
+    /**
+     * Construct a service description for registering with JmDNS. The properties hashtable must map property names to either Strings or byte arrays describing the property values.
+     * 
+     * @param type
+     *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
+     * @param name
+     *            unqualified service instance name, such as <code>foobar</code>
+     * @param subtype
+     *            service subtype see draft-cheshire-dnsext-dns-sd-06.txt chapter 7.1 Selective Instance Enumeration
+     * @param port
+     *            the local port on which the service runs
+     * @param weight
+     *            weight of the service
+     * @param priority
+     *            priority of the service
+     * @param props
+     *            properties describing the service
+     * @return new service info
+     */
+    public static ServiceInfo create(final String type, final String name, final String subtype, final int port, final int weight, final int priority, final Map<String, ?> props) {
+        return new ServiceInfoImpl(type, name, subtype, port, weight, priority, false, props);
+    }
+
+    /**
+     * Construct a service description for registering with JmDNS.
+     * 
+     * @param type
+     *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
+     * @param name
+     *            unqualified service instance name, such as <code>foobar</code>
+     * @param port
+     *            the local port on which the service runs
+     * @param weight
+     *            weight of the service
+     * @param priority
+     *            priority of the service
+     * @param text
+     *            bytes describing the service
+     * @return new service info
+     */
+    public static ServiceInfo create(final String type, final String name, final int port, final int weight, final int priority, final byte[] text) {
+        return new ServiceInfoImpl(type, name, "", port, weight, priority, false, text);
+    }
+
+    /**
+     * Construct a service description for registering with JmDNS.
+     * 
+     * @param type
+     *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
+     * @param name
+     *            unqualified service instance name, such as <code>foobar</code>
+     * @param subtype
+     *            service subtype see draft-cheshire-dnsext-dns-sd-06.txt chapter 7.1 Selective Instance Enumeration
+     * @param port
+     *            the local port on which the service runs
+     * @param weight
+     *            weight of the service
+     * @param priority
+     *            priority of the service
+     * @param text
+     *            bytes describing the service
+     * @return new service info
+     */
+    public static ServiceInfo create(final String type, final String name, final String subtype, final int port, final int weight, final int priority, final byte[] text) {
+        return new ServiceInfoImpl(type, name, subtype, port, weight, priority, false, text);
+    }
+
+    /**
+     * Construct a service description for registering with JmDNS.
+     * 
+     * @param type
+     *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
+     * @param name
+     *            unqualified service instance name, such as <code>foobar</code>
+     * @param port
+     *            the local port on which the service runs
+     * @param weight
+     *            weight of the service
+     * @param priority
+     *            priority of the service
+     * @param persistent
+     *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
+     * @param text
+     *            string describing the service
+     * @return new service info
+     */
+    public static ServiceInfo create(final String type, final String name, final int port, final int weight, final int priority, final boolean persistent, final String text) {
+        return new ServiceInfoImpl(type, name, "", port, weight, priority, persistent, text);
+    }
+
+    /**
+     * Construct a service description for registering with JmDNS.
+     * 
+     * @param type
+     *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
+     * @param name
+     *            unqualified service instance name, such as <code>foobar</code>
+     * @param subtype
+     *            service subtype see draft-cheshire-dnsext-dns-sd-06.txt chapter 7.1 Selective Instance Enumeration
+     * @param port
+     *            the local port on which the service runs
+     * @param weight
+     *            weight of the service
+     * @param priority
+     *            priority of the service
+     * @param persistent
+     *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
+     * @param text
+     *            string describing the service
+     * @return new service info
+     */
+    public static ServiceInfo create(final String type, final String name, final String subtype, final int port, final int weight, final int priority, final boolean persistent, final String text) {
+        return new ServiceInfoImpl(type, name, subtype, port, weight, priority, persistent, text);
+    }
+
+    /**
+     * Construct a service description for registering with JmDNS. The properties hashtable must map property names to either Strings or byte arrays describing the property values.
+     * 
+     * @param type
+     *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
+     * @param name
+     *            unqualified service instance name, such as <code>foobar</code>
+     * @param port
+     *            the local port on which the service runs
+     * @param weight
+     *            weight of the service
+     * @param priority
+     *            priority of the service
+     * @param persistent
+     *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
+     * @param props
+     *            properties describing the service
+     * @return new service info
+     */
+    public static ServiceInfo create(final String type, final String name, final int port, final int weight, final int priority, final boolean persistent, final Map<String, ?> props) {
+        return new ServiceInfoImpl(type, name, "", port, weight, priority, persistent, props);
+    }
+
+    /**
+     * Construct a service description for registering with JmDNS. The properties hashtable must map property names to either Strings or byte arrays describing the property values.
+     * 
+     * @param type
+     *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
+     * @param name
+     *            unqualified service instance name, such as <code>foobar</code>
+     * @param subtype
+     *            service subtype see draft-cheshire-dnsext-dns-sd-06.txt chapter 7.1 Selective Instance Enumeration
+     * @param port
+     *            the local port on which the service runs
+     * @param weight
+     *            weight of the service
+     * @param priority
+     *            priority of the service
+     * @param persistent
+     *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
+     * @param props
+     *            properties describing the service
+     * @return new service info
+     */
+    public static ServiceInfo create(final String type, final String name, final String subtype, final int port, final int weight, final int priority, final boolean persistent, final Map<String, ?> props) {
+        return new ServiceInfoImpl(type, name, subtype, port, weight, priority, persistent, props);
+    }
+
+    /**
+     * Construct a service description for registering with JmDNS.
+     * 
+     * @param type
+     *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
+     * @param name
+     *            unqualified service instance name, such as <code>foobar</code>
+     * @param port
+     *            the local port on which the service runs
+     * @param weight
+     *            weight of the service
+     * @param priority
+     *            priority of the service
+     * @param persistent
+     *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
+     * @param text
+     *            bytes describing the service
+     * @return new service info
+     */
+    public static ServiceInfo create(final String type, final String name, final int port, final int weight, final int priority, final boolean persistent, final byte[] text) {
+        return new ServiceInfoImpl(type, name, "", port, weight, priority, persistent, text);
+    }
+
+    /**
+     * Construct a service description for registering with JmDNS.
+     * 
+     * @param type
+     *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
+     * @param name
+     *            unqualified service instance name, such as <code>foobar</code>
+     * @param subtype
+     *            service subtype see draft-cheshire-dnsext-dns-sd-06.txt chapter 7.1 Selective Instance Enumeration
+     * @param port
+     *            the local port on which the service runs
+     * @param weight
+     *            weight of the service
+     * @param priority
+     *            priority of the service
+     * @param persistent
+     *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
+     * @param text
+     *            bytes describing the service
+     * @return new service info
+     */
+    public static ServiceInfo create(final String type, final String name, final String subtype, final int port, final int weight, final int priority, final boolean persistent, final byte[] text) {
+        return new ServiceInfoImpl(type, name, subtype, port, weight, priority, persistent, text);
+    }
+
+    /**
+     * Construct a service description for registering with JmDNS. The properties hashtable must map property names to either Strings or byte arrays describing the property values.
+     * 
+     * @param qualifiedNameMap
+     *            dictionary of values to build the fully qualified service name. Mandatory keys are Application and Instance. The Domain default is local, the Protocol default is tcp and the subtype default is none.
+     * @param port
+     *            the local port on which the service runs
+     * @param weight
+     *            weight of the service
+     * @param priority
+     *            priority of the service
+     * @param persistent
+     *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
+     * @param props
+     *            properties describing the service
+     * @return new service info
+     */
+    public static ServiceInfo create(final Map<Fields, String> qualifiedNameMap, final int port, final int weight, final int priority, final boolean persistent, final Map<String, ?> props) {
+        return new ServiceInfoImpl(qualifiedNameMap, port, weight, priority, persistent, props);
+    }
+
+    /**
+     * Returns true if the service info is filled with data.
+     * 
+     * @return <code>true</code> if the service info has data, <code>false</code> otherwise.
+     */
+    public abstract boolean hasData();
+
+    /**
+     * Fully qualified service type name, such as <code>_http._tcp.local.</code>
+     * 
+     * @return service type name
+     */
+    public abstract String getType();
+
+    /**
+     * Fully qualified service type name with the subtype if appropriate, such as <code>_printer._sub._http._tcp.local.</code>
+     * 
+     * @return service type name
+     */
+    public abstract String getTypeWithSubtype();
+
+    /**
+     * Unqualified service instance name, such as <code>foobar</code> .
+     * 
+     * @return service name
+     */
+    public abstract String getName();
+
+    /**
+     * The key is used to retrieve service info in hash tables.<br/>
+     * The key is the lower case qualified name.
+     * 
+     * @return the key
+     */
+    public abstract String getKey();
+
+    /**
+     * Fully qualified service name, such as <code>foobar._http._tcp.local.</code> .
+     * 
+     * @return qualified service name
+     */
+    public abstract String getQualifiedName();
+
+    /**
+     * Get the name of the server.
+     * 
+     * @return server name
+     */
+    public abstract String getServer();
+
+    /**
+     * Returns the host IP address string in textual presentation.<br/>
+     * <b>Note:</b> This can be either an IPv4 or an IPv6 representation.
+     * 
+     * @return the host raw IP address in a string format.
+     * @deprecated since 3.2.3
+     * @see #getHostAddresses()
+     */
+    @Deprecated
+    public abstract String getHostAddress();
+
+    /**
+     * Returns the host IP addresses string in textual presentation.
+     * 
+     * @return list of host raw IP address in a string format.
+     */
+    public abstract String[] getHostAddresses();
+
+    /**
+     * Get the host address of the service.<br/>
+     * 
+     * @return host Internet address
+     * @deprecated since 3.1.8
+     * @see #getInetAddresses()
+     */
+    @Deprecated
+    public abstract InetAddress getAddress();
+
+    /**
+     * Get the InetAddress of the service. This will return the IPv4 if it exist, otherwise it return the IPv6 if set.<br/>
+     * <b>Note:</b> This return null if the service IP address cannot be resolved.
+     * 
+     * @return Internet address
+     * @deprecated since 3.2.3
+     * @see #getInetAddresses()
+     */
+    @Deprecated
+    public abstract InetAddress getInetAddress();
+
+    /**
+     * Get the IPv4 InetAddress of the service.<br/>
+     * <b>Note:</b> This return null if the service IPv4 address cannot be resolved.
+     * 
+     * @return Internet address
+     * @deprecated since 3.2.3
+     * @see #getInet4Addresses()
+     */
+    @Deprecated
+    public abstract Inet4Address getInet4Address();
+
+    /**
+     * Get the IPv6 InetAddress of the service.<br/>
+     * <b>Note:</b> This return null if the service IPv6 address cannot be resolved.
+     * 
+     * @return Internet address
+     * @deprecated since 3.2.3
+     * @see #getInet6Addresses()
+     */
+    @Deprecated
+    public abstract Inet6Address getInet6Address();
+
+    /**
+     * Returns a list of all InetAddresses that can be used for this service.
+     * <p>
+     * In a multi-homed environment service info can be associated with more than one address.
+     * </p>
+     * 
+     * @return list of InetAddress objects
+     */
+    public abstract InetAddress[] getInetAddresses();
+
+    /**
+     * Returns a list of all IPv4 InetAddresses that can be used for this service.
+     * <p>
+     * In a multi-homed environment service info can be associated with more than one address.
+     * </p>
+     * 
+     * @return list of InetAddress objects
+     */
+    public abstract Inet4Address[] getInet4Addresses();
+
+    /**
+     * Returns a list of all IPv6 InetAddresses that can be used for this service.
+     * <p>
+     * In a multi-homed environment service info can be associated with more than one address.
+     * </p>
+     * 
+     * @return list of InetAddress objects
+     */
+    public abstract Inet6Address[] getInet6Addresses();
+
+    /**
+     * Get the port for the service.
+     * 
+     * @return service port
+     */
+    public abstract int getPort();
+
+    /**
+     * Get the priority of the service.
+     * 
+     * @return service priority
+     */
+    public abstract int getPriority();
+
+    /**
+     * Get the weight of the service.
+     * 
+     * @return service weight
+     */
+    public abstract int getWeight();
+
+    /**
+     * Get the text for the service as raw bytes.
+     * 
+     * @return raw service text
+     */
+    public abstract byte[] getTextBytes();
+
+    /**
+     * Get the text for the service. This will interpret the text bytes as a UTF8 encoded string. Will return null if the bytes are not a valid UTF8 encoded string.<br/>
+     * <b>Note:</b> Do not use. This method make the assumption that the TXT record is one string. This is false. The TXT record is a series of key value pairs.
+     * 
+     * @return service text
+     * @see #getPropertyNames()
+     * @see #getPropertyBytes(String)
+     * @see #getPropertyString(String)
+     * @deprecated since 3.1.7
+     */
+    @Deprecated
+    public abstract String getTextString();
+
+    /**
+     * Get the URL for this service. An http URL is created by combining the address, port, and path properties.
+     * 
+     * @return service URL
+     * @deprecated since 3.2.3
+     * @see #getURLs()
+     */
+    @Deprecated
+    public abstract String getURL();
+
+    /**
+     * Get the list of URL for this service. An http URL is created by combining the address, port, and path properties.
+     * 
+     * @return list of service URL
+     */
+    public abstract String[] getURLs();
+
+    /**
+     * Get the URL for this service. An URL is created by combining the protocol, address, port, and path properties.
+     * 
+     * @param protocol
+     *            requested protocol
+     * @return service URL
+     * @deprecated since 3.2.3
+     * @see #getURLs()
+     */
+    @Deprecated
+    public abstract String getURL(String protocol);
+
+    /**
+     * Get the list of URL for this service. An URL is created by combining the protocol, address, port, and path properties.
+     * 
+     * @param protocol
+     *            requested protocol
+     * @return list of service URL
+     */
+    public abstract String[] getURLs(String protocol);
+
+    /**
+     * Get a property of the service. This involves decoding the text bytes into a property list. Returns null if the property is not found or the text data could not be decoded correctly.
+     * 
+     * @param name
+     *            property name
+     * @return raw property text
+     */
+    public abstract byte[] getPropertyBytes(final String name);
+
+    /**
+     * Get a property of the service. This involves decoding the text bytes into a property list. Returns null if the property is not found, the text data could not be decoded correctly, or the resulting bytes are not a valid UTF8 string.
+     * 
+     * @param name
+     *            property name
+     * @return property text
+     */
+    public abstract String getPropertyString(final String name);
+
+    /**
+     * Enumeration of the property names.
+     * 
+     * @return property name enumeration
+     */
+    public abstract Enumeration<String> getPropertyNames();
+
+    /**
+     * Returns a description of the service info suitable for printing.
+     * 
+     * @return service info description
+     */
+    public abstract String getNiceTextString();
+
+    /**
+     * Set the text for the service. Setting the text will fore a re-announce of the service.
+     * 
+     * @param text
+     *            the raw byte representation of the text field.
+     * @exception IllegalStateException
+     *                if attempting to set the text for a non persistent service info.
+     */
+    public abstract void setText(final byte[] text) throws IllegalStateException;
+
+    /**
+     * Set the text for the service. Setting the text will fore a re-announce of the service.
+     * 
+     * @param props
+     *            a key=value map that will be encoded into raw bytes.
+     * @exception IllegalStateException
+     *                if attempting to set the text for a non persistent service info.
+     */
+    public abstract void setText(final Map<String, ?> props) throws IllegalStateException;
+
+    /**
+     * Returns <code>true</code> if ServiceListener.resolveService will be called whenever new new information is received.
+     * 
+     * @return the persistent
+     */
+    public abstract boolean isPersistent();
+
+    /**
+     * Returns the domain of the service info suitable for printing.
+     * 
+     * @return service domain
+     */
+    public abstract String getDomain();
+
+    /**
+     * Returns the protocol of the service info suitable for printing.
+     * 
+     * @return service protocol
+     */
+    public abstract String getProtocol();
+
+    /**
+     * Returns the application of the service info suitable for printing.
+     * 
+     * @return service application
+     */
+    public abstract String getApplication();
+
+    /**
+     * Returns the sub type of the service info suitable for printing.
+     * 
+     * @return service sub type
+     */
+    public abstract String getSubtype();
+
+    /**
+     * Returns a dictionary of the fully qualified name component of this service.
+     * 
+     * @return dictionary of the fully qualified name components
+     */
+    public abstract Map<Fields, String> getQualifiedNameMap();
+
+    /*
+     * (non-Javadoc)
+     * @see java.lang.Object#clone()
+     */
+    @Override
+    public ServiceInfo clone() {
+        try {
+            return (ServiceInfo) super.clone();
+        } catch (CloneNotSupportedException exception) {
+            // clone is supported
+            return null;
+        }
+    }
+
+}
diff --git a/src/javax/jmdns/ServiceListener.java b/src/javax/jmdns/ServiceListener.java
new file mode 100644
index 0000000..b08263d
--- /dev/null
+++ b/src/javax/jmdns/ServiceListener.java
@@ -0,0 +1,49 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns;
+
+import java.util.EventListener;
+
+/**
+ * Listener for service updates.
+ *
+ * @author Arthur van Hoff, Werner Randelshofer, Pierre Frisch
+ */
+public interface ServiceListener extends EventListener {
+    /**
+     * A service has been added.<br/>
+     * <b>Note:</b>This event is only the service added event. The service info associated with this event does not include resolution information.<br/>
+     * To get the full resolved information you need to listen to {@link #serviceResolved(ServiceEvent)} or call {@link JmDNS#getServiceInfo(String, String, long)}
+     *
+     * <pre>
+     *  ServiceInfo info = event.getDNS().getServiceInfo(event.getType(), event.getName())
+     * </pre>
+     * <p>
+     * Please note that service resolution may take a few second to resolve.
+     * </p>
+     *
+     * @param event
+     *            The ServiceEvent providing the name and fully qualified type of the service.
+     */
+    void serviceAdded(ServiceEvent event);
+
+    /**
+     * A service has been removed.
+     *
+     * @param event
+     *            The ServiceEvent providing the name and fully qualified type of the service.
+     */
+    void serviceRemoved(ServiceEvent event);
+
+    /**
+     * A service has been resolved. Its details are now available in the ServiceInfo record.<br/>
+     * <b>Note:</b>This call back will never be called if the service does not resolve.<br/>
+     *
+     * @param event
+     *            The ServiceEvent providing the name, the fully qualified type of the service, and the service info record.
+     */
+    void serviceResolved(ServiceEvent event);
+
+}
diff --git a/src/javax/jmdns/ServiceTypeListener.java b/src/javax/jmdns/ServiceTypeListener.java
new file mode 100644
index 0000000..6c2cc5f
--- /dev/null
+++ b/src/javax/jmdns/ServiceTypeListener.java
@@ -0,0 +1,35 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns;
+
+import java.util.EventListener;
+
+/**
+ * Listener for service types.
+ * 
+ * @author Arthur van Hoff, Werner Randelshofer
+ */
+public interface ServiceTypeListener extends EventListener {
+    /**
+     * A new service type was discovered.
+     * 
+     * @param event
+     *            The service event providing the fully qualified type of the service.
+     */
+    void serviceTypeAdded(ServiceEvent event);
+
+    /**
+     * A new subtype for the service type was discovered.
+     * 
+     * <pre>
+     * &lt;sub&gt;._sub.&lt;app&gt;.&lt;protocol&gt;.&lt;servicedomain&gt;.&lt;parentdomain&gt;.
+     * </pre>
+     * 
+     * @param event
+     *            The service event providing the fully qualified type of the service with subtype.
+     * @since 3.2.0
+     */
+    void subTypeForServiceTypeAdded(ServiceEvent event);
+}
diff --git a/src/javax/jmdns/impl/DNSCache.java b/src/javax/jmdns/impl/DNSCache.java
new file mode 100644
index 0000000..ed26f0d
--- /dev/null
+++ b/src/javax/jmdns/impl/DNSCache.java
@@ -0,0 +1,543 @@
+// Copyright 2003-2005 Arthur van Hoff Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl;
+
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jmdns.impl.constants.DNSRecordClass;
+import javax.jmdns.impl.constants.DNSRecordType;
+
+/**
+ * A table of DNS entries. This is a map table which can handle multiple entries with the same name.
+ * <p/>
+ * Storing multiple entries with the same name is implemented using a linked list. This is hidden from the user and can change in later implementation.
+ * <p/>
+ * Here's how to iterate over all entries:
+ *
+ * <pre>
+ *       for (Iterator i=dnscache.allValues().iterator(); i.hasNext(); ) {
+ *             DNSEntry entry = i.next();
+ *             ...do something with entry...
+ *       }
+ * </pre>
+ * <p/>
+ * And here's how to iterate over all entries having a given name:
+ *
+ * <pre>
+ *       for (Iterator i=dnscache.getDNSEntryList(name).iterator(); i.hasNext(); ) {
+ *             DNSEntry entry = i.next();
+ *           ...do something with entry...
+ *       }
+ * </pre>
+ *
+ * @author Arthur van Hoff, Werner Randelshofer, Rick Blair, Pierre Frisch
+ */
+public class DNSCache extends AbstractMap<String, List<? extends DNSEntry>> {
+
+    // private static Logger logger = Logger.getLogger(DNSCache.class.getName());
+
+    private transient Set<Map.Entry<String, List<? extends DNSEntry>>> _entrySet  = null;
+
+    /**
+     *
+     */
+    public static final DNSCache                                       EmptyCache = new _EmptyCache();
+
+    static final class _EmptyCache extends DNSCache {
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public int size() {
+            return 0;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean isEmpty() {
+            return true;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean containsKey(Object key) {
+            return false;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean containsValue(Object value) {
+            return false;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public List<DNSEntry> get(Object key) {
+            return null;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public Set<String> keySet() {
+            return Collections.emptySet();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public Collection<List<? extends DNSEntry>> values() {
+            return Collections.emptySet();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public Set<Map.Entry<String, List<? extends DNSEntry>>> entrySet() {
+            return Collections.emptySet();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean equals(Object o) {
+            return (o instanceof Map) && ((Map<?, ?>) o).size() == 0;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public List<? extends DNSEntry> put(String key, List<? extends DNSEntry> value) {
+            return null;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public int hashCode() {
+            return 0;
+        }
+
+    }
+
+    /**
+     *
+     */
+    protected static class _CacheEntry extends Object implements Map.Entry<String, List<? extends DNSEntry>> {
+
+        private List<? extends DNSEntry> _value;
+
+        private String                   _key;
+
+        /**
+         * @param key
+         * @param value
+         */
+        protected _CacheEntry(String key, List<? extends DNSEntry> value) {
+            super();
+            _key = (key != null ? key.trim().toLowerCase() : null);
+            _value = value;
+        }
+
+        /**
+         * @param entry
+         */
+        protected _CacheEntry(Map.Entry<String, List<? extends DNSEntry>> entry) {
+            super();
+            if (entry instanceof _CacheEntry) {
+                _key = ((_CacheEntry) entry).getKey();
+                _value = ((_CacheEntry) entry).getValue();
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public String getKey() {
+            return (_key != null ? _key : "");
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public List<? extends DNSEntry> getValue() {
+            return _value;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public List<? extends DNSEntry> setValue(List<? extends DNSEntry> value) {
+            List<? extends DNSEntry> oldValue = _value;
+            _value = value;
+            return oldValue;
+        }
+
+        /**
+         * Returns <tt>true</tt> if this list contains no elements.
+         *
+         * @return <tt>true</tt> if this list contains no elements
+         */
+        public boolean isEmpty() {
+            return this.getValue().isEmpty();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean equals(Object entry) {
+            if (!(entry instanceof Map.Entry)) {
+                return false;
+            }
+            return this.getKey().equals(((Map.Entry<?, ?>) entry).getKey()) && this.getValue().equals(((Map.Entry<?, ?>) entry).getValue());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public int hashCode() {
+            return (_key == null ? 0 : _key.hashCode());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public synchronized String toString() {
+            StringBuffer aLog = new StringBuffer(200);
+            aLog.append("\n\t\tname '");
+            aLog.append(_key);
+            aLog.append("' ");
+            if ((_value != null) && (!_value.isEmpty())) {
+                for (DNSEntry entry : _value) {
+                    aLog.append("\n\t\t\t");
+                    aLog.append(entry.toString());
+                }
+            } else {
+                aLog.append(" no entries");
+            }
+            return aLog.toString();
+        }
+    }
+
+    /**
+     *
+     */
+    public DNSCache() {
+        this(1024);
+    }
+
+    /**
+     * @param map
+     */
+    public DNSCache(DNSCache map) {
+        this(map != null ? map.size() : 1024);
+        if (map != null) {
+            this.putAll(map);
+        }
+    }
+
+    /**
+     * Create a table with a given initial size.
+     *
+     * @param initialCapacity
+     */
+    public DNSCache(int initialCapacity) {
+        super();
+        _entrySet = new HashSet<Map.Entry<String, List<? extends DNSEntry>>>(initialCapacity);
+    }
+
+    // ====================================================================
+    // Map
+
+    /*
+     * (non-Javadoc)
+     * @see java.util.AbstractMap#entrySet()
+     */
+    @Override
+    public Set<Map.Entry<String, List<? extends DNSEntry>>> entrySet() {
+        if (_entrySet == null) {
+            _entrySet = new HashSet<Map.Entry<String, List<? extends DNSEntry>>>();
+        }
+        return _entrySet;
+    }
+
+    /**
+     * @param key
+     * @return map entry for the key
+     */
+    protected Map.Entry<String, List<? extends DNSEntry>> getEntry(String key) {
+        String stringKey = (key != null ? key.trim().toLowerCase() : null);
+        for (Map.Entry<String, List<? extends DNSEntry>> entry : this.entrySet()) {
+            if (stringKey != null) {
+                if (stringKey.equals(entry.getKey())) {
+                    return entry;
+                }
+            } else {
+                if (entry.getKey() == null) {
+                    return entry;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<? extends DNSEntry> put(String key, List<? extends DNSEntry> value) {
+        synchronized (this) {
+            List<? extends DNSEntry> oldValue = null;
+            Map.Entry<String, List<? extends DNSEntry>> oldEntry = this.getEntry(key);
+            if (oldEntry != null) {
+                oldValue = oldEntry.setValue(value);
+            } else {
+                this.entrySet().add(new _CacheEntry(key, value));
+            }
+            return oldValue;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Object clone() throws CloneNotSupportedException {
+        return new DNSCache(this);
+    }
+
+    // ====================================================================
+
+    /**
+     * Returns all entries in the cache
+     *
+     * @return all entries in the cache
+     */
+    public synchronized Collection<DNSEntry> allValues() {
+        List<DNSEntry> allValues = new ArrayList<DNSEntry>();
+        for (List<? extends DNSEntry> entry : this.values()) {
+            if (entry != null) {
+                allValues.addAll(entry);
+            }
+        }
+        return allValues;
+    }
+
+    /**
+     * Iterate only over items with matching name. Returns an list of DNSEntry or null. To retrieve all entries, one must iterate over this linked list.
+     *
+     * @param name
+     * @return list of DNSEntries
+     */
+    public synchronized Collection<? extends DNSEntry> getDNSEntryList(String name) {
+        Collection<? extends DNSEntry> entryList = this._getDNSEntryList(name);
+        if (entryList != null) {
+            entryList = new ArrayList<DNSEntry>(entryList);
+        } else {
+            entryList = Collections.emptyList();
+        }
+        return entryList;
+    }
+
+    private Collection<? extends DNSEntry> _getDNSEntryList(String name) {
+        return this.get(name != null ? name.toLowerCase() : null);
+    }
+
+    /**
+     * Get a matching DNS entry from the table (using isSameEntry). Returns the entry that was found.
+     *
+     * @param dnsEntry
+     * @return DNSEntry
+     */
+    public synchronized DNSEntry getDNSEntry(DNSEntry dnsEntry) {
+        DNSEntry result = null;
+        if (dnsEntry != null) {
+            Collection<? extends DNSEntry> entryList = this._getDNSEntryList(dnsEntry.getKey());
+            if (entryList != null) {
+                for (DNSEntry testDNSEntry : entryList) {
+                    if (testDNSEntry.isSameEntry(dnsEntry)) {
+                        result = testDNSEntry;
+                        break;
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Get a matching DNS entry from the table.
+     *
+     * @param name
+     * @param type
+     * @param recordClass
+     * @return DNSEntry
+     */
+    public synchronized DNSEntry getDNSEntry(String name, DNSRecordType type, DNSRecordClass recordClass) {
+        DNSEntry result = null;
+        Collection<? extends DNSEntry> entryList = this._getDNSEntryList(name);
+        if (entryList != null) {
+            for (DNSEntry testDNSEntry : entryList) {
+                if (testDNSEntry.getRecordType().equals(type) && ((DNSRecordClass.CLASS_ANY == recordClass) || testDNSEntry.getRecordClass().equals(recordClass))) {
+                    result = testDNSEntry;
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Get all matching DNS entries from the table.
+     *
+     * @param name
+     * @param type
+     * @param recordClass
+     * @return list of entries
+     */
+    public synchronized Collection<? extends DNSEntry> getDNSEntryList(String name, DNSRecordType type, DNSRecordClass recordClass) {
+        Collection<? extends DNSEntry> entryList = this._getDNSEntryList(name);
+        if (entryList != null) {
+            entryList = new ArrayList<DNSEntry>(entryList);
+            for (Iterator<? extends DNSEntry> i = entryList.iterator(); i.hasNext();) {
+                DNSEntry testDNSEntry = i.next();
+                if (!testDNSEntry.getRecordType().equals(type) || ((DNSRecordClass.CLASS_ANY != recordClass) && !testDNSEntry.getRecordClass().equals(recordClass))) {
+                    i.remove();
+                }
+            }
+        } else {
+            entryList = Collections.emptyList();
+        }
+        return entryList;
+    }
+
+    /**
+     * Adds an entry to the table.
+     *
+     * @param dnsEntry
+     * @return true if the entry was added
+     */
+    public synchronized boolean addDNSEntry(final DNSEntry dnsEntry) {
+        boolean result = false;
+        if (dnsEntry != null) {
+            Map.Entry<String, List<? extends DNSEntry>> oldEntry = this.getEntry(dnsEntry.getKey());
+
+            List<DNSEntry> aNewValue = null;
+            if (oldEntry != null) {
+                aNewValue = new ArrayList<DNSEntry>(oldEntry.getValue());
+            } else {
+                aNewValue = new ArrayList<DNSEntry>();
+            }
+            aNewValue.add(dnsEntry);
+
+            if (oldEntry != null) {
+                oldEntry.setValue(aNewValue);
+            } else {
+                this.entrySet().add(new _CacheEntry(dnsEntry.getKey(), aNewValue));
+            }
+            // This is probably not very informative
+            result = true;
+        }
+        return result;
+    }
+
+    /**
+     * Removes a specific entry from the table. Returns true if the entry was found.
+     *
+     * @param dnsEntry
+     * @return true if the entry was removed
+     */
+    public synchronized boolean removeDNSEntry(DNSEntry dnsEntry) {
+        boolean result = false;
+        if (dnsEntry != null) {
+            Map.Entry<String, List<? extends DNSEntry>> existingEntry = this.getEntry(dnsEntry.getKey());
+            if (existingEntry != null) {
+                result = existingEntry.getValue().remove(dnsEntry);
+                // If we just removed the last one we need to get rid of the entry
+                if (existingEntry.getValue().isEmpty()) {
+                    this.entrySet().remove(existingEntry);
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Replace an existing entry by a new one.<br/>
+     * <b>Note:</b> the 2 entries must have the same key.
+     *
+     * @param newDNSEntry
+     * @param existingDNSEntry
+     * @return <code>true</code> if the entry has been replace, <code>false</code> otherwise.
+     */
+    public synchronized boolean replaceDNSEntry(DNSEntry newDNSEntry, DNSEntry existingDNSEntry) {
+        boolean result = false;
+        if ((newDNSEntry != null) && (existingDNSEntry != null) && (newDNSEntry.getKey().equals(existingDNSEntry.getKey()))) {
+            Map.Entry<String, List<? extends DNSEntry>> oldEntry = this.getEntry(newDNSEntry.getKey());
+
+            List<DNSEntry> aNewValue = null;
+            if (oldEntry != null) {
+                aNewValue = new ArrayList<DNSEntry>(oldEntry.getValue());
+            } else {
+                aNewValue = new ArrayList<DNSEntry>();
+            }
+            aNewValue.remove(existingDNSEntry);
+            aNewValue.add(newDNSEntry);
+
+            if (oldEntry != null) {
+                oldEntry.setValue(aNewValue);
+            } else {
+                this.entrySet().add(new _CacheEntry(newDNSEntry.getKey(), aNewValue));
+            }
+            // This is probably not very informative
+            result = true;
+        }
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized String toString() {
+        StringBuffer aLog = new StringBuffer(2000);
+        aLog.append("\t---- cache ----");
+        for (Map.Entry<String, List<? extends DNSEntry>> entry : this.entrySet()) {
+            aLog.append("\n\t\t");
+            aLog.append(entry.toString());
+        }
+        return aLog.toString();
+    }
+
+}
diff --git a/src/javax/jmdns/impl/DNSEntry.java b/src/javax/jmdns/impl/DNSEntry.java
new file mode 100644
index 0000000..472ec65
--- /dev/null
+++ b/src/javax/jmdns/impl/DNSEntry.java
@@ -0,0 +1,296 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+
+import javax.jmdns.ServiceInfo.Fields;
+import javax.jmdns.impl.constants.DNSRecordClass;
+import javax.jmdns.impl.constants.DNSRecordType;
+
+/**
+ * DNS entry with a name, type, and class. This is the base class for questions and records.
+ * 
+ * @author Arthur van Hoff, Pierre Frisch, Rick Blair
+ */
+public abstract class DNSEntry {
+    // private static Logger logger = Logger.getLogger(DNSEntry.class.getName());
+    private final String         _key;
+
+    private final String         _name;
+
+    private final String         _type;
+
+    private final DNSRecordType  _recordType;
+
+    private final DNSRecordClass _dnsClass;
+
+    private final boolean        _unique;
+
+    final Map<Fields, String>    _qualifiedNameMap;
+
+    /**
+     * Create an entry.
+     */
+    DNSEntry(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+        _name = name;
+        // _key = (name != null ? name.trim().toLowerCase() : null);
+        _recordType = type;
+        _dnsClass = recordClass;
+        _unique = unique;
+        _qualifiedNameMap = ServiceInfoImpl.decodeQualifiedNameMapForType(this.getName());
+        String domain = _qualifiedNameMap.get(Fields.Domain);
+        String protocol = _qualifiedNameMap.get(Fields.Protocol);
+        String application = _qualifiedNameMap.get(Fields.Application);
+        String instance = _qualifiedNameMap.get(Fields.Instance).toLowerCase();
+        _type = (application.length() > 0 ? "_" + application + "." : "") + (protocol.length() > 0 ? "_" + protocol + "." : "") + domain + ".";
+        _key = ((instance.length() > 0 ? instance + "." : "") + _type).toLowerCase();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        boolean result = false;
+        if (obj instanceof DNSEntry) {
+            DNSEntry other = (DNSEntry) obj;
+            result = this.getKey().equals(other.getKey()) && this.getRecordType().equals(other.getRecordType()) && this.getRecordClass() == other.getRecordClass();
+        }
+        return result;
+    }
+
+    /**
+     * Check if two entries have exactly the same name, type, and class.
+     * 
+     * @param entry
+     * @return <code>true</code> if the two entries have are for the same record, <code>false</code> otherwise
+     */
+    public boolean isSameEntry(DNSEntry entry) {
+        return this.getKey().equals(entry.getKey()) && this.getRecordType().equals(entry.getRecordType()) && ((DNSRecordClass.CLASS_ANY == entry.getRecordClass()) || this.getRecordClass().equals(entry.getRecordClass()));
+    }
+
+    /**
+     * Check if two entries have the same subtype.
+     * 
+     * @param other
+     * @return <code>true</code> if the two entries have are for the same subtype, <code>false</code> otherwise
+     */
+    public boolean sameSubtype(DNSEntry other) {
+        return this.getSubtype().equals(other.getSubtype());
+    }
+
+    /**
+     * Returns the subtype of this entry
+     * 
+     * @return subtype of this entry
+     */
+    public String getSubtype() {
+        String subtype = this.getQualifiedNameMap().get(Fields.Subtype);
+        return (subtype != null ? subtype : "");
+    }
+
+    /**
+     * Returns the name of this entry
+     * 
+     * @return name of this entry
+     */
+    public String getName() {
+        return (_name != null ? _name : "");
+    }
+
+    /**
+     * @return the type
+     */
+    public String getType() {
+        return (_type != null ? _type : "");
+    }
+
+    /**
+     * Returns the key for this entry. The key is the lower case name.
+     * 
+     * @return key for this entry
+     */
+    public String getKey() {
+        return (_key != null ? _key : "");
+    }
+
+    /**
+     * @return record type
+     */
+    public DNSRecordType getRecordType() {
+        return (_recordType != null ? _recordType : DNSRecordType.TYPE_IGNORE);
+    }
+
+    /**
+     * @return record class
+     */
+    public DNSRecordClass getRecordClass() {
+        return (_dnsClass != null ? _dnsClass : DNSRecordClass.CLASS_UNKNOWN);
+    }
+
+    /**
+     * @return true if unique
+     */
+    public boolean isUnique() {
+        return _unique;
+    }
+
+    public Map<Fields, String> getQualifiedNameMap() {
+        return Collections.unmodifiableMap(_qualifiedNameMap);
+    }
+
+    public boolean isServicesDiscoveryMetaQuery() {
+        return _qualifiedNameMap.get(Fields.Application).equals("dns-sd") && _qualifiedNameMap.get(Fields.Instance).equals("_services");
+    }
+
+    public boolean isDomainDiscoveryQuery() {
+        // b._dns-sd._udp.<domain>.
+        // db._dns-sd._udp.<domain>.
+        // r._dns-sd._udp.<domain>.
+        // dr._dns-sd._udp.<domain>.
+        // lb._dns-sd._udp.<domain>.
+
+        if (_qualifiedNameMap.get(Fields.Application).equals("dns-sd")) {
+            String name = _qualifiedNameMap.get(Fields.Instance);
+            return "b".equals(name) || "db".equals(name) || "r".equals(name) || "dr".equals(name) || "lb".equals(name);
+        }
+        return false;
+    }
+
+    public boolean isReverseLookup() {
+        return this.isV4ReverseLookup() || this.isV6ReverseLookup();
+    }
+
+    public boolean isV4ReverseLookup() {
+        return _qualifiedNameMap.get(Fields.Domain).endsWith("in-addr.arpa");
+    }
+
+    public boolean isV6ReverseLookup() {
+        return _qualifiedNameMap.get(Fields.Domain).endsWith("ip6.arpa");
+    }
+
+    /**
+     * Check if the record is stale, i.e. it has outlived more than half of its TTL.
+     * 
+     * @param now
+     *            update date
+     * @return <code>true</code> is the record is stale, <code>false</code> otherwise.
+     */
+    public abstract boolean isStale(long now);
+
+    /**
+     * Check if the record is expired.
+     * 
+     * @param now
+     *            update date
+     * @return <code>true</code> is the record is expired, <code>false</code> otherwise.
+     */
+    public abstract boolean isExpired(long now);
+
+    /**
+     * Check that 2 entries are of the same class.
+     * 
+     * @param entry
+     * @return <code>true</code> is the two class are the same, <code>false</code> otherwise.
+     */
+    public boolean isSameRecordClass(DNSEntry entry) {
+        return (entry != null) && (entry.getRecordClass() == this.getRecordClass());
+    }
+
+    /**
+     * Check that 2 entries are of the same type.
+     * 
+     * @param entry
+     * @return <code>true</code> is the two type are the same, <code>false</code> otherwise.
+     */
+    public boolean isSameType(DNSEntry entry) {
+        return (entry != null) && (entry.getRecordType() == this.getRecordType());
+    }
+
+    /**
+     * @param dout
+     * @exception IOException
+     */
+    protected void toByteArray(DataOutputStream dout) throws IOException {
+        dout.write(this.getName().getBytes("UTF8"));
+        dout.writeShort(this.getRecordType().indexValue());
+        dout.writeShort(this.getRecordClass().indexValue());
+    }
+
+    /**
+     * Creates a byte array representation of this record. This is needed for tie-break tests according to draft-cheshire-dnsext-multicastdns-04.txt chapter 9.2.
+     * 
+     * @return byte array representation
+     */
+    protected byte[] toByteArray() {
+        try {
+            ByteArrayOutputStream bout = new ByteArrayOutputStream();
+            DataOutputStream dout = new DataOutputStream(bout);
+            this.toByteArray(dout);
+            dout.close();
+            return bout.toByteArray();
+        } catch (IOException e) {
+            throw new InternalError();
+        }
+    }
+
+    /**
+     * Does a lexicographic comparison of the byte array representation of this record and that record. This is needed for tie-break tests according to draft-cheshire-dnsext-multicastdns-04.txt chapter 9.2.
+     * 
+     * @param that
+     * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
+     */
+    public int compareTo(DNSEntry that) {
+        byte[] thisBytes = this.toByteArray();
+        byte[] thatBytes = that.toByteArray();
+        for (int i = 0, n = Math.min(thisBytes.length, thatBytes.length); i < n; i++) {
+            if (thisBytes[i] > thatBytes[i]) {
+                return 1;
+            } else if (thisBytes[i] < thatBytes[i]) {
+                return -1;
+            }
+        }
+        return thisBytes.length - thatBytes.length;
+    }
+
+    /**
+     * Overriden, to return a value which is consistent with the value returned by equals(Object).
+     */
+    @Override
+    public int hashCode() {
+        return this.getKey().hashCode() + this.getRecordType().indexValue() + this.getRecordClass().indexValue();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        StringBuilder aLog = new StringBuilder(200);
+        aLog.append("[" + this.getClass().getSimpleName() + "@" + System.identityHashCode(this));
+        aLog.append(" type: " + this.getRecordType());
+        aLog.append(", class: " + this.getRecordClass());
+        aLog.append((_unique ? "-unique," : ","));
+        aLog.append(" name: " + _name);
+        this.toString(aLog);
+        aLog.append("]");
+        return aLog.toString();
+    }
+
+    /**
+     * @param aLog
+     */
+    protected void toString(StringBuilder aLog) {
+        // Stub
+    }
+
+}
diff --git a/src/javax/jmdns/impl/DNSIncoming.java b/src/javax/jmdns/impl/DNSIncoming.java
new file mode 100644
index 0000000..ed5de5c
--- /dev/null
+++ b/src/javax/jmdns/impl/DNSIncoming.java
@@ -0,0 +1,578 @@
+// /Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.jmdns.impl.constants.DNSConstants;
+import javax.jmdns.impl.constants.DNSLabel;
+import javax.jmdns.impl.constants.DNSOptionCode;
+import javax.jmdns.impl.constants.DNSRecordClass;
+import javax.jmdns.impl.constants.DNSRecordType;
+import javax.jmdns.impl.constants.DNSResultCode;
+
+/**
+ * Parse an incoming DNS message into its components.
+ *
+ * @author Arthur van Hoff, Werner Randelshofer, Pierre Frisch, Daniel Bobbert
+ */
+public final class DNSIncoming extends DNSMessage {
+    private static Logger logger                                = Logger.getLogger(DNSIncoming.class.getName());
+
+    // This is a hack to handle a bug in the BonjourConformanceTest
+    // It is sending out target strings that don't follow the "domain name" format.
+    public static boolean USE_DOMAIN_NAME_FORMAT_FOR_SRV_TARGET = true;
+
+    public static class MessageInputStream extends ByteArrayInputStream {
+        private static Logger      logger1 = Logger.getLogger(MessageInputStream.class.getName());
+
+        final Map<Integer, String> _names;
+
+        public MessageInputStream(byte[] buffer, int length) {
+            this(buffer, 0, length);
+        }
+
+        /**
+         * @param buffer
+         * @param offset
+         * @param length
+         */
+        public MessageInputStream(byte[] buffer, int offset, int length) {
+            super(buffer, offset, length);
+            _names = new HashMap<Integer, String>();
+        }
+
+        public int readByte() {
+            return this.read();
+        }
+
+        public int readUnsignedShort() {
+            return (this.read() << 8) | this.read();
+        }
+
+        public int readInt() {
+            return (this.readUnsignedShort() << 16) | this.readUnsignedShort();
+        }
+
+        public byte[] readBytes(int len) {
+            byte bytes[] = new byte[len];
+            this.read(bytes, 0, len);
+            return bytes;
+        }
+
+        public String readUTF(int len) {
+            StringBuilder buffer = new StringBuilder(len);
+            for (int index = 0; index < len; index++) {
+                int ch = this.read();
+                switch (ch >> 4) {
+                    case 0:
+                    case 1:
+                    case 2:
+                    case 3:
+                    case 4:
+                    case 5:
+                    case 6:
+                    case 7:
+                        // 0xxxxxxx
+                        break;
+                    case 12:
+                    case 13:
+                        // 110x xxxx 10xx xxxx
+                        ch = ((ch & 0x1F) << 6) | (this.read() & 0x3F);
+                        index++;
+                        break;
+                    case 14:
+                        // 1110 xxxx 10xx xxxx 10xx xxxx
+                        ch = ((ch & 0x0f) << 12) | ((this.read() & 0x3F) << 6) | (this.read() & 0x3F);
+                        index++;
+                        index++;
+                        break;
+                    default:
+                        // 10xx xxxx, 1111 xxxx
+                        ch = ((ch & 0x3F) << 4) | (this.read() & 0x0f);
+                        index++;
+                        break;
+                }
+                buffer.append((char) ch);
+            }
+            return buffer.toString();
+        }
+
+        protected synchronized int peek() {
+            return (pos < count) ? (buf[pos] & 0xff) : -1;
+        }
+
+        public String readName() {
+            Map<Integer, StringBuilder> names = new HashMap<Integer, StringBuilder>();
+            StringBuilder buffer = new StringBuilder();
+            boolean finished = false;
+            while (!finished) {
+                int len = this.read();
+                if (len == 0) {
+                    finished = true;
+                    break;
+                }
+                switch (DNSLabel.labelForByte(len)) {
+                    case Standard:
+                        int offset = pos - 1;
+                        String label = this.readUTF(len) + ".";
+                        buffer.append(label);
+                        for (StringBuilder previousLabel : names.values()) {
+                            previousLabel.append(label);
+                        }
+                        names.put(Integer.valueOf(offset), new StringBuilder(label));
+                        break;
+                    case Compressed:
+                        int index = (DNSLabel.labelValue(len) << 8) | this.read();
+                        String compressedLabel = _names.get(Integer.valueOf(index));
+                        if (compressedLabel == null) {
+                            logger1.severe("bad domain name: possible circular name detected. Bad offset: 0x" + Integer.toHexString(index) + " at 0x" + Integer.toHexString(pos - 2));
+                            compressedLabel = "";
+                        }
+                        buffer.append(compressedLabel);
+                        for (StringBuilder previousLabel : names.values()) {
+                            previousLabel.append(compressedLabel);
+                        }
+                        finished = true;
+                        break;
+                    case Extended:
+                        // int extendedLabelClass = DNSLabel.labelValue(len);
+                        logger1.severe("Extended label are not currently supported.");
+                        break;
+                    case Unknown:
+                    default:
+                        logger1.severe("unsupported dns label type: '" + Integer.toHexString(len & 0xC0) + "'");
+                }
+            }
+            for (Integer index : names.keySet()) {
+                _names.put(index, names.get(index).toString());
+            }
+            return buffer.toString();
+        }
+
+        public String readNonNameString() {
+            int len = this.read();
+            return this.readUTF(len);
+        }
+
+    }
+
+    private final DatagramPacket     _packet;
+
+    private final long               _receivedTime;
+
+    private final MessageInputStream _messageInputStream;
+
+    private int                      _senderUDPPayload;
+
+    /**
+     * Parse a message from a datagram packet.
+     *
+     * @param packet
+     * @exception IOException
+     */
+    public DNSIncoming(DatagramPacket packet) throws IOException {
+        super(0, 0, packet.getPort() == DNSConstants.MDNS_PORT);
+        this._packet = packet;
+        InetAddress source = packet.getAddress();
+        this._messageInputStream = new MessageInputStream(packet.getData(), packet.getLength());
+        this._receivedTime = System.currentTimeMillis();
+        this._senderUDPPayload = DNSConstants.MAX_MSG_TYPICAL;
+
+        try {
+            this.setId(_messageInputStream.readUnsignedShort());
+            this.setFlags(_messageInputStream.readUnsignedShort());
+            int numQuestions = _messageInputStream.readUnsignedShort();
+            int numAnswers = _messageInputStream.readUnsignedShort();
+            int numAuthorities = _messageInputStream.readUnsignedShort();
+            int numAdditionals = _messageInputStream.readUnsignedShort();
+
+            // parse questions
+            if (numQuestions > 0) {
+                for (int i = 0; i < numQuestions; i++) {
+                    _questions.add(this.readQuestion());
+                }
+            }
+
+            // parse answers
+            if (numAnswers > 0) {
+                for (int i = 0; i < numAnswers; i++) {
+                    DNSRecord rec = this.readAnswer(source);
+                    if (rec != null) {
+                        // Add a record, if we were able to create one.
+                        _answers.add(rec);
+                    }
+                }
+            }
+
+            if (numAuthorities > 0) {
+                for (int i = 0; i < numAuthorities; i++) {
+                    DNSRecord rec = this.readAnswer(source);
+                    if (rec != null) {
+                        // Add a record, if we were able to create one.
+                        _authoritativeAnswers.add(rec);
+                    }
+                }
+            }
+
+            if (numAdditionals > 0) {
+                for (int i = 0; i < numAdditionals; i++) {
+                    DNSRecord rec = this.readAnswer(source);
+                    if (rec != null) {
+                        // Add a record, if we were able to create one.
+                        _additionals.add(rec);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            logger.log(Level.WARNING, "DNSIncoming() dump " + print(true) + "\n exception ", e);
+            // This ugly but some JVM don't implement the cause on IOException
+            IOException ioe = new IOException("DNSIncoming corrupted message");
+            ioe.initCause(e);
+            throw ioe;
+        }
+    }
+
+    private DNSIncoming(int flags, int id, boolean multicast, DatagramPacket packet, long receivedTime) {
+        super(flags, id, multicast);
+        this._packet = packet;
+        this._messageInputStream = new MessageInputStream(packet.getData(), packet.getLength());
+        this._receivedTime = receivedTime;
+    }
+
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Object#clone()
+     */
+    @Override
+    public DNSIncoming clone() {
+        DNSIncoming in = new DNSIncoming(this.getFlags(), this.getId(), this.isMulticast(), this._packet, this._receivedTime);
+         in._senderUDPPayload = this._senderUDPPayload;
+         in._questions.addAll(this._questions);
+         in._answers.addAll(this._answers);
+         in._authoritativeAnswers.addAll(this._authoritativeAnswers);
+         in._additionals.addAll(this._additionals);
+         return in;
+    }
+
+
+    private DNSQuestion readQuestion() {
+        String domain = _messageInputStream.readName();
+        DNSRecordType type = DNSRecordType.typeForIndex(_messageInputStream.readUnsignedShort());
+        if (type == DNSRecordType.TYPE_IGNORE) {
+            logger.log(Level.SEVERE, "Could not find record type: " + this.print(true));
+        }
+        int recordClassIndex = _messageInputStream.readUnsignedShort();
+        DNSRecordClass recordClass = DNSRecordClass.classForIndex(recordClassIndex);
+        boolean unique = recordClass.isUnique(recordClassIndex);
+        return DNSQuestion.newQuestion(domain, type, recordClass, unique);
+    }
+
+    private DNSRecord readAnswer(InetAddress source) {
+        String domain = _messageInputStream.readName();
+        DNSRecordType type = DNSRecordType.typeForIndex(_messageInputStream.readUnsignedShort());
+        if (type == DNSRecordType.TYPE_IGNORE) {
+            logger.log(Level.SEVERE, "Could not find record type. domain: " + domain + "\n" + this.print(true));
+        }
+        int recordClassIndex = _messageInputStream.readUnsignedShort();
+        DNSRecordClass recordClass = (type == DNSRecordType.TYPE_OPT ? DNSRecordClass.CLASS_UNKNOWN : DNSRecordClass.classForIndex(recordClassIndex));
+        if ((recordClass == DNSRecordClass.CLASS_UNKNOWN) && (type != DNSRecordType.TYPE_OPT)) {
+            logger.log(Level.SEVERE, "Could not find record class. domain: " + domain + " type: " + type + "\n" + this.print(true));
+        }
+        boolean unique = recordClass.isUnique(recordClassIndex);
+        int ttl = _messageInputStream.readInt();
+        int len = _messageInputStream.readUnsignedShort();
+        DNSRecord rec = null;
+
+        switch (type) {
+            case TYPE_A: // IPv4
+                rec = new DNSRecord.IPv4Address(domain, recordClass, unique, ttl, _messageInputStream.readBytes(len));
+                break;
+            case TYPE_AAAA: // IPv6
+                rec = new DNSRecord.IPv6Address(domain, recordClass, unique, ttl, _messageInputStream.readBytes(len));
+                break;
+            case TYPE_CNAME:
+            case TYPE_PTR:
+                String service = "";
+                service = _messageInputStream.readName();
+                if (service.length() > 0) {
+                    rec = new DNSRecord.Pointer(domain, recordClass, unique, ttl, service);
+                } else {
+                    logger.log(Level.WARNING, "PTR record of class: " + recordClass + ", there was a problem reading the service name of the answer for domain:" + domain);
+                }
+                break;
+            case TYPE_TXT:
+                rec = new DNSRecord.Text(domain, recordClass, unique, ttl, _messageInputStream.readBytes(len));
+                break;
+            case TYPE_SRV:
+                int priority = _messageInputStream.readUnsignedShort();
+                int weight = _messageInputStream.readUnsignedShort();
+                int port = _messageInputStream.readUnsignedShort();
+                String target = "";
+                // This is a hack to handle a bug in the BonjourConformanceTest
+                // It is sending out target strings that don't follow the "domain name" format.
+                if (USE_DOMAIN_NAME_FORMAT_FOR_SRV_TARGET) {
+                    target = _messageInputStream.readName();
+                } else {
+                    // [PJYF Nov 13 2010] Do we still need this? This looks really bad. All label are supposed to start by a length.
+                    target = _messageInputStream.readNonNameString();
+                }
+                rec = new DNSRecord.Service(domain, recordClass, unique, ttl, priority, weight, port, target);
+                break;
+            case TYPE_HINFO:
+                StringBuilder buf = new StringBuilder();
+                buf.append(_messageInputStream.readUTF(len));
+                int index = buf.indexOf(" ");
+                String cpu = (index > 0 ? buf.substring(0, index) : buf.toString()).trim();
+                String os = (index > 0 ? buf.substring(index + 1) : "").trim();
+                rec = new DNSRecord.HostInformation(domain, recordClass, unique, ttl, cpu, os);
+                break;
+            case TYPE_OPT:
+                DNSResultCode extendedResultCode = DNSResultCode.resultCodeForFlags(this.getFlags(), ttl);
+                int version = (ttl & 0x00ff0000) >> 16;
+                if (version == 0) {
+                    _senderUDPPayload = recordClassIndex;
+                    while (_messageInputStream.available() > 0) {
+                        // Read RDData
+                        int optionCodeInt = 0;
+                        DNSOptionCode optionCode = null;
+                        if (_messageInputStream.available() >= 2) {
+                            optionCodeInt = _messageInputStream.readUnsignedShort();
+                            optionCode = DNSOptionCode.resultCodeForFlags(optionCodeInt);
+                        } else {
+                            logger.log(Level.WARNING, "There was a problem reading the OPT record. Ignoring.");
+                            break;
+                        }
+                        int optionLength = 0;
+                        if (_messageInputStream.available() >= 2) {
+                            optionLength = _messageInputStream.readUnsignedShort();
+                        } else {
+                            logger.log(Level.WARNING, "There was a problem reading the OPT record. Ignoring.");
+                            break;
+                        }
+                        byte[] optiondata = new byte[0];
+                        if (_messageInputStream.available() >= optionLength) {
+                            optiondata = _messageInputStream.readBytes(optionLength);
+                        }
+                        //
+                        // We should really do something with those options.
+                        switch (optionCode) {
+                            case Owner:
+                                // Valid length values are 8, 14, 18 and 20
+                                // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+                                // |Opt|Len|V|S|Primary MAC|Wakeup MAC | Password |
+                                // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+                                //
+                                int ownerVersion = 0;
+                                int ownerSequence = 0;
+                                byte[] ownerPrimaryMacAddress = null;
+                                byte[] ownerWakeupMacAddress = null;
+                                byte[] ownerPassword = null;
+                                try {
+                                    ownerVersion = optiondata[0];
+                                    ownerSequence = optiondata[1];
+                                    ownerPrimaryMacAddress = new byte[] { optiondata[2], optiondata[3], optiondata[4], optiondata[5], optiondata[6], optiondata[7] };
+                                    ownerWakeupMacAddress = ownerPrimaryMacAddress;
+                                    if (optiondata.length > 8) {
+                                        // We have a wakeupMacAddress.
+                                        ownerWakeupMacAddress = new byte[] { optiondata[8], optiondata[9], optiondata[10], optiondata[11], optiondata[12], optiondata[13] };
+                                    }
+                                    if (optiondata.length == 18) {
+                                        // We have a short password.
+                                        ownerPassword = new byte[] { optiondata[14], optiondata[15], optiondata[16], optiondata[17] };
+                                    }
+                                    if (optiondata.length == 22) {
+                                        // We have a long password.
+                                        ownerPassword = new byte[] { optiondata[14], optiondata[15], optiondata[16], optiondata[17], optiondata[18], optiondata[19], optiondata[20], optiondata[21] };
+                                    }
+                                } catch (Exception exception) {
+                                    logger.warning("Malformed OPT answer. Option code: Owner data: " + this._hexString(optiondata));
+                                }
+                                if (logger.isLoggable(Level.FINE)) {
+                                    logger.fine("Unhandled Owner OPT version: " + ownerVersion + " sequence: " + ownerSequence + " MAC address: " + this._hexString(ownerPrimaryMacAddress)
+                                            + (ownerWakeupMacAddress != ownerPrimaryMacAddress ? " wakeup MAC address: " + this._hexString(ownerWakeupMacAddress) : "") + (ownerPassword != null ? " password: " + this._hexString(ownerPassword) : ""));
+                                }
+                                break;
+                            case LLQ:
+                            case NSID:
+                            case UL:
+                                if (logger.isLoggable(Level.FINE)) {
+                                    logger.log(Level.FINE, "There was an OPT answer. Option code: " + optionCode + " data: " + this._hexString(optiondata));
+                                }
+                                break;
+                            case Unknown:
+                                logger.log(Level.WARNING, "There was an OPT answer. Not currently handled. Option code: " + optionCodeInt + " data: " + this._hexString(optiondata));
+                                break;
+                            default:
+                                // This is to keep the compiler happy.
+                                break;
+                        }
+                    }
+                } else {
+                    logger.log(Level.WARNING, "There was an OPT answer. Wrong version number: " + version + " result code: " + extendedResultCode);
+                }
+                break;
+            default:
+                if (logger.isLoggable(Level.FINER)) {
+                    logger.finer("DNSIncoming() unknown type:" + type);
+                }
+                _messageInputStream.skip(len);
+                break;
+        }
+        if (rec != null) {
+            rec.setRecordSource(source);
+        }
+        return rec;
+    }
+
+    /**
+     * Debugging.
+     */
+    String print(boolean dump) {
+        StringBuilder buf = new StringBuilder();
+        buf.append(this.print());
+        if (dump) {
+            byte[] data = new byte[_packet.getLength()];
+            System.arraycopy(_packet.getData(), 0, data, 0, data.length);
+            buf.append(this.print(data));
+        }
+        return buf.toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder();
+        buf.append(isQuery() ? "dns[query," : "dns[response,");
+        if (_packet.getAddress() != null) {
+            buf.append(_packet.getAddress().getHostAddress());
+        }
+        buf.append(':');
+        buf.append(_packet.getPort());
+        buf.append(", length=");
+        buf.append(_packet.getLength());
+        buf.append(", id=0x");
+        buf.append(Integer.toHexString(this.getId()));
+        if (this.getFlags() != 0) {
+            buf.append(", flags=0x");
+            buf.append(Integer.toHexString(this.getFlags()));
+            if ((this.getFlags() & DNSConstants.FLAGS_QR_RESPONSE) != 0) {
+                buf.append(":r");
+            }
+            if ((this.getFlags() & DNSConstants.FLAGS_AA) != 0) {
+                buf.append(":aa");
+            }
+            if ((this.getFlags() & DNSConstants.FLAGS_TC) != 0) {
+                buf.append(":tc");
+            }
+        }
+        if (this.getNumberOfQuestions() > 0) {
+            buf.append(", questions=");
+            buf.append(this.getNumberOfQuestions());
+        }
+        if (this.getNumberOfAnswers() > 0) {
+            buf.append(", answers=");
+            buf.append(this.getNumberOfAnswers());
+        }
+        if (this.getNumberOfAuthorities() > 0) {
+            buf.append(", authorities=");
+            buf.append(this.getNumberOfAuthorities());
+        }
+        if (this.getNumberOfAdditionals() > 0) {
+            buf.append(", additionals=");
+            buf.append(this.getNumberOfAdditionals());
+        }
+        if (this.getNumberOfQuestions() > 0) {
+            buf.append("\nquestions:");
+            for (DNSQuestion question : _questions) {
+                buf.append("\n\t");
+                buf.append(question);
+            }
+        }
+        if (this.getNumberOfAnswers() > 0) {
+            buf.append("\nanswers:");
+            for (DNSRecord record : _answers) {
+                buf.append("\n\t");
+                buf.append(record);
+            }
+        }
+        if (this.getNumberOfAuthorities() > 0) {
+            buf.append("\nauthorities:");
+            for (DNSRecord record : _authoritativeAnswers) {
+                buf.append("\n\t");
+                buf.append(record);
+            }
+        }
+        if (this.getNumberOfAdditionals() > 0) {
+            buf.append("\nadditionals:");
+            for (DNSRecord record : _additionals) {
+                buf.append("\n\t");
+                buf.append(record);
+            }
+        }
+        buf.append("]");
+        return buf.toString();
+    }
+
+    /**
+     * Appends answers to this Incoming.
+     *
+     * @exception IllegalArgumentException
+     *                If not a query or if Truncated.
+     */
+    void append(DNSIncoming that) {
+        if (this.isQuery() && this.isTruncated() && that.isQuery()) {
+            this._questions.addAll(that.getQuestions());
+            this._answers.addAll(that.getAnswers());
+            this._authoritativeAnswers.addAll(that.getAuthorities());
+            this._additionals.addAll(that.getAdditionals());
+        } else {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    public int elapseSinceArrival() {
+        return (int) (System.currentTimeMillis() - _receivedTime);
+    }
+
+    /**
+     * This will return the default UDP payload except if an OPT record was found with a different size.
+     *
+     * @return the senderUDPPayload
+     */
+    public int getSenderUDPPayload() {
+        return this._senderUDPPayload;
+    }
+
+    private static final char[] _nibbleToHex = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+    /**
+     * Returns a hex-string for printing
+     *
+     * @param bytes
+     * @return Returns a hex-string which can be used within a SQL expression
+     */
+    private String _hexString(byte[] bytes) {
+
+        StringBuilder result = new StringBuilder(2 * bytes.length);
+
+        for (int i = 0; i < bytes.length; i++) {
+            int b = bytes[i] & 0xFF;
+            result.append(_nibbleToHex[b / 16]);
+            result.append(_nibbleToHex[b % 16]);
+        }
+
+        return result.toString();
+    }
+
+}
diff --git a/src/javax/jmdns/impl/DNSListener.java b/src/javax/jmdns/impl/DNSListener.java
new file mode 100644
index 0000000..d3618e1
--- /dev/null
+++ b/src/javax/jmdns/impl/DNSListener.java
@@ -0,0 +1,28 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl;
+
+// REMIND: Listener should follow Java idiom for listener or have a different
+// name.
+
+/**
+ * DNSListener. Listener for record updates.
+ * 
+ * @author Werner Randelshofer, Rick Blair
+ * @version 1.0 May 22, 2004 Created.
+ */
+interface DNSListener {
+    /**
+     * Update a DNS record.
+     * 
+     * @param dnsCache
+     *            record cache
+     * @param now
+     *            update date
+     * @param record
+     *            DNS record
+     */
+    void updateRecord(DNSCache dnsCache, long now, DNSEntry record);
+}
diff --git a/src/javax/jmdns/impl/DNSMessage.java b/src/javax/jmdns/impl/DNSMessage.java
new file mode 100644
index 0000000..6537705
--- /dev/null
+++ b/src/javax/jmdns/impl/DNSMessage.java
@@ -0,0 +1,307 @@
+/**
+ *
+ */
+package javax.jmdns.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.jmdns.impl.constants.DNSConstants;
+
+/**
+ * DNSMessage define a DNS message either incoming or outgoing.
+ * 
+ * @author Werner Randelshofer, Rick Blair, Pierre Frisch
+ */
+public abstract class DNSMessage {
+
+    /**
+     *
+     */
+    public static final boolean       MULTICAST = true;
+
+    /**
+     *
+     */
+    public static final boolean       UNICAST   = false;
+
+    // protected DatagramPacket _packet;
+    // protected int _off;
+    // protected int _len;
+    // protected byte[] _data;
+
+    private int                       _id;
+
+    boolean                           _multicast;
+
+    private int                       _flags;
+
+    protected final List<DNSQuestion> _questions;
+
+    protected final List<DNSRecord>   _answers;
+
+    protected final List<DNSRecord>   _authoritativeAnswers;
+
+    protected final List<DNSRecord>   _additionals;
+
+    /**
+     * @param flags
+     * @param id
+     * @param multicast
+     */
+    protected DNSMessage(int flags, int id, boolean multicast) {
+        super();
+        _flags = flags;
+        _id = id;
+        _multicast = multicast;
+        _questions = Collections.synchronizedList(new LinkedList<DNSQuestion>());
+        _answers = Collections.synchronizedList(new LinkedList<DNSRecord>());
+        _authoritativeAnswers = Collections.synchronizedList(new LinkedList<DNSRecord>());
+        _additionals = Collections.synchronizedList(new LinkedList<DNSRecord>());
+    }
+
+    // public DatagramPacket getPacket() {
+    // return _packet;
+    // }
+    //
+    // public int getOffset() {
+    // return _off;
+    // }
+    //
+    // public int getLength() {
+    // return _len;
+    // }
+    //
+    // public byte[] getData() {
+    // if ( _data == null ) _data = new byte[DNSConstants.MAX_MSG_TYPICAL];
+    // return _data;
+    // }
+
+    /**
+     * @return message id
+     */
+    public int getId() {
+        return (_multicast ? 0 : _id);
+    }
+
+    /**
+     * @param id
+     *            the id to set
+     */
+    public void setId(int id) {
+        this._id = id;
+    }
+
+    /**
+     * @return message flags
+     */
+    public int getFlags() {
+        return _flags;
+    }
+
+    /**
+     * @param flags
+     *            the flags to set
+     */
+    public void setFlags(int flags) {
+        this._flags = flags;
+    }
+
+    /**
+     * @return true if multicast
+     */
+    public boolean isMulticast() {
+        return _multicast;
+    }
+
+    /**
+     * @return list of questions
+     */
+    public Collection<? extends DNSQuestion> getQuestions() {
+        return _questions;
+    }
+
+    /**
+     * @return number of questions in the message
+     */
+    public int getNumberOfQuestions() {
+        return this.getQuestions().size();
+    }
+
+    public Collection<? extends DNSRecord> getAllAnswers() {
+        List<DNSRecord> aList = new ArrayList<DNSRecord>(_answers.size() + _authoritativeAnswers.size() + _additionals.size());
+        aList.addAll(_answers);
+        aList.addAll(_authoritativeAnswers);
+        aList.addAll(_additionals);
+        return aList;
+    }
+
+    /**
+     * @return list of answers
+     */
+    public Collection<? extends DNSRecord> getAnswers() {
+        return _answers;
+    }
+
+    /**
+     * @return number of answers in the message
+     */
+    public int getNumberOfAnswers() {
+        return this.getAnswers().size();
+    }
+
+    /**
+     * @return list of authorities
+     */
+    public Collection<? extends DNSRecord> getAuthorities() {
+        return _authoritativeAnswers;
+    }
+
+    /**
+     * @return number of authorities in the message
+     */
+    public int getNumberOfAuthorities() {
+        return this.getAuthorities().size();
+    }
+
+    /**
+     * @return list of additional answers
+     */
+    public Collection<? extends DNSRecord> getAdditionals() {
+        return _additionals;
+    }
+
+    /**
+     * @return number of additional in the message
+     */
+    public int getNumberOfAdditionals() {
+        return this.getAdditionals().size();
+    }
+
+    /**
+     * Check if the message is truncated.
+     * 
+     * @return true if the message was truncated
+     */
+    public boolean isTruncated() {
+        return (_flags & DNSConstants.FLAGS_TC) != 0;
+    }
+
+    /**
+     * Check if the message is a query.
+     * 
+     * @return true is the message is a query
+     */
+    public boolean isQuery() {
+        return (_flags & DNSConstants.FLAGS_QR_MASK) == DNSConstants.FLAGS_QR_QUERY;
+    }
+
+    /**
+     * Check if the message is a response.
+     * 
+     * @return true is the message is a response
+     */
+    public boolean isResponse() {
+        return (_flags & DNSConstants.FLAGS_QR_MASK) == DNSConstants.FLAGS_QR_RESPONSE;
+    }
+
+    /**
+     * Check if the message is empty
+     * 
+     * @return true is the message is empty
+     */
+    public boolean isEmpty() {
+        return (this.getNumberOfQuestions() + this.getNumberOfAnswers() + this.getNumberOfAuthorities() + this.getNumberOfAdditionals()) == 0;
+    }
+
+    /**
+     * Debugging.
+     */
+    String print() {
+        StringBuffer buf = new StringBuffer(200);
+        buf.append(this.toString());
+        buf.append("\n");
+        for (DNSQuestion question : _questions) {
+            buf.append("\tquestion:      ");
+            buf.append(question);
+            buf.append("\n");
+        }
+        for (DNSRecord answer : _answers) {
+            buf.append("\tanswer:        ");
+            buf.append(answer);
+            buf.append("\n");
+        }
+        for (DNSRecord answer : _authoritativeAnswers) {
+            buf.append("\tauthoritative: ");
+            buf.append(answer);
+            buf.append("\n");
+        }
+        for (DNSRecord answer : _additionals) {
+            buf.append("\tadditional:    ");
+            buf.append(answer);
+            buf.append("\n");
+        }
+        return buf.toString();
+    }
+
+    /**
+     * Debugging.
+     * 
+     * @param data
+     * @return data dump
+     */
+    protected String print(byte[] data) {
+        StringBuilder buf = new StringBuilder(4000);
+        for (int off = 0, len = data.length; off < len; off += 32) {
+            int n = Math.min(32, len - off);
+            if (off < 0x10) {
+                buf.append(' ');
+            }
+            if (off < 0x100) {
+                buf.append(' ');
+            }
+            if (off < 0x1000) {
+                buf.append(' ');
+            }
+            buf.append(Integer.toHexString(off));
+            buf.append(':');
+            int index = 0;
+            for (index = 0; index < n; index++) {
+                if ((index % 8) == 0) {
+                    buf.append(' ');
+                }
+                buf.append(Integer.toHexString((data[off + index] & 0xF0) >> 4));
+                buf.append(Integer.toHexString((data[off + index] & 0x0F) >> 0));
+            }
+            // for incomplete lines
+            if (index < 32) {
+                for (int i = index; i < 32; i++) {
+                    if ((i % 8) == 0) {
+                        buf.append(' ');
+                    }
+                    buf.append("  ");
+                }
+            }
+            buf.append("    ");
+            for (index = 0; index < n; index++) {
+                if ((index % 8) == 0) {
+                    buf.append(' ');
+                }
+                int ch = data[off + index] & 0xFF;
+                buf.append(((ch > ' ') && (ch < 127)) ? (char) ch : '.');
+            }
+            buf.append("\n");
+
+            // limit message size
+            if (off + 32 >= 2048) {
+                buf.append("....\n");
+                break;
+            }
+        }
+        return buf.toString();
+    }
+
+}
diff --git a/src/javax/jmdns/impl/DNSOutgoing.java b/src/javax/jmdns/impl/DNSOutgoing.java
new file mode 100644
index 0000000..c3ba24e
--- /dev/null
+++ b/src/javax/jmdns/impl/DNSOutgoing.java
@@ -0,0 +1,451 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jmdns.impl.constants.DNSConstants;
+import javax.jmdns.impl.constants.DNSRecordClass;
+
+/**
+ * An outgoing DNS message.
+ * 
+ * @author Arthur van Hoff, Rick Blair, Werner Randelshofer
+ */
+public final class DNSOutgoing extends DNSMessage {
+
+    public static class MessageOutputStream extends ByteArrayOutputStream {
+        private final DNSOutgoing _out;
+
+        private final int         _offset;
+
+        /**
+         * Creates a new message stream, with a buffer capacity of the specified size, in bytes.
+         * 
+         * @param size
+         *            the initial size.
+         * @exception IllegalArgumentException
+         *                if size is negative.
+         */
+        MessageOutputStream(int size, DNSOutgoing out) {
+            this(size, out, 0);
+        }
+
+        MessageOutputStream(int size, DNSOutgoing out, int offset) {
+            super(size);
+            _out = out;
+            _offset = offset;
+        }
+
+        void writeByte(int value) {
+            this.write(value & 0xFF);
+        }
+
+        void writeBytes(String str, int off, int len) {
+            for (int i = 0; i < len; i++) {
+                writeByte(str.charAt(off + i));
+            }
+        }
+
+        void writeBytes(byte data[]) {
+            if (data != null) {
+                writeBytes(data, 0, data.length);
+            }
+        }
+
+        void writeBytes(byte data[], int off, int len) {
+            for (int i = 0; i < len; i++) {
+                writeByte(data[off + i]);
+            }
+        }
+
+        void writeShort(int value) {
+            writeByte(value >> 8);
+            writeByte(value);
+        }
+
+        void writeInt(int value) {
+            writeShort(value >> 16);
+            writeShort(value);
+        }
+
+        void writeUTF(String str, int off, int len) {
+            // compute utf length
+            int utflen = 0;
+            for (int i = 0; i < len; i++) {
+                int ch = str.charAt(off + i);
+                if ((ch >= 0x0001) && (ch <= 0x007F)) {
+                    utflen += 1;
+                } else {
+                    if (ch > 0x07FF) {
+                        utflen += 3;
+                    } else {
+                        utflen += 2;
+                    }
+                }
+            }
+            // write utf length
+            writeByte(utflen);
+            // write utf data
+            for (int i = 0; i < len; i++) {
+                int ch = str.charAt(off + i);
+                if ((ch >= 0x0001) && (ch <= 0x007F)) {
+                    writeByte(ch);
+                } else {
+                    if (ch > 0x07FF) {
+                        writeByte(0xE0 | ((ch >> 12) & 0x0F));
+                        writeByte(0x80 | ((ch >> 6) & 0x3F));
+                        writeByte(0x80 | ((ch >> 0) & 0x3F));
+                    } else {
+                        writeByte(0xC0 | ((ch >> 6) & 0x1F));
+                        writeByte(0x80 | ((ch >> 0) & 0x3F));
+                    }
+                }
+            }
+        }
+
+        void writeName(String name) {
+            writeName(name, true);
+        }
+
+        void writeName(String name, boolean useCompression) {
+            String aName = name;
+            while (true) {
+                int n = aName.indexOf('.');
+                if (n < 0) {
+                    n = aName.length();
+                }
+                if (n <= 0) {
+                    writeByte(0);
+                    return;
+                }
+                String label = aName.substring(0, n);
+                if (useCompression && USE_DOMAIN_NAME_COMPRESSION) {
+                    Integer offset = _out._names.get(aName);
+                    if (offset != null) {
+                        int val = offset.intValue();
+                        writeByte((val >> 8) | 0xC0);
+                        writeByte(val & 0xFF);
+                        return;
+                    }
+                    _out._names.put(aName, Integer.valueOf(this.size() + _offset));
+                    writeUTF(label, 0, label.length());
+                } else {
+                    writeUTF(label, 0, label.length());
+                }
+                aName = aName.substring(n);
+                if (aName.startsWith(".")) {
+                    aName = aName.substring(1);
+                }
+            }
+        }
+
+        void writeQuestion(DNSQuestion question) {
+            writeName(question.getName());
+            writeShort(question.getRecordType().indexValue());
+            writeShort(question.getRecordClass().indexValue());
+        }
+
+        void writeRecord(DNSRecord rec, long now) {
+            writeName(rec.getName());
+            writeShort(rec.getRecordType().indexValue());
+            writeShort(rec.getRecordClass().indexValue() | ((rec.isUnique() && _out.isMulticast()) ? DNSRecordClass.CLASS_UNIQUE : 0));
+            writeInt((now == 0) ? rec.getTTL() : rec.getRemainingTTL(now));
+
+            // We need to take into account the 2 size bytes
+            MessageOutputStream record = new MessageOutputStream(512, _out, _offset + this.size() + 2);
+            rec.write(record);
+            byte[] byteArray = record.toByteArray();
+
+            writeShort(byteArray.length);
+            write(byteArray, 0, byteArray.length);
+        }
+
+    }
+
+    /**
+     * This can be used to turn off domain name compression. This was helpful for tracking problems interacting with other mdns implementations.
+     */
+    public static boolean             USE_DOMAIN_NAME_COMPRESSION = true;
+
+    Map<String, Integer>              _names;
+
+    private int                       _maxUDPPayload;
+
+    private final MessageOutputStream _questionsBytes;
+
+    private final MessageOutputStream _answersBytes;
+
+    private final MessageOutputStream _authoritativeAnswersBytes;
+
+    private final MessageOutputStream _additionalsAnswersBytes;
+
+    private final static int          HEADER_SIZE                 = 12;
+
+    /**
+     * Create an outgoing multicast query or response.
+     * 
+     * @param flags
+     */
+    public DNSOutgoing(int flags) {
+        this(flags, true, DNSConstants.MAX_MSG_TYPICAL);
+    }
+
+    /**
+     * Create an outgoing query or response.
+     * 
+     * @param flags
+     * @param multicast
+     */
+    public DNSOutgoing(int flags, boolean multicast) {
+        this(flags, multicast, DNSConstants.MAX_MSG_TYPICAL);
+    }
+
+    /**
+     * Create an outgoing query or response.
+     * 
+     * @param flags
+     * @param multicast
+     * @param senderUDPPayload
+     *            The sender's UDP payload size is the number of bytes of the largest UDP payload that can be reassembled and delivered in the sender's network stack.
+     */
+    public DNSOutgoing(int flags, boolean multicast, int senderUDPPayload) {
+        super(flags, 0, multicast);
+        _names = new HashMap<String, Integer>();
+        _maxUDPPayload = (senderUDPPayload > 0 ? senderUDPPayload : DNSConstants.MAX_MSG_TYPICAL);
+        _questionsBytes = new MessageOutputStream(senderUDPPayload, this);
+        _answersBytes = new MessageOutputStream(senderUDPPayload, this);
+        _authoritativeAnswersBytes = new MessageOutputStream(senderUDPPayload, this);
+        _additionalsAnswersBytes = new MessageOutputStream(senderUDPPayload, this);
+    }
+
+    /**
+     * Return the number of byte available in the message.
+     * 
+     * @return available space
+     */
+    public int availableSpace() {
+        return _maxUDPPayload - HEADER_SIZE - _questionsBytes.size() - _answersBytes.size() - _authoritativeAnswersBytes.size() - _additionalsAnswersBytes.size();
+    }
+
+    /**
+     * Add a question to the message.
+     * 
+     * @param rec
+     * @exception IOException
+     */
+    public void addQuestion(DNSQuestion rec) throws IOException {
+        MessageOutputStream record = new MessageOutputStream(512, this);
+        record.writeQuestion(rec);
+        byte[] byteArray = record.toByteArray();
+        if (byteArray.length < this.availableSpace()) {
+            _questions.add(rec);
+            _questionsBytes.write(byteArray, 0, byteArray.length);
+        } else {
+            throw new IOException("message full");
+        }
+    }
+
+    /**
+     * Add an answer if it is not suppressed.
+     * 
+     * @param in
+     * @param rec
+     * @exception IOException
+     */
+    public void addAnswer(DNSIncoming in, DNSRecord rec) throws IOException {
+        if ((in == null) || !rec.suppressedBy(in)) {
+            this.addAnswer(rec, 0);
+        }
+    }
+
+    /**
+     * Add an answer to the message.
+     * 
+     * @param rec
+     * @param now
+     * @exception IOException
+     */
+    public void addAnswer(DNSRecord rec, long now) throws IOException {
+        if (rec != null) {
+            if ((now == 0) || !rec.isExpired(now)) {
+                MessageOutputStream record = new MessageOutputStream(512, this);
+                record.writeRecord(rec, now);
+                byte[] byteArray = record.toByteArray();
+                if (byteArray.length < this.availableSpace()) {
+                    _answers.add(rec);
+                    _answersBytes.write(byteArray, 0, byteArray.length);
+                } else {
+                    throw new IOException("message full");
+                }
+            }
+        }
+    }
+
+    /**
+     * Add an authoritative answer to the message.
+     * 
+     * @param rec
+     * @exception IOException
+     */
+    public void addAuthorativeAnswer(DNSRecord rec) throws IOException {
+        MessageOutputStream record = new MessageOutputStream(512, this);
+        record.writeRecord(rec, 0);
+        byte[] byteArray = record.toByteArray();
+        if (byteArray.length < this.availableSpace()) {
+            _authoritativeAnswers.add(rec);
+            _authoritativeAnswersBytes.write(byteArray, 0, byteArray.length);
+        } else {
+            throw new IOException("message full");
+        }
+    }
+
+    /**
+     * Add an additional answer to the record. Omit if there is no room.
+     * 
+     * @param in
+     * @param rec
+     * @exception IOException
+     */
+    public void addAdditionalAnswer(DNSIncoming in, DNSRecord rec) throws IOException {
+        MessageOutputStream record = new MessageOutputStream(512, this);
+        record.writeRecord(rec, 0);
+        byte[] byteArray = record.toByteArray();
+        if (byteArray.length < this.availableSpace()) {
+            _additionals.add(rec);
+            _additionalsAnswersBytes.write(byteArray, 0, byteArray.length);
+        } else {
+            throw new IOException("message full");
+        }
+    }
+
+    /**
+     * Builds the final message buffer to be send and returns it.
+     * 
+     * @return bytes to send.
+     */
+    public byte[] data() {
+        long now = System.currentTimeMillis(); // System.currentTimeMillis()
+        _names.clear();
+
+        MessageOutputStream message = new MessageOutputStream(_maxUDPPayload, this);
+        message.writeShort(_multicast ? 0 : this.getId());
+        message.writeShort(this.getFlags());
+        message.writeShort(this.getNumberOfQuestions());
+        message.writeShort(this.getNumberOfAnswers());
+        message.writeShort(this.getNumberOfAuthorities());
+        message.writeShort(this.getNumberOfAdditionals());
+        for (DNSQuestion question : _questions) {
+            message.writeQuestion(question);
+        }
+        for (DNSRecord record : _answers) {
+            message.writeRecord(record, now);
+        }
+        for (DNSRecord record : _authoritativeAnswers) {
+            message.writeRecord(record, now);
+        }
+        for (DNSRecord record : _additionals) {
+            message.writeRecord(record, now);
+        }
+        return message.toByteArray();
+    }
+
+    @Override
+    public boolean isQuery() {
+        return (this.getFlags() & DNSConstants.FLAGS_QR_MASK) == DNSConstants.FLAGS_QR_QUERY;
+    }
+
+    /**
+     * Debugging.
+     */
+    String print(boolean dump) {
+        StringBuilder buf = new StringBuilder();
+        buf.append(this.print());
+        if (dump) {
+            buf.append(this.print(this.data()));
+        }
+        return buf.toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer buf = new StringBuffer();
+        buf.append(isQuery() ? "dns[query:" : "dns[response:");
+        buf.append(" id=0x");
+        buf.append(Integer.toHexString(this.getId()));
+        if (this.getFlags() != 0) {
+            buf.append(", flags=0x");
+            buf.append(Integer.toHexString(this.getFlags()));
+            if ((this.getFlags() & DNSConstants.FLAGS_QR_RESPONSE) != 0) {
+                buf.append(":r");
+            }
+            if ((this.getFlags() & DNSConstants.FLAGS_AA) != 0) {
+                buf.append(":aa");
+            }
+            if ((this.getFlags() & DNSConstants.FLAGS_TC) != 0) {
+                buf.append(":tc");
+            }
+        }
+        if (this.getNumberOfQuestions() > 0) {
+            buf.append(", questions=");
+            buf.append(this.getNumberOfQuestions());
+        }
+        if (this.getNumberOfAnswers() > 0) {
+            buf.append(", answers=");
+            buf.append(this.getNumberOfAnswers());
+        }
+        if (this.getNumberOfAuthorities() > 0) {
+            buf.append(", authorities=");
+            buf.append(this.getNumberOfAuthorities());
+        }
+        if (this.getNumberOfAdditionals() > 0) {
+            buf.append(", additionals=");
+            buf.append(this.getNumberOfAdditionals());
+        }
+        if (this.getNumberOfQuestions() > 0) {
+            buf.append("\nquestions:");
+            for (DNSQuestion question : _questions) {
+                buf.append("\n\t");
+                buf.append(question);
+            }
+        }
+        if (this.getNumberOfAnswers() > 0) {
+            buf.append("\nanswers:");
+            for (DNSRecord record : _answers) {
+                buf.append("\n\t");
+                buf.append(record);
+            }
+        }
+        if (this.getNumberOfAuthorities() > 0) {
+            buf.append("\nauthorities:");
+            for (DNSRecord record : _authoritativeAnswers) {
+                buf.append("\n\t");
+                buf.append(record);
+            }
+        }
+        if (this.getNumberOfAdditionals() > 0) {
+            buf.append("\nadditionals:");
+            for (DNSRecord record : _additionals) {
+                buf.append("\n\t");
+                buf.append(record);
+            }
+        }
+        buf.append("\nnames=");
+        buf.append(_names);
+        buf.append("]");
+        return buf.toString();
+    }
+
+    /**
+     * @return the maxUDPPayload
+     */
+    public int getMaxUDPPayload() {
+        return this._maxUDPPayload;
+    }
+
+}
diff --git a/src/javax/jmdns/impl/DNSQuestion.java b/src/javax/jmdns/impl/DNSQuestion.java
new file mode 100644
index 0000000..2125bc8
--- /dev/null
+++ b/src/javax/jmdns/impl/DNSQuestion.java
@@ -0,0 +1,328 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl;
+
+import java.net.InetAddress;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.jmdns.ServiceInfo;
+import javax.jmdns.ServiceInfo.Fields;
+import javax.jmdns.impl.JmDNSImpl.ServiceTypeEntry;
+import javax.jmdns.impl.constants.DNSConstants;
+import javax.jmdns.impl.constants.DNSRecordClass;
+import javax.jmdns.impl.constants.DNSRecordType;
+
+/**
+ * A DNS question.
+ * 
+ * @author Arthur van Hoff, Pierre Frisch
+ */
+public class DNSQuestion extends DNSEntry {
+    private static Logger logger = Logger.getLogger(DNSQuestion.class.getName());
+
+    /**
+     * Address question.
+     */
+    private static class DNS4Address extends DNSQuestion {
+        DNS4Address(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+            super(name, type, recordClass, unique);
+        }
+
+        @Override
+        public void addAnswers(JmDNSImpl jmDNSImpl, Set<DNSRecord> answers) {
+            DNSRecord answer = jmDNSImpl.getLocalHost().getDNSAddressRecord(this.getRecordType(), DNSRecordClass.UNIQUE, DNSConstants.DNS_TTL);
+            if (answer != null) {
+                answers.add(answer);
+            }
+        }
+
+        @Override
+        public boolean iAmTheOnlyOne(JmDNSImpl jmDNSImpl) {
+            String name = this.getName().toLowerCase();
+            return jmDNSImpl.getLocalHost().getName().equals(name) || jmDNSImpl.getServices().keySet().contains(name);
+        }
+
+    }
+
+    /**
+     * Address question.
+     */
+    private static class DNS6Address extends DNSQuestion {
+        DNS6Address(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+            super(name, type, recordClass, unique);
+        }
+
+        @Override
+        public void addAnswers(JmDNSImpl jmDNSImpl, Set<DNSRecord> answers) {
+            DNSRecord answer = jmDNSImpl.getLocalHost().getDNSAddressRecord(this.getRecordType(), DNSRecordClass.UNIQUE, DNSConstants.DNS_TTL);
+            if (answer != null) {
+                answers.add(answer);
+            }
+        }
+
+        @Override
+        public boolean iAmTheOnlyOne(JmDNSImpl jmDNSImpl) {
+            String name = this.getName().toLowerCase();
+            return jmDNSImpl.getLocalHost().getName().equals(name) || jmDNSImpl.getServices().keySet().contains(name);
+        }
+
+    }
+
+    /**
+     * Host Information question.
+     */
+    private static class HostInformation extends DNSQuestion {
+        HostInformation(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+            super(name, type, recordClass, unique);
+        }
+    }
+
+    /**
+     * Pointer question.
+     */
+    private static class Pointer extends DNSQuestion {
+        Pointer(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+            super(name, type, recordClass, unique);
+        }
+
+        @Override
+        public void addAnswers(JmDNSImpl jmDNSImpl, Set<DNSRecord> answers) {
+            // find matching services
+            for (ServiceInfo serviceInfo : jmDNSImpl.getServices().values()) {
+                this.addAnswersForServiceInfo(jmDNSImpl, answers, (ServiceInfoImpl) serviceInfo);
+            }
+            if (this.isServicesDiscoveryMetaQuery()) {
+                for (String serviceType : jmDNSImpl.getServiceTypes().keySet()) {
+                    ServiceTypeEntry typeEntry = jmDNSImpl.getServiceTypes().get(serviceType);
+                    answers.add(new DNSRecord.Pointer("_services._dns-sd._udp.local.", DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE, DNSConstants.DNS_TTL, typeEntry.getType()));
+                }
+            } else if (this.isReverseLookup()) {
+                String ipValue = this.getQualifiedNameMap().get(Fields.Instance);
+                if ((ipValue != null) && (ipValue.length() > 0)) {
+                    InetAddress address = jmDNSImpl.getLocalHost().getInetAddress();
+                    String hostIPAddress = (address != null ? address.getHostAddress() : "");
+                    if (ipValue.equalsIgnoreCase(hostIPAddress)) {
+                        if (this.isV4ReverseLookup()) {
+                            answers.add(jmDNSImpl.getLocalHost().getDNSReverseAddressRecord(DNSRecordType.TYPE_A, DNSRecordClass.NOT_UNIQUE, DNSConstants.DNS_TTL));
+                        }
+                        if (this.isV6ReverseLookup()) {
+                            answers.add(jmDNSImpl.getLocalHost().getDNSReverseAddressRecord(DNSRecordType.TYPE_AAAA, DNSRecordClass.NOT_UNIQUE, DNSConstants.DNS_TTL));
+                        }
+                    }
+                }
+            } else if (this.isDomainDiscoveryQuery()) {
+                // FIXME [PJYF Nov 16 2010] We do not currently support domain discovery
+            }
+        }
+
+    }
+
+    /**
+     * Service question.
+     */
+    private static class Service extends DNSQuestion {
+        Service(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+            super(name, type, recordClass, unique);
+        }
+
+        @Override
+        public void addAnswers(JmDNSImpl jmDNSImpl, Set<DNSRecord> answers) {
+            String loname = this.getName().toLowerCase();
+            if (jmDNSImpl.getLocalHost().getName().equalsIgnoreCase(loname)) {
+                // type = DNSConstants.TYPE_A;
+                answers.addAll(jmDNSImpl.getLocalHost().answers(this.isUnique(), DNSConstants.DNS_TTL));
+                return;
+            }
+            // Service type request
+            if (jmDNSImpl.getServiceTypes().containsKey(loname)) {
+                DNSQuestion question = new Pointer(this.getName(), DNSRecordType.TYPE_PTR, this.getRecordClass(), this.isUnique());
+                question.addAnswers(jmDNSImpl, answers);
+                return;
+            }
+
+            this.addAnswersForServiceInfo(jmDNSImpl, answers, (ServiceInfoImpl) jmDNSImpl.getServices().get(loname));
+        }
+
+        @Override
+        public boolean iAmTheOnlyOne(JmDNSImpl jmDNSImpl) {
+            String name = this.getName().toLowerCase();
+            return jmDNSImpl.getLocalHost().getName().equals(name) || jmDNSImpl.getServices().keySet().contains(name);
+        }
+
+    }
+
+    /**
+     * Text question.
+     */
+    private static class Text extends DNSQuestion {
+        Text(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+            super(name, type, recordClass, unique);
+        }
+
+        @Override
+        public void addAnswers(JmDNSImpl jmDNSImpl, Set<DNSRecord> answers) {
+            this.addAnswersForServiceInfo(jmDNSImpl, answers, (ServiceInfoImpl) jmDNSImpl.getServices().get(this.getName().toLowerCase()));
+        }
+
+        @Override
+        public boolean iAmTheOnlyOne(JmDNSImpl jmDNSImpl) {
+            String name = this.getName().toLowerCase();
+            return jmDNSImpl.getLocalHost().getName().equals(name) || jmDNSImpl.getServices().keySet().contains(name);
+        }
+
+    }
+
+    /**
+     * AllRecords question.
+     */
+    private static class AllRecords extends DNSQuestion {
+        AllRecords(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+            super(name, type, recordClass, unique);
+        }
+
+        @Override
+        public boolean isSameType(DNSEntry entry) {
+            // We match all non null entry
+            return (entry != null);
+        }
+
+        @Override
+        public void addAnswers(JmDNSImpl jmDNSImpl, Set<DNSRecord> answers) {
+            String loname = this.getName().toLowerCase();
+            if (jmDNSImpl.getLocalHost().getName().equalsIgnoreCase(loname)) {
+                // type = DNSConstants.TYPE_A;
+                answers.addAll(jmDNSImpl.getLocalHost().answers(this.isUnique(), DNSConstants.DNS_TTL));
+                return;
+            }
+            // Service type request
+            if (jmDNSImpl.getServiceTypes().containsKey(loname)) {
+                DNSQuestion question = new Pointer(this.getName(), DNSRecordType.TYPE_PTR, this.getRecordClass(), this.isUnique());
+                question.addAnswers(jmDNSImpl, answers);
+                return;
+            }
+
+            this.addAnswersForServiceInfo(jmDNSImpl, answers, (ServiceInfoImpl) jmDNSImpl.getServices().get(loname));
+        }
+
+        @Override
+        public boolean iAmTheOnlyOne(JmDNSImpl jmDNSImpl) {
+            String name = this.getName().toLowerCase();
+            return jmDNSImpl.getLocalHost().getName().equals(name) || jmDNSImpl.getServices().keySet().contains(name);
+        }
+
+    }
+
+    DNSQuestion(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+        super(name, type, recordClass, unique);
+    }
+
+    /**
+     * Create a question.
+     * 
+     * @param name
+     *            DNS name to be resolved
+     * @param type
+     *            Record type to resolve
+     * @param recordClass
+     *            Record class to resolve
+     * @param unique
+     *            Request unicast response (Currently not supported in this implementation)
+     * @return new question
+     */
+    public static DNSQuestion newQuestion(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+        switch (type) {
+            case TYPE_A:
+                return new DNS4Address(name, type, recordClass, unique);
+            case TYPE_A6:
+                return new DNS6Address(name, type, recordClass, unique);
+            case TYPE_AAAA:
+                return new DNS6Address(name, type, recordClass, unique);
+            case TYPE_ANY:
+                return new AllRecords(name, type, recordClass, unique);
+            case TYPE_HINFO:
+                return new HostInformation(name, type, recordClass, unique);
+            case TYPE_PTR:
+                return new Pointer(name, type, recordClass, unique);
+            case TYPE_SRV:
+                return new Service(name, type, recordClass, unique);
+            case TYPE_TXT:
+                return new Text(name, type, recordClass, unique);
+            default:
+                return new DNSQuestion(name, type, recordClass, unique);
+        }
+    }
+
+    /**
+     * Check if this question is answered by a given DNS record.
+     */
+    boolean answeredBy(DNSEntry rec) {
+        return this.isSameRecordClass(rec) && this.isSameType(rec) && this.getName().equals(rec.getName());
+    }
+
+    /**
+     * Adds answers to the list for our question.
+     * 
+     * @param jmDNSImpl
+     *            DNS holding the records
+     * @param answers
+     *            List of previous answer to append.
+     */
+    public void addAnswers(JmDNSImpl jmDNSImpl, Set<DNSRecord> answers) {
+        // By default we do nothing
+    }
+
+    protected void addAnswersForServiceInfo(JmDNSImpl jmDNSImpl, Set<DNSRecord> answers, ServiceInfoImpl info) {
+        if ((info != null) && info.isAnnounced()) {
+            if (this.getName().equalsIgnoreCase(info.getQualifiedName()) || this.getName().equalsIgnoreCase(info.getType())) {
+                answers.addAll(jmDNSImpl.getLocalHost().answers(DNSRecordClass.UNIQUE, DNSConstants.DNS_TTL));
+                answers.addAll(info.answers(DNSRecordClass.UNIQUE, DNSConstants.DNS_TTL, jmDNSImpl.getLocalHost()));
+            }
+            if (logger.isLoggable(Level.FINER)) {
+                logger.finer(jmDNSImpl.getName() + " DNSQuestion(" + this.getName() + ").addAnswersForServiceInfo(): info: " + info + "\n" + answers);
+            }
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSEntry#isStale(long)
+     */
+    @Override
+    public boolean isStale(long now) {
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSEntry#isExpired(long)
+     */
+    @Override
+    public boolean isExpired(long now) {
+        return false;
+    }
+
+    /**
+     * Checks if we are the only to be able to answer that question.
+     * 
+     * @param jmDNSImpl
+     *            DNS holding the records
+     * @return <code>true</code> if we are the only one with the answer to the question, <code>false</code> otherwise.
+     */
+    public boolean iAmTheOnlyOne(JmDNSImpl jmDNSImpl) {
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSEntry#toString(java.lang.StringBuilder)
+     */
+    @Override
+    public void toString(StringBuilder aLog) {
+        // do nothing
+    }
+
+}
\ No newline at end of file
diff --git a/src/javax/jmdns/impl/DNSRecord.java b/src/javax/jmdns/impl/DNSRecord.java
new file mode 100644
index 0000000..d0ff6f3
--- /dev/null
+++ b/src/javax/jmdns/impl/DNSRecord.java
@@ -0,0 +1,1025 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.jmdns.ServiceEvent;
+import javax.jmdns.ServiceInfo;
+import javax.jmdns.ServiceInfo.Fields;
+import javax.jmdns.impl.DNSOutgoing.MessageOutputStream;
+import javax.jmdns.impl.constants.DNSConstants;
+import javax.jmdns.impl.constants.DNSRecordClass;
+import javax.jmdns.impl.constants.DNSRecordType;
+
+/**
+ * DNS record
+ *
+ * @author Arthur van Hoff, Rick Blair, Werner Randelshofer, Pierre Frisch
+ */
+public abstract class DNSRecord extends DNSEntry {
+    private static Logger logger = Logger.getLogger(DNSRecord.class.getName());
+    private int           _ttl;
+    private long          _created;
+
+    /**
+     * This source is mainly for debugging purposes, should be the address that sent this record.
+     */
+    private InetAddress   _source;
+
+    /**
+     * Create a DNSRecord with a name, type, class, and ttl.
+     */
+    DNSRecord(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique, int ttl) {
+        super(name, type, recordClass, unique);
+        this._ttl = ttl;
+        this._created = System.currentTimeMillis();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSEntry#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object other) {
+        return (other instanceof DNSRecord) && super.equals(other) && sameValue((DNSRecord) other);
+    }
+
+    /**
+     * True if this record has the same value as some other record.
+     */
+    abstract boolean sameValue(DNSRecord other);
+
+    /**
+     * True if this record has the same type as some other record.
+     */
+    boolean sameType(DNSRecord other) {
+        return this.getRecordType() == other.getRecordType();
+    }
+
+    /**
+     * Handles a query represented by this record.
+     *
+     * @return Returns true if a conflict with one of the services registered with JmDNS or with the hostname occured.
+     */
+    abstract boolean handleQuery(JmDNSImpl dns, long expirationTime);
+
+    /**
+     * Handles a response represented by this record.
+     *
+     * @return Returns true if a conflict with one of the services registered with JmDNS or with the hostname occured.
+     */
+    abstract boolean handleResponse(JmDNSImpl dns);
+
+    /**
+     * Adds this as an answer to the provided outgoing datagram.
+     */
+    abstract DNSOutgoing addAnswer(JmDNSImpl dns, DNSIncoming in, InetAddress addr, int port, DNSOutgoing out) throws IOException;
+
+    /**
+     * True if this record is suppressed by the answers in a message.
+     */
+    boolean suppressedBy(DNSIncoming msg) {
+        try {
+            for (DNSRecord answer : msg.getAllAnswers()) {
+                if (suppressedBy(answer)) {
+                    return true;
+                }
+            }
+            return false;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            logger.log(Level.WARNING, "suppressedBy() message " + msg + " exception ", e);
+            // msg.print(true);
+            return false;
+        }
+    }
+
+    /**
+     * True if this record would be suppressed by an answer. This is the case if this record would not have a significantly longer TTL.
+     */
+    boolean suppressedBy(DNSRecord other) {
+        if (this.equals(other) && (other._ttl > _ttl / 2)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Get the expiration time of this record.
+     */
+    long getExpirationTime(int percent) {
+        // ttl is in seconds the constant 10 is 1000 ms / 100 %
+        return _created + (percent * _ttl * 10L);
+    }
+
+    /**
+     * Get the remaining TTL for this record.
+     */
+    int getRemainingTTL(long now) {
+        return (int) Math.max(0, (getExpirationTime(100) - now) / 1000);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSEntry#isExpired(long)
+     */
+    @Override
+    public boolean isExpired(long now) {
+        return getExpirationTime(100) <= now;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSEntry#isStale(long)
+     */
+    @Override
+    public boolean isStale(long now) {
+        return getExpirationTime(50) <= now;
+    }
+
+    /**
+     * Reset the TTL of a record. This avoids having to update the entire record in the cache.
+     */
+    void resetTTL(DNSRecord other) {
+        _created = other._created;
+        _ttl = other._ttl;
+    }
+
+    /**
+     * When a record flushed we don't remove it immediately, but mark it for rapid decay.
+     */
+    void setWillExpireSoon(long now) {
+        _created = now;
+        _ttl = DNSConstants.RECORD_EXPIRY_DELAY;
+    }
+
+    /**
+     * Write this record into an outgoing message.
+     */
+    abstract void write(MessageOutputStream out);
+
+    public static class IPv4Address extends Address {
+
+        IPv4Address(String name, DNSRecordClass recordClass, boolean unique, int ttl, InetAddress addr) {
+            super(name, DNSRecordType.TYPE_A, recordClass, unique, ttl, addr);
+        }
+
+        IPv4Address(String name, DNSRecordClass recordClass, boolean unique, int ttl, byte[] rawAddress) {
+            super(name, DNSRecordType.TYPE_A, recordClass, unique, ttl, rawAddress);
+        }
+
+        @Override
+        void write(MessageOutputStream out) {
+            if (_addr != null) {
+                byte[] buffer = _addr.getAddress();
+                // If we have a type A records we should answer with a IPv4 address
+                if (_addr instanceof Inet4Address) {
+                    // All is good
+                } else {
+                    // Get the last four bytes
+                    byte[] tempbuffer = buffer;
+                    buffer = new byte[4];
+                    System.arraycopy(tempbuffer, 12, buffer, 0, 4);
+                }
+                int length = buffer.length;
+                out.writeBytes(buffer, 0, length);
+            }
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#getServiceInfo(boolean)
+         */
+        @Override
+        public ServiceInfo getServiceInfo(boolean persistent) {
+
+            ServiceInfoImpl info = (ServiceInfoImpl) super.getServiceInfo(persistent);
+            info.addAddress((Inet4Address) _addr);
+            return info;
+        }
+
+    }
+
+    public static class IPv6Address extends Address {
+
+        IPv6Address(String name, DNSRecordClass recordClass, boolean unique, int ttl, InetAddress addr) {
+            super(name, DNSRecordType.TYPE_AAAA, recordClass, unique, ttl, addr);
+        }
+
+        IPv6Address(String name, DNSRecordClass recordClass, boolean unique, int ttl, byte[] rawAddress) {
+            super(name, DNSRecordType.TYPE_AAAA, recordClass, unique, ttl, rawAddress);
+        }
+
+        @Override
+        void write(MessageOutputStream out) {
+            if (_addr != null) {
+                byte[] buffer = _addr.getAddress();
+                // If we have a type AAAA records we should answer with a IPv6 address
+                if (_addr instanceof Inet4Address) {
+                    byte[] tempbuffer = buffer;
+                    buffer = new byte[16];
+                    for (int i = 0; i < 16; i++) {
+                        if (i < 11) {
+                            buffer[i] = tempbuffer[i - 12];
+                        } else {
+                            buffer[i] = 0;
+                        }
+                    }
+                }
+                int length = buffer.length;
+                out.writeBytes(buffer, 0, length);
+            }
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#getServiceInfo(boolean)
+         */
+        @Override
+        public ServiceInfo getServiceInfo(boolean persistent) {
+
+            ServiceInfoImpl info = (ServiceInfoImpl) super.getServiceInfo(persistent);
+            info.addAddress((Inet6Address) _addr);
+            return info;
+        }
+
+    }
+
+    /**
+     * Address record.
+     */
+    public static abstract class Address extends DNSRecord {
+        private static Logger logger1 = Logger.getLogger(Address.class.getName());
+
+        InetAddress           _addr;
+
+        protected Address(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique, int ttl, InetAddress addr) {
+            super(name, type, recordClass, unique, ttl);
+            this._addr = addr;
+        }
+
+        protected Address(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique, int ttl, byte[] rawAddress) {
+            super(name, type, recordClass, unique, ttl);
+            try {
+                this._addr = InetAddress.getByAddress(rawAddress);
+            } catch (UnknownHostException exception) {
+                logger1.log(Level.WARNING, "Address() exception ", exception);
+            }
+        }
+
+        boolean same(DNSRecord other) {
+            if (! (other instanceof Address) ) {
+                return false;
+            }
+            return ((sameName(other)) && ((sameValue(other))));
+        }
+
+        boolean sameName(DNSRecord other) {
+            return this.getName().equalsIgnoreCase(other.getName());
+        }
+
+        @Override
+        boolean sameValue(DNSRecord other) {
+            if (! (other instanceof Address) ) {
+                return false;
+            }
+            Address address = (Address) other;
+            if ((this.getAddress() == null) && (address.getAddress() != null)) {
+                return false;
+            }
+            return this.getAddress().equals(address.getAddress());
+        }
+
+        @Override
+        public boolean isSingleValued() {
+            return false;
+        }
+
+        InetAddress getAddress() {
+            return _addr;
+        }
+
+        /**
+         * Creates a byte array representation of this record. This is needed for tie-break tests according to draft-cheshire-dnsext-multicastdns-04.txt chapter 9.2.
+         */
+        @Override
+        protected void toByteArray(DataOutputStream dout) throws IOException {
+            super.toByteArray(dout);
+            byte[] buffer = this.getAddress().getAddress();
+            for (int i = 0; i < buffer.length; i++) {
+                dout.writeByte(buffer[i]);
+            }
+        }
+
+        /**
+         * Does the necessary actions, when this as a query.
+         */
+        @Override
+        boolean handleQuery(JmDNSImpl dns, long expirationTime) {
+            if (dns.getLocalHost().conflictWithRecord(this)) {
+                DNSRecord.Address localAddress = dns.getLocalHost().getDNSAddressRecord(this.getRecordType(), this.isUnique(), DNSConstants.DNS_TTL);
+                int comparison = this.compareTo(localAddress);
+
+                if (comparison == 0) {
+                    // the 2 records are identical this probably means we are seeing our own record.
+                    // With multiple interfaces on a single computer it is possible to see our
+                    // own records come in on different interfaces than the ones they were sent on.
+                    // see section "10. Conflict Resolution" of mdns draft spec.
+                    logger1.finer("handleQuery() Ignoring an identical address query");
+                    return false;
+                }
+
+                logger1.finer("handleQuery() Conflicting query detected.");
+                // Tie breaker test
+                if (dns.isProbing() && comparison > 0) {
+                    // We lost the tie-break. We have to choose a different name.
+                    dns.getLocalHost().incrementHostName();
+                    dns.getCache().clear();
+                    for (ServiceInfo serviceInfo : dns.getServices().values()) {
+                        ServiceInfoImpl info = (ServiceInfoImpl) serviceInfo;
+                        info.revertState();
+                    }
+                }
+                dns.revertState();
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * Does the necessary actions, when this as a response.
+         */
+        @Override
+        boolean handleResponse(JmDNSImpl dns) {
+            if (dns.getLocalHost().conflictWithRecord(this)) {
+                logger1.finer("handleResponse() Denial detected");
+
+                if (dns.isProbing()) {
+                    dns.getLocalHost().incrementHostName();
+                    dns.getCache().clear();
+                    for (ServiceInfo serviceInfo : dns.getServices().values()) {
+                        ServiceInfoImpl info = (ServiceInfoImpl) serviceInfo;
+                        info.revertState();
+                    }
+                }
+                dns.revertState();
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        DNSOutgoing addAnswer(JmDNSImpl dns, DNSIncoming in, InetAddress addr, int port, DNSOutgoing out) throws IOException {
+            return out;
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#getServiceInfo(boolean)
+         */
+        @Override
+        public ServiceInfo getServiceInfo(boolean persistent) {
+            ServiceInfoImpl info = new ServiceInfoImpl(this.getQualifiedNameMap(), 0, 0, 0, persistent, (byte[]) null);
+            // info.setAddress(_addr); This is done in the sub class so we don't have to test for class type
+            return info;
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#getServiceEvent(javax.jmdns.impl.JmDNSImpl)
+         */
+        @Override
+        public ServiceEvent getServiceEvent(JmDNSImpl dns) {
+            ServiceInfo info = this.getServiceInfo(false);
+            ((ServiceInfoImpl) info).setDns(dns);
+            return new ServiceEventImpl(dns, info.getType(), info.getName(), info);
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see com.webobjects.discoveryservices.DNSRecord#toString(java.lang.StringBuilder)
+         */
+        @Override
+        protected void toString(StringBuilder aLog) {
+            super.toString(aLog);
+            aLog.append(" address: '" + (this.getAddress() != null ? this.getAddress().getHostAddress() : "null") + "'");
+        }
+
+    }
+
+    /**
+     * Pointer record.
+     */
+    public static class Pointer extends DNSRecord {
+        // private static Logger logger = Logger.getLogger(Pointer.class.getName());
+        private final String _alias;
+
+        public Pointer(String name, DNSRecordClass recordClass, boolean unique, int ttl, String alias) {
+            super(name, DNSRecordType.TYPE_PTR, recordClass, unique, ttl);
+            this._alias = alias;
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSEntry#isSameEntry(javax.jmdns.impl.DNSEntry)
+         */
+        @Override
+        public boolean isSameEntry(DNSEntry entry) {
+            return super.isSameEntry(entry) && (entry instanceof Pointer) && this.sameValue((Pointer) entry);
+        }
+
+        @Override
+        void write(MessageOutputStream out) {
+            out.writeName(_alias);
+        }
+
+        @Override
+        boolean sameValue(DNSRecord other) {
+            if (! (other instanceof Pointer) ) {
+                return false;
+            }
+            Pointer pointer = (Pointer) other;
+            if ((_alias == null) && (pointer._alias != null)) {
+                return false;
+            }
+            return _alias.equals(pointer._alias);
+        }
+
+        @Override
+        public boolean isSingleValued() {
+            return false;
+        }
+
+        @Override
+        boolean handleQuery(JmDNSImpl dns, long expirationTime) {
+            // Nothing to do (?)
+            // I think there is no possibility for conflicts for this record type?
+            return false;
+        }
+
+        @Override
+        boolean handleResponse(JmDNSImpl dns) {
+            // Nothing to do (?)
+            // I think there is no possibility for conflicts for this record type?
+            return false;
+        }
+
+        String getAlias() {
+            return _alias;
+        }
+
+        @Override
+        DNSOutgoing addAnswer(JmDNSImpl dns, DNSIncoming in, InetAddress addr, int port, DNSOutgoing out) throws IOException {
+            return out;
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#getServiceInfo(boolean)
+         */
+        @Override
+        public ServiceInfo getServiceInfo(boolean persistent) {
+            if (this.isServicesDiscoveryMetaQuery()) {
+                // The service name is in the alias
+                Map<Fields, String> map = ServiceInfoImpl.decodeQualifiedNameMapForType(this.getAlias());
+                return new ServiceInfoImpl(map, 0, 0, 0, persistent, (byte[]) null);
+            } else if (this.isReverseLookup()) {
+                return new ServiceInfoImpl(this.getQualifiedNameMap(), 0, 0, 0, persistent, (byte[]) null);
+            } else if (this.isDomainDiscoveryQuery()) {
+                // FIXME [PJYF Nov 16 2010] We do not currently support domain discovery
+                return new ServiceInfoImpl(this.getQualifiedNameMap(), 0, 0, 0, persistent, (byte[]) null);
+            }
+            Map<Fields, String> map = ServiceInfoImpl.decodeQualifiedNameMapForType(this.getAlias());
+            map.put(Fields.Subtype, this.getQualifiedNameMap().get(Fields.Subtype));
+            return new ServiceInfoImpl(map, 0, 0, 0, persistent, this.getAlias());
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#getServiceEvent(javax.jmdns.impl.JmDNSImpl)
+         */
+        @Override
+        public ServiceEvent getServiceEvent(JmDNSImpl dns) {
+            ServiceInfo info = this.getServiceInfo(false);
+            ((ServiceInfoImpl) info).setDns(dns);
+            String domainName = info.getType();
+            String serviceName = JmDNSImpl.toUnqualifiedName(domainName, this.getAlias());
+            return new ServiceEventImpl(dns, domainName, serviceName, info);
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see com.webobjects.discoveryservices.DNSRecord#toString(java.lang.StringBuilder)
+         */
+        @Override
+        protected void toString(StringBuilder aLog) {
+            super.toString(aLog);
+            aLog.append(" alias: '" + (_alias != null ? _alias.toString() : "null") + "'");
+        }
+
+    }
+
+    public final static byte[] EMPTY_TXT = new byte[] { 0 };
+
+    public static class Text extends DNSRecord {
+        // private static Logger logger = Logger.getLogger(Text.class.getName());
+        private final byte[] _text;
+
+        public Text(String name, DNSRecordClass recordClass, boolean unique, int ttl, byte text[]) {
+            super(name, DNSRecordType.TYPE_TXT, recordClass, unique, ttl);
+            this._text = (text != null && text.length > 0 ? text : EMPTY_TXT);
+        }
+
+        /**
+         * @return the text
+         */
+        byte[] getText() {
+            return this._text;
+        }
+
+        @Override
+        void write(MessageOutputStream out) {
+            out.writeBytes(_text, 0, _text.length);
+        }
+
+        @Override
+        boolean sameValue(DNSRecord other) {
+            if (! (other instanceof Text) ) {
+                return false;
+            }
+            Text txt = (Text) other;
+            if ((_text == null) && (txt._text != null)) {
+                return false;
+            }
+            if (txt._text.length != _text.length) {
+                return false;
+            }
+            for (int i = _text.length; i-- > 0;) {
+                if (txt._text[i] != _text[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        @Override
+        public boolean isSingleValued() {
+            return true;
+        }
+
+        @Override
+        boolean handleQuery(JmDNSImpl dns, long expirationTime) {
+            // Nothing to do (?)
+            // I think there is no possibility for conflicts for this record type?
+            return false;
+        }
+
+        @Override
+        boolean handleResponse(JmDNSImpl dns) {
+            // Nothing to do (?)
+            // Shouldn't we care if we get a conflict at this level?
+            /*
+             * ServiceInfo info = (ServiceInfo) dns.services.get(name.toLowerCase()); if (info != null) { if (! Arrays.equals(text,info.text)) { info.revertState(); return true; } }
+             */
+            return false;
+        }
+
+        @Override
+        DNSOutgoing addAnswer(JmDNSImpl dns, DNSIncoming in, InetAddress addr, int port, DNSOutgoing out) throws IOException {
+            return out;
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#getServiceInfo(boolean)
+         */
+        @Override
+        public ServiceInfo getServiceInfo(boolean persistent) {
+            return new ServiceInfoImpl(this.getQualifiedNameMap(), 0, 0, 0, persistent, _text);
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#getServiceEvent(javax.jmdns.impl.JmDNSImpl)
+         */
+        @Override
+        public ServiceEvent getServiceEvent(JmDNSImpl dns) {
+            ServiceInfo info = this.getServiceInfo(false);
+            ((ServiceInfoImpl) info).setDns(dns);
+            return new ServiceEventImpl(dns, info.getType(), info.getName(), info);
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see com.webobjects.discoveryservices.DNSRecord#toString(java.lang.StringBuilder)
+         */
+        @Override
+        protected void toString(StringBuilder aLog) {
+            super.toString(aLog);
+            aLog.append(" text: '" + ((_text.length > 20) ? new String(_text, 0, 17) + "..." : new String(_text)) + "'");
+        }
+
+    }
+
+    /**
+     * Service record.
+     */
+    public static class Service extends DNSRecord {
+        private static Logger logger1 = Logger.getLogger(Service.class.getName());
+        private final int     _priority;
+        private final int     _weight;
+        private final int     _port;
+        private final String  _server;
+
+        public Service(String name, DNSRecordClass recordClass, boolean unique, int ttl, int priority, int weight, int port, String server) {
+            super(name, DNSRecordType.TYPE_SRV, recordClass, unique, ttl);
+            this._priority = priority;
+            this._weight = weight;
+            this._port = port;
+            this._server = server;
+        }
+
+        @Override
+        void write(MessageOutputStream out) {
+            out.writeShort(_priority);
+            out.writeShort(_weight);
+            out.writeShort(_port);
+            if (DNSIncoming.USE_DOMAIN_NAME_FORMAT_FOR_SRV_TARGET) {
+                out.writeName(_server);
+            } else {
+                // [PJYF Nov 13 2010] Do we still need this? This looks really bad. All label are supposed to start by a length.
+                out.writeUTF(_server, 0, _server.length());
+
+                // add a zero byte to the end just to be safe, this is the strange form
+                // used by the BonjourConformanceTest
+                out.writeByte(0);
+            }
+        }
+
+        @Override
+        protected void toByteArray(DataOutputStream dout) throws IOException {
+            super.toByteArray(dout);
+            dout.writeShort(_priority);
+            dout.writeShort(_weight);
+            dout.writeShort(_port);
+            try {
+                dout.write(_server.getBytes("UTF-8"));
+            } catch (UnsupportedEncodingException exception) {
+                /* UTF-8 is always present */
+            }
+        }
+
+        String getServer() {
+            return _server;
+        }
+
+        /**
+         * @return the priority
+         */
+        public int getPriority() {
+            return this._priority;
+        }
+
+        /**
+         * @return the weight
+         */
+        public int getWeight() {
+            return this._weight;
+        }
+
+        /**
+         * @return the port
+         */
+        public int getPort() {
+            return this._port;
+        }
+
+        @Override
+        boolean sameValue(DNSRecord other) {
+            if (! (other instanceof Service) ) {
+                return false;
+            }
+            Service s = (Service) other;
+            return (_priority == s._priority) && (_weight == s._weight) && (_port == s._port) && _server.equals(s._server);
+        }
+
+        @Override
+        public boolean isSingleValued() {
+            return true;
+        }
+
+        @Override
+        boolean handleQuery(JmDNSImpl dns, long expirationTime) {
+            ServiceInfoImpl info = (ServiceInfoImpl) dns.getServices().get(this.getKey());
+            if (info != null && (info.isAnnouncing() || info.isAnnounced()) && (_port != info.getPort() || !_server.equalsIgnoreCase(dns.getLocalHost().getName()))) {
+                logger1.finer("handleQuery() Conflicting probe detected from: " + getRecordSource());
+                DNSRecord.Service localService = new DNSRecord.Service(info.getQualifiedName(), DNSRecordClass.CLASS_IN, DNSRecordClass.UNIQUE, DNSConstants.DNS_TTL, info.getPriority(), info.getWeight(), info.getPort(), dns.getLocalHost().getName());
+
+                // This block is useful for debugging race conditions when jmdns is responding to itself.
+                try {
+                    if (dns.getInetAddress().equals(getRecordSource())) {
+                        logger1.warning("Got conflicting probe from ourselves\n" + "incoming: " + this.toString() + "\n" + "local   : " + localService.toString());
+                    }
+                } catch (IOException e) {
+                    logger1.log(Level.WARNING, "IOException", e);
+                }
+
+                int comparison = this.compareTo(localService);
+
+                if (comparison == 0) {
+                    // the 2 records are identical this probably means we are seeing our own record.
+                    // With multiple interfaces on a single computer it is possible to see our
+                    // own records come in on different interfaces than the ones they were sent on.
+                    // see section "10. Conflict Resolution" of mdns draft spec.
+                    logger1.finer("handleQuery() Ignoring a identical service query");
+                    return false;
+                }
+
+                // Tie breaker test
+                if (info.isProbing() && comparison > 0) {
+                    // We lost the tie break
+                    String oldName = info.getQualifiedName().toLowerCase();
+                    info.setName(dns.incrementName(info.getName()));
+                    dns.getServices().remove(oldName);
+                    dns.getServices().put(info.getQualifiedName().toLowerCase(), info);
+                    logger1.finer("handleQuery() Lost tie break: new unique name chosen:" + info.getName());
+
+                    // We revert the state to start probing again with the new name
+                    info.revertState();
+                } else {
+                    // We won the tie break, so this conflicting probe should be ignored
+                    // See paragraph 3 of section 9.2 in mdns draft spec
+                    return false;
+                }
+
+                return true;
+
+            }
+            return false;
+        }
+
+        @Override
+        boolean handleResponse(JmDNSImpl dns) {
+            ServiceInfoImpl info = (ServiceInfoImpl) dns.getServices().get(this.getKey());
+            if (info != null && (_port != info.getPort() || !_server.equalsIgnoreCase(dns.getLocalHost().getName()))) {
+                logger1.finer("handleResponse() Denial detected");
+
+                if (info.isProbing()) {
+                    String oldName = info.getQualifiedName().toLowerCase();
+                    info.setName(dns.incrementName(info.getName()));
+                    dns.getServices().remove(oldName);
+                    dns.getServices().put(info.getQualifiedName().toLowerCase(), info);
+                    logger1.finer("handleResponse() New unique name chose:" + info.getName());
+
+                }
+                info.revertState();
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        DNSOutgoing addAnswer(JmDNSImpl dns, DNSIncoming in, InetAddress addr, int port, DNSOutgoing out) throws IOException {
+            ServiceInfoImpl info = (ServiceInfoImpl) dns.getServices().get(this.getKey());
+            if (info != null) {
+                if (this._port == info.getPort() != _server.equals(dns.getLocalHost().getName())) {
+                    return dns.addAnswer(in, addr, port, out, new DNSRecord.Service(info.getQualifiedName(), DNSRecordClass.CLASS_IN, DNSRecordClass.UNIQUE, DNSConstants.DNS_TTL, info.getPriority(), info.getWeight(), info.getPort(), dns
+                            .getLocalHost().getName()));
+                }
+            }
+            return out;
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#getServiceInfo(boolean)
+         */
+        @Override
+        public ServiceInfo getServiceInfo(boolean persistent) {
+            return new ServiceInfoImpl(this.getQualifiedNameMap(), _port, _weight, _priority, persistent, _server);
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#getServiceEvent(javax.jmdns.impl.JmDNSImpl)
+         */
+        @Override
+        public ServiceEvent getServiceEvent(JmDNSImpl dns) {
+            ServiceInfo info = this.getServiceInfo(false);
+            ((ServiceInfoImpl) info).setDns(dns);
+            // String domainName = "";
+            // String serviceName = this.getServer();
+            // int index = serviceName.indexOf('.');
+            // if (index > 0)
+            // {
+            // serviceName = this.getServer().substring(0, index);
+            // if (index + 1 < this.getServer().length())
+            // domainName = this.getServer().substring(index + 1);
+            // }
+            // return new ServiceEventImpl(dns, domainName, serviceName, info);
+            return new ServiceEventImpl(dns, info.getType(), info.getName(), info);
+
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see com.webobjects.discoveryservices.DNSRecord#toString(java.lang.StringBuilder)
+         */
+        @Override
+        protected void toString(StringBuilder aLog) {
+            super.toString(aLog);
+            aLog.append(" server: '" + _server + ":" + _port + "'");
+        }
+
+    }
+
+    public static class HostInformation extends DNSRecord {
+        String _os;
+        String _cpu;
+
+        /**
+         * @param name
+         * @param recordClass
+         * @param unique
+         * @param ttl
+         * @param cpu
+         * @param os
+         */
+        public HostInformation(String name, DNSRecordClass recordClass, boolean unique, int ttl, String cpu, String os) {
+            super(name, DNSRecordType.TYPE_HINFO, recordClass, unique, ttl);
+            _cpu = cpu;
+            _os = os;
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#addAnswer(javax.jmdns.impl.JmDNSImpl, javax.jmdns.impl.DNSIncoming, java.net.InetAddress, int, javax.jmdns.impl.DNSOutgoing)
+         */
+        @Override
+        DNSOutgoing addAnswer(JmDNSImpl dns, DNSIncoming in, InetAddress addr, int port, DNSOutgoing out) throws IOException {
+            return out;
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#handleQuery(javax.jmdns.impl.JmDNSImpl, long)
+         */
+        @Override
+        boolean handleQuery(JmDNSImpl dns, long expirationTime) {
+            return false;
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#handleResponse(javax.jmdns.impl.JmDNSImpl)
+         */
+        @Override
+        boolean handleResponse(JmDNSImpl dns) {
+            return false;
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#sameValue(javax.jmdns.impl.DNSRecord)
+         */
+        @Override
+        boolean sameValue(DNSRecord other) {
+            if (! (other instanceof HostInformation) ) {
+                return false;
+            }
+            HostInformation hinfo = (HostInformation) other;
+            if ((_cpu == null) && (hinfo._cpu != null)) {
+                return false;
+            }
+            if ((_os == null) && (hinfo._os != null)) {
+                return false;
+            }
+            return _cpu.equals(hinfo._cpu) && _os.equals(hinfo._os);
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#isSingleValued()
+         */
+        @Override
+        public boolean isSingleValued() {
+            return true;
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#write(javax.jmdns.impl.DNSOutgoing)
+         */
+        @Override
+        void write(MessageOutputStream out) {
+            String hostInfo = _cpu + " " + _os;
+            out.writeUTF(hostInfo, 0, hostInfo.length());
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#getServiceInfo(boolean)
+         */
+        @Override
+        public ServiceInfo getServiceInfo(boolean persistent) {
+            Map<String, String> hinfo = new HashMap<String, String>(2);
+            hinfo.put("cpu", _cpu);
+            hinfo.put("os", _os);
+            return new ServiceInfoImpl(this.getQualifiedNameMap(), 0, 0, 0, persistent, hinfo);
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSRecord#getServiceEvent(javax.jmdns.impl.JmDNSImpl)
+         */
+        @Override
+        public ServiceEvent getServiceEvent(JmDNSImpl dns) {
+            ServiceInfo info = this.getServiceInfo(false);
+            ((ServiceInfoImpl) info).setDns(dns);
+            return new ServiceEventImpl(dns, info.getType(), info.getName(), info);
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see com.webobjects.discoveryservices.DNSRecord#toString(java.lang.StringBuilder)
+         */
+        @Override
+        protected void toString(StringBuilder aLog) {
+            super.toString(aLog);
+            aLog.append(" cpu: '" + _cpu + "' os: '" + _os + "'");
+        }
+
+    }
+
+    /**
+     * Determine if a record can have multiple values in the cache.
+     *
+     * @return <code>false</code> if this record can have multiple values in the cache, <code>true</code> otherwise.
+     */
+    public abstract boolean isSingleValued();
+
+    /**
+     * Return a service information associated with that record if appropriate.
+     *
+     * @return service information
+     */
+    public ServiceInfo getServiceInfo() {
+        return this.getServiceInfo(false);
+    }
+
+    /**
+     * Return a service information associated with that record if appropriate.
+     *
+     * @param persistent
+     *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
+     * @return service information
+     */
+    public abstract ServiceInfo getServiceInfo(boolean persistent);
+
+    /**
+     * Creates and return a service event for this record.
+     *
+     * @param dns
+     *            DNS serviced by this event
+     * @return service event
+     */
+    public abstract ServiceEvent getServiceEvent(JmDNSImpl dns);
+
+    public void setRecordSource(InetAddress source) {
+        this._source = source;
+    }
+
+    public InetAddress getRecordSource() {
+        return _source;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.webobjects.discoveryservices.DNSRecord#toString(java.lang.StringBuilder)
+     */
+    @Override
+    protected void toString(StringBuilder aLog) {
+        super.toString(aLog);
+        aLog.append(" ttl: '" + getRemainingTTL(System.currentTimeMillis()) + "/" + _ttl + "'");
+    }
+
+    public void setTTL(int ttl) {
+        this._ttl = ttl;
+    }
+
+    public int getTTL() {
+        return _ttl;
+    }
+}
diff --git a/src/javax/jmdns/impl/DNSStatefulObject.java b/src/javax/jmdns/impl/DNSStatefulObject.java
new file mode 100644
index 0000000..aadd6f1
--- /dev/null
+++ b/src/javax/jmdns/impl/DNSStatefulObject.java
@@ -0,0 +1,559 @@
+// Licensed under Apache License version 2.0
+package javax.jmdns.impl;
+
+import java.util.Collection;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.jmdns.impl.constants.DNSState;
+import javax.jmdns.impl.tasks.DNSTask;
+
+/**
+ * Sets of methods to manage the state machine.<br/>
+ * <b>Implementation note:</b> This interface is accessed from multiple threads. The implementation must be thread safe.
+ *
+ * @author Pierre Frisch
+ */
+public interface DNSStatefulObject {
+
+    /**
+     * This class define a semaphore. On this multiple threads can wait the arrival of one event. Thread wait for a maximum defined by the timeout.
+     * <p>
+     * Implementation note: this class is based on {@link java.util.concurrent.Semaphore} so that they can be released by the timeout timer.
+     * </p>
+     *
+     * @author Pierre Frisch
+     */
+    public static final class DNSStatefulObjectSemaphore {
+        private static Logger                          logger = Logger.getLogger(DNSStatefulObjectSemaphore.class.getName());
+
+        private final String                           _name;
+
+        private final ConcurrentMap<Thread, Semaphore> _semaphores;
+
+        /**
+         * @param name
+         *            Semaphore name for debugging purposes.
+         */
+        public DNSStatefulObjectSemaphore(String name) {
+            super();
+            _name = name;
+            _semaphores = new ConcurrentHashMap<Thread, Semaphore>(50);
+        }
+
+        /**
+         * Blocks the current thread until the event arrives or the timeout expires.
+         *
+         * @param timeout
+         *            wait period for the event
+         */
+        public void waitForEvent(long timeout) {
+            Thread thread = Thread.currentThread();
+            Semaphore semaphore = _semaphores.get(thread);
+            if (semaphore == null) {
+                semaphore = new Semaphore(1, true);
+                semaphore.drainPermits();
+                _semaphores.putIfAbsent(thread, semaphore);
+            }
+            semaphore = _semaphores.get(thread);
+            try {
+                semaphore.tryAcquire(timeout, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException exception) {
+                logger.log(Level.FINER, "Exception ", exception);
+            }
+        }
+
+        /**
+         * Signals the semaphore when the event arrives.
+         */
+        public void signalEvent() {
+            Collection<Semaphore> semaphores = _semaphores.values();
+            for (Semaphore semaphore : semaphores) {
+                semaphore.release();
+                semaphores.remove(semaphore);
+            }
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder aLog = new StringBuilder(1000);
+            aLog.append("Semaphore: ");
+            aLog.append(this._name);
+            if (_semaphores.size() == 0) {
+                aLog.append(" no semaphores.");
+            } else {
+                aLog.append(" semaphores:\n");
+                for (Thread thread : _semaphores.keySet()) {
+                    aLog.append("\tThread: ");
+                    aLog.append(thread.getName());
+                    aLog.append(' ');
+                    aLog.append(_semaphores.get(thread));
+                    aLog.append('\n');
+                }
+            }
+            return aLog.toString();
+        }
+
+    }
+
+    public static class DefaultImplementation extends ReentrantLock implements DNSStatefulObject {
+        private static Logger                    logger           = Logger.getLogger(DefaultImplementation.class.getName());
+
+        private static final long                serialVersionUID = -3264781576883412227L;
+
+        private volatile JmDNSImpl               _dns;
+
+        protected volatile DNSTask               _task;
+
+        protected volatile DNSState              _state;
+
+        private final DNSStatefulObjectSemaphore _announcing;
+
+        private final DNSStatefulObjectSemaphore _canceling;
+
+        public DefaultImplementation() {
+            super();
+            _dns = null;
+            _task = null;
+            _state = DNSState.PROBING_1;
+            _announcing = new DNSStatefulObjectSemaphore("Announce");
+            _canceling = new DNSStatefulObjectSemaphore("Cancel");
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public JmDNSImpl getDns() {
+            return this._dns;
+        }
+
+        protected void setDns(JmDNSImpl dns) {
+            this._dns = dns;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void associateWithTask(DNSTask task, DNSState state) {
+            if (this._task == null && this._state == state) {
+                this.lock();
+                try {
+                    if (this._task == null && this._state == state) {
+                        this.setTask(task);
+                    }
+                } finally {
+                    this.unlock();
+                }
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void removeAssociationWithTask(DNSTask task) {
+            if (this._task == task) {
+                this.lock();
+                try {
+                    if (this._task == task) {
+                        this.setTask(null);
+                    }
+                } finally {
+                    this.unlock();
+                }
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean isAssociatedWithTask(DNSTask task, DNSState state) {
+            this.lock();
+            try {
+                return this._task == task && this._state == state;
+            } finally {
+                this.unlock();
+            }
+        }
+
+        protected void setTask(DNSTask task) {
+            this._task = task;
+        }
+
+        /**
+         * @param state
+         *            the state to set
+         */
+        protected void setState(DNSState state) {
+            this.lock();
+            try {
+                this._state = state;
+                if (this.isAnnounced()) {
+                    _announcing.signalEvent();
+                }
+                if (this.isCanceled()) {
+                    _canceling.signalEvent();
+                    // clear any waiting announcing
+                    _announcing.signalEvent();
+                }
+            } finally {
+                this.unlock();
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean advanceState(DNSTask task) {
+            boolean result = true;
+            if (this._task == task) {
+                this.lock();
+                try {
+                    if (this._task == task) {
+                        this.setState(this._state.advance());
+                    } else {
+                        logger.warning("Trying to advance state whhen not the owner. owner: " + this._task + " perpetrator: " + task);
+                    }
+                } finally {
+                    this.unlock();
+                }
+            }
+            return result;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean revertState() {
+            boolean result = true;
+            if (!this.willCancel()) {
+                this.lock();
+                try {
+                    if (!this.willCancel()) {
+                        this.setState(this._state.revert());
+                        this.setTask(null);
+                    }
+                } finally {
+                    this.unlock();
+                }
+            }
+            return result;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean cancelState() {
+            boolean result = false;
+            if (!this.willCancel()) {
+                this.lock();
+                try {
+                    if (!this.willCancel()) {
+                        this.setState(DNSState.CANCELING_1);
+                        this.setTask(null);
+                        result = true;
+                    }
+                } finally {
+                    this.unlock();
+                }
+            }
+            return result;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean closeState() {
+            boolean result = false;
+            if (!this.willClose()) {
+                this.lock();
+                try {
+                    if (!this.willClose()) {
+                        this.setState(DNSState.CLOSING);
+                        this.setTask(null);
+                        result = true;
+                    }
+                } finally {
+                    this.unlock();
+                }
+            }
+            return result;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean recoverState() {
+            boolean result = false;
+            this.lock();
+            try {
+                this.setState(DNSState.PROBING_1);
+                this.setTask(null);
+            } finally {
+                this.unlock();
+            }
+            return result;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean isProbing() {
+            return this._state.isProbing();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean isAnnouncing() {
+            return this._state.isAnnouncing();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean isAnnounced() {
+            return this._state.isAnnounced();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean isCanceling() {
+            return this._state.isCanceling();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean isCanceled() {
+            return this._state.isCanceled();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean isClosing() {
+            return this._state.isClosing();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean isClosed() {
+            return this._state.isClosed();
+        }
+
+        private boolean willCancel() {
+            return this._state.isCanceled() || this._state.isCanceling();
+        }
+
+        private boolean willClose() {
+            return this._state.isClosed() || this._state.isClosing();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean waitForAnnounced(long timeout) {
+            if (!this.isAnnounced() && !this.willCancel()) {
+                _announcing.waitForEvent(timeout);
+            }
+            if (!this.isAnnounced()) {
+                if (this.willCancel() || this.willClose()) {
+                    logger.fine("Wait for announced cancelled: " + this);
+                } else {
+                    logger.warning("Wait for announced timed out: " + this);
+                }
+            }
+            return this.isAnnounced();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean waitForCanceled(long timeout) {
+            if (!this.isCanceled()) {
+                _canceling.waitForEvent(timeout);
+            }
+            if (!this.isCanceled() && !this.willClose()) {
+                logger.warning("Wait for canceled timed out: " + this);
+            }
+            return this.isCanceled();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public String toString() {
+            return (_dns != null ? "DNS: " + _dns.getName() : "NO DNS") + " state: " + _state + " task: " + _task;
+        }
+
+    }
+
+    /**
+     * Returns the DNS associated with this object.
+     *
+     * @return DNS resolver
+     */
+    public JmDNSImpl getDns();
+
+    /**
+     * Sets the task associated with this Object.
+     *
+     * @param task
+     *            associated task
+     * @param state
+     *            state of the task
+     */
+    public void associateWithTask(DNSTask task, DNSState state);
+
+    /**
+     * Remove the association of the task with this Object.
+     *
+     * @param task
+     *            associated task
+     */
+    public void removeAssociationWithTask(DNSTask task);
+
+    /**
+     * Checks if this object is associated with the task and in the same state.
+     *
+     * @param task
+     *            associated task
+     * @param state
+     *            state of the task
+     * @return <code>true</code> is the task is associated with this object, <code>false</code> otherwise.
+     */
+    public boolean isAssociatedWithTask(DNSTask task, DNSState state);
+
+    /**
+     * Sets the state and notifies all objects that wait on the ServiceInfo.
+     *
+     * @param task
+     *            associated task
+     * @return <code>true</code if the state was changed by this thread, <code>false</code> otherwise.
+     * @see DNSState#advance()
+     */
+    public boolean advanceState(DNSTask task);
+
+    /**
+     * Sets the state and notifies all objects that wait on the ServiceInfo.
+     *
+     * @return <code>true</code if the state was changed by this thread, <code>false</code> otherwise.
+     * @see DNSState#revert()
+     */
+    public boolean revertState();
+
+    /**
+     * Sets the state and notifies all objects that wait on the ServiceInfo.
+     *
+     * @return <code>true</code if the state was changed by this thread, <code>false</code> otherwise.
+     */
+    public boolean cancelState();
+
+    /**
+     * Sets the state and notifies all objects that wait on the ServiceInfo.
+     *
+     * @return <code>true</code if the state was changed by this thread, <code>false</code> otherwise.
+     */
+    public boolean closeState();
+
+    /**
+     * Sets the state and notifies all objects that wait on the ServiceInfo.
+     *
+     * @return <code>true</code if the state was changed by this thread, <code>false</code> otherwise.
+     */
+    public boolean recoverState();
+
+    /**
+     * Returns true, if this is a probing state.
+     *
+     * @return <code>true</code> if probing state, <code>false</code> otherwise
+     */
+    public boolean isProbing();
+
+    /**
+     * Returns true, if this is an announcing state.
+     *
+     * @return <code>true</code> if announcing state, <code>false</code> otherwise
+     */
+    public boolean isAnnouncing();
+
+    /**
+     * Returns true, if this is an announced state.
+     *
+     * @return <code>true</code> if announced state, <code>false</code> otherwise
+     */
+    public boolean isAnnounced();
+
+    /**
+     * Returns true, if this is a canceling state.
+     *
+     * @return <code>true</code> if canceling state, <code>false</code> otherwise
+     */
+    public boolean isCanceling();
+
+    /**
+     * Returns true, if this is a canceled state.
+     *
+     * @return <code>true</code> if canceled state, <code>false</code> otherwise
+     */
+    public boolean isCanceled();
+
+    /**
+     * Returns true, if this is a closing state.
+     *
+     * @return <code>true</code> if closing state, <code>false</code> otherwise
+     */
+    public boolean isClosing();
+
+    /**
+     * Returns true, if this is a closed state.
+     *
+     * @return <code>true</code> if closed state, <code>false</code> otherwise
+     */
+    public boolean isClosed();
+
+    /**
+     * Waits for the object to be announced.
+     *
+     * @param timeout
+     *            the maximum time to wait in milliseconds.
+     * @return <code>true</code> if the object is announced, <code>false</code> otherwise
+     */
+    public boolean waitForAnnounced(long timeout);
+
+    /**
+     * Waits for the object to be canceled.
+     *
+     * @param timeout
+     *            the maximum time to wait in milliseconds.
+     * @return <code>true</code> if the object is canceled, <code>false</code> otherwise
+     */
+    public boolean waitForCanceled(long timeout);
+
+}
diff --git a/src/javax/jmdns/impl/DNSTaskStarter.java b/src/javax/jmdns/impl/DNSTaskStarter.java
new file mode 100644
index 0000000..ab17201
--- /dev/null
+++ b/src/javax/jmdns/impl/DNSTaskStarter.java
@@ -0,0 +1,464 @@
+/**
+ *
+ */
+package javax.jmdns.impl;
+
+import java.util.Date;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.jmdns.impl.tasks.RecordReaper;
+import javax.jmdns.impl.tasks.Responder;
+import javax.jmdns.impl.tasks.resolver.ServiceInfoResolver;
+import javax.jmdns.impl.tasks.resolver.ServiceResolver;
+import javax.jmdns.impl.tasks.resolver.TypeResolver;
+import javax.jmdns.impl.tasks.state.Announcer;
+import javax.jmdns.impl.tasks.state.Canceler;
+import javax.jmdns.impl.tasks.state.Prober;
+import javax.jmdns.impl.tasks.state.Renewer;
+
+/**
+ * This class is used by JmDNS to start the various task required to run the DNS discovery. This interface is only there in order to support MANET modifications.
+ * <p>
+ * <b>Note: </b> This is not considered as part of the general public API of JmDNS.
+ * </p>
+ *
+ * @author Pierre Frisch
+ */
+public interface DNSTaskStarter {
+
+    /**
+     * DNSTaskStarter.Factory enable the creation of new instance of DNSTaskStarter.
+     */
+    public static final class Factory {
+
+        private static volatile Factory                        _instance;
+        private final ConcurrentMap<JmDNSImpl, DNSTaskStarter> _instances;
+
+        /**
+         * This interface defines a delegate to the DNSTaskStarter class to enable subclassing.
+         */
+        public static interface ClassDelegate {
+
+            /**
+             * Allows the delegate the opportunity to construct and return a different DNSTaskStarter.
+             *
+             * @param jmDNSImpl
+             *            jmDNS instance
+             * @return Should return a new DNSTaskStarter Object.
+             * @see #classDelegate()
+             * @see #setClassDelegate(ClassDelegate anObject)
+             */
+            public DNSTaskStarter newDNSTaskStarter(JmDNSImpl jmDNSImpl);
+        }
+
+        private static final AtomicReference<Factory.ClassDelegate> _databaseClassDelegate = new AtomicReference<Factory.ClassDelegate>();
+
+        private Factory() {
+            super();
+            _instances = new ConcurrentHashMap<JmDNSImpl, DNSTaskStarter>(20);
+        }
+
+        /**
+         * Assigns <code>delegate</code> as DNSTaskStarter's class delegate. The class delegate is optional.
+         *
+         * @param delegate
+         *            The object to set as DNSTaskStarter's class delegate.
+         * @see #classDelegate()
+         * @see DNSTaskStarter.Factory.ClassDelegate
+         */
+        public static void setClassDelegate(Factory.ClassDelegate delegate) {
+            _databaseClassDelegate.set(delegate);
+        }
+
+        /**
+         * Returns DNSTaskStarter's class delegate.
+         *
+         * @return DNSTaskStarter's class delegate.
+         * @see #setClassDelegate(ClassDelegate anObject)
+         * @see DNSTaskStarter.Factory.ClassDelegate
+         */
+        public static Factory.ClassDelegate classDelegate() {
+            return _databaseClassDelegate.get();
+        }
+
+        /**
+         * Returns a new instance of DNSTaskStarter using the class delegate if it exists.
+         *
+         * @param jmDNSImpl
+         *            jmDNS instance
+         * @return new instance of DNSTaskStarter
+         */
+        protected static DNSTaskStarter newDNSTaskStarter(JmDNSImpl jmDNSImpl) {
+            DNSTaskStarter instance = null;
+            Factory.ClassDelegate delegate = _databaseClassDelegate.get();
+            if (delegate != null) {
+                instance = delegate.newDNSTaskStarter(jmDNSImpl);
+            }
+            return (instance != null ? instance : new DNSTaskStarterImpl(jmDNSImpl));
+        }
+
+        /**
+         * Return the instance of the DNSTaskStarter Factory.
+         *
+         * @return DNSTaskStarter Factory
+         */
+        public static Factory getInstance() {
+            if (_instance == null) {
+                synchronized (DNSTaskStarter.Factory.class) {
+                    if (_instance == null) {
+                        _instance = new Factory();
+                    }
+                }
+            }
+            return _instance;
+        }
+
+        /**
+         * Return the instance of the DNSTaskStarter for the JmDNS.
+         *
+         * @param jmDNSImpl
+         *            jmDNS instance
+         * @return the DNSTaskStarter
+         */
+        public DNSTaskStarter getStarter(JmDNSImpl jmDNSImpl) {
+            DNSTaskStarter starter = _instances.get(jmDNSImpl);
+            if (starter == null) {
+                _instances.putIfAbsent(jmDNSImpl, newDNSTaskStarter(jmDNSImpl));
+                starter = _instances.get(jmDNSImpl);
+            }
+            return starter;
+        }
+
+    }
+
+    public static final class DNSTaskStarterImpl implements DNSTaskStarter {
+
+        private final JmDNSImpl _jmDNSImpl;
+
+        /**
+         * The timer is used to dispatch all outgoing messages of JmDNS. It is also used to dispatch maintenance tasks for the DNS cache.
+         */
+        private final Timer     _timer;
+
+        /**
+         * The timer is used to dispatch maintenance tasks for the DNS cache.
+         */
+        private final Timer     _stateTimer;
+
+        public static class StarterTimer extends Timer {
+
+            // This is needed because in some case we cancel the timers before all the task have finished running and in some case they will try to reschedule
+            private volatile boolean _cancelled;
+
+            /**
+             *
+             */
+            public StarterTimer() {
+                super();
+                _cancelled = false;
+            }
+
+            /**
+             * @param isDaemon
+             */
+            public StarterTimer(boolean isDaemon) {
+                super(isDaemon);
+                _cancelled = false;
+            }
+
+            /**
+             * @param name
+             * @param isDaemon
+             */
+            public StarterTimer(String name, boolean isDaemon) {
+                super(name, isDaemon);
+                _cancelled = false;
+            }
+
+            /**
+             * @param name
+             */
+            public StarterTimer(String name) {
+                super(name);
+                _cancelled = false;
+            }
+
+            /*
+             * (non-Javadoc)
+             * @see java.util.Timer#cancel()
+             */
+            @Override
+            public synchronized void cancel() {
+                if (_cancelled) return;
+                _cancelled = true;
+                super.cancel();
+            }
+
+            /*
+             * (non-Javadoc)
+             * @see java.util.Timer#schedule(java.util.TimerTask, long)
+             */
+            @Override
+            public synchronized void schedule(TimerTask task, long delay) {
+                if (_cancelled) return;
+                super.schedule(task, delay);
+            }
+
+            /*
+             * (non-Javadoc)
+             * @see java.util.Timer#schedule(java.util.TimerTask, java.util.Date)
+             */
+            @Override
+            public synchronized void schedule(TimerTask task, Date time) {
+                if (_cancelled) return;
+                super.schedule(task, time);
+            }
+
+            /*
+             * (non-Javadoc)
+             * @see java.util.Timer#schedule(java.util.TimerTask, long, long)
+             */
+            @Override
+            public synchronized void schedule(TimerTask task, long delay, long period) {
+                if (_cancelled) return;
+                super.schedule(task, delay, period);
+            }
+
+            /*
+             * (non-Javadoc)
+             * @see java.util.Timer#schedule(java.util.TimerTask, java.util.Date, long)
+             */
+            @Override
+            public synchronized void schedule(TimerTask task, Date firstTime, long period) {
+                if (_cancelled) return;
+                super.schedule(task, firstTime, period);
+            }
+
+            /*
+             * (non-Javadoc)
+             * @see java.util.Timer#scheduleAtFixedRate(java.util.TimerTask, long, long)
+             */
+            @Override
+            public synchronized void scheduleAtFixedRate(TimerTask task, long delay, long period) {
+                if (_cancelled) return;
+                super.scheduleAtFixedRate(task, delay, period);
+            }
+
+            /*
+             * (non-Javadoc)
+             * @see java.util.Timer#scheduleAtFixedRate(java.util.TimerTask, java.util.Date, long)
+             */
+            @Override
+            public synchronized void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) {
+                if (_cancelled) return;
+                super.scheduleAtFixedRate(task, firstTime, period);
+            }
+
+        }
+
+        public DNSTaskStarterImpl(JmDNSImpl jmDNSImpl) {
+            super();
+            _jmDNSImpl = jmDNSImpl;
+            _timer = new StarterTimer("JmDNS(" + _jmDNSImpl.getName() + ").Timer", true);
+            _stateTimer = new StarterTimer("JmDNS(" + _jmDNSImpl.getName() + ").State.Timer", false);
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSTaskStarter#purgeTimer()
+         */
+        @Override
+        public void purgeTimer() {
+            _timer.purge();
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSTaskStarter#purgeStateTimer()
+         */
+        @Override
+        public void purgeStateTimer() {
+            _stateTimer.purge();
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSTaskStarter#cancelTimer()
+         */
+        @Override
+        public void cancelTimer() {
+            _timer.cancel();
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSTaskStarter#cancelStateTimer()
+         */
+        @Override
+        public void cancelStateTimer() {
+            _stateTimer.cancel();
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSTaskStarter#startProber()
+         */
+        @Override
+        public void startProber() {
+            new Prober(_jmDNSImpl).start(_stateTimer);
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSTaskStarter#startAnnouncer()
+         */
+        @Override
+        public void startAnnouncer() {
+            new Announcer(_jmDNSImpl).start(_stateTimer);
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSTaskStarter#startRenewer()
+         */
+        @Override
+        public void startRenewer() {
+            new Renewer(_jmDNSImpl).start(_stateTimer);
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSTaskStarter#startCanceler()
+         */
+        @Override
+        public void startCanceler() {
+            new Canceler(_jmDNSImpl).start(_stateTimer);
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSTaskStarter#startReaper()
+         */
+        @Override
+        public void startReaper() {
+            new RecordReaper(_jmDNSImpl).start(_timer);
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSTaskStarter#startServiceInfoResolver(javax.jmdns.impl.ServiceInfoImpl)
+         */
+        @Override
+        public void startServiceInfoResolver(ServiceInfoImpl info) {
+            new ServiceInfoResolver(_jmDNSImpl, info).start(_timer);
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSTaskStarter#startTypeResolver()
+         */
+        @Override
+        public void startTypeResolver() {
+            new TypeResolver(_jmDNSImpl).start(_timer);
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSTaskStarter#startServiceResolver(java.lang.String)
+         */
+        @Override
+        public void startServiceResolver(String type) {
+            new ServiceResolver(_jmDNSImpl, type).start(_timer);
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.DNSTaskStarter#startResponder(javax.jmdns.impl.DNSIncoming, int)
+         */
+        @Override
+        public void startResponder(DNSIncoming in, int port) {
+            new Responder(_jmDNSImpl, in, port).start(_timer);
+        }
+    }
+
+    /**
+     * Purge the general task timer
+     */
+    public void purgeTimer();
+
+    /**
+     * Purge the state task timer
+     */
+    public void purgeStateTimer();
+
+    /**
+     * Cancel the generals task timer
+     */
+    public void cancelTimer();
+
+    /**
+     * Cancel the state task timer
+     */
+    public void cancelStateTimer();
+
+    /**
+     * Start a new prober task
+     */
+    public void startProber();
+
+    /**
+     * Start a new announcer task
+     */
+    public void startAnnouncer();
+
+    /**
+     * Start a new renewer task
+     */
+    public void startRenewer();
+
+    /**
+     * Start a new canceler task
+     */
+    public void startCanceler();
+
+    /**
+     * Start a new reaper task. There is only supposed to be one reaper running at a time.
+     */
+    public void startReaper();
+
+    /**
+     * Start a new service info resolver task
+     *
+     * @param info
+     *            service info to resolve
+     */
+    public void startServiceInfoResolver(ServiceInfoImpl info);
+
+    /**
+     * Start a new service type resolver task
+     */
+    public void startTypeResolver();
+
+    /**
+     * Start a new service resolver task
+     *
+     * @param type
+     *            service type to resolve
+     */
+    public void startServiceResolver(String type);
+
+    /**
+     * Start a new responder task
+     *
+     * @param in
+     *            incoming message
+     * @param port
+     *            incoming port
+     */
+    public void startResponder(DNSIncoming in, int port);
+
+}
diff --git a/src/javax/jmdns/impl/HostInfo.java b/src/javax/jmdns/impl/HostInfo.java
new file mode 100755
index 0000000..1f9650e
--- /dev/null
+++ b/src/javax/jmdns/impl/HostInfo.java
@@ -0,0 +1,431 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.jmdns.NetworkTopologyDiscovery;
+import javax.jmdns.impl.constants.DNSConstants;
+import javax.jmdns.impl.constants.DNSRecordClass;
+import javax.jmdns.impl.constants.DNSRecordType;
+import javax.jmdns.impl.constants.DNSState;
+import javax.jmdns.impl.tasks.DNSTask;
+
+/**
+ * HostInfo information on the local host to be able to cope with change of addresses.
+ *
+ * @author Pierre Frisch, Werner Randelshofer
+ */
+public class HostInfo implements DNSStatefulObject {
+    private static Logger       logger = Logger.getLogger(HostInfo.class.getName());
+
+    protected String            _name;
+
+    protected InetAddress       _address;
+
+    protected NetworkInterface  _interfaze;
+
+    private final HostInfoState _state;
+
+    private final static class HostInfoState extends DNSStatefulObject.DefaultImplementation {
+
+        private static final long serialVersionUID = -8191476803620402088L;
+
+        /**
+         * @param dns
+         */
+        public HostInfoState(JmDNSImpl dns) {
+            super();
+            this.setDns(dns);
+        }
+
+    }
+
+    /**
+     * @param address
+     *            IP address to bind
+     * @param dns
+     *            JmDNS instance
+     * @param jmdnsName
+     *            JmDNS name
+     * @return new HostInfo
+     */
+    public static HostInfo newHostInfo(InetAddress address, JmDNSImpl dns, String jmdnsName) {
+        HostInfo localhost = null;
+        String aName = "";
+        InetAddress addr = address;
+        try {
+            if (addr == null) {
+                String ip = System.getProperty("net.mdns.interface");
+                if (ip != null) {
+                    addr = InetAddress.getByName(ip);
+                } else {
+                    addr = InetAddress.getLocalHost();
+                    if (addr.isLoopbackAddress()) {
+                        // Find local address that isn't a loopback address
+                        InetAddress[] addresses = NetworkTopologyDiscovery.Factory.getInstance().getInetAddresses();
+                        if (addresses.length > 0) {
+                            addr = addresses[0];
+                        }
+                    }
+                }
+                aName = addr.getHostName();
+                if (addr.isLoopbackAddress()) {
+                    logger.warning("Could not find any address beside the loopback.");
+                }
+            } else {
+                aName = addr.getHostName();
+            }
+            if (aName.contains("in-addr.arpa") || (aName.equals(addr.getHostAddress()))) {
+                aName = ((jmdnsName != null) && (jmdnsName.length() > 0) ? jmdnsName : addr.getHostAddress());
+            }
+        } catch (final IOException e) {
+            logger.log(Level.WARNING, "Could not intialize the host network interface on " + address + "because of an error: " + e.getMessage(), e);
+            // This is only used for running unit test on Debian / Ubuntu
+            addr = loopbackAddress();
+            aName = ((jmdnsName != null) && (jmdnsName.length() > 0) ? jmdnsName : "computer");
+        }
+        // A host name with "." is illegal. so strip off everything and append .local.
+        aName = aName.replace('.', '-');
+        aName += ".local.";
+        localhost = new HostInfo(addr, aName, dns);
+        return localhost;
+    }
+
+    private static InetAddress loopbackAddress() {
+        try {
+            return InetAddress.getByName(null);
+        } catch (UnknownHostException exception) {
+            return null;
+        }
+    }
+
+    /**
+     * This is used to create a unique name for the host name.
+     */
+    private int hostNameCount;
+
+    private HostInfo(final InetAddress address, final String name, final JmDNSImpl dns) {
+        super();
+        this._state = new HostInfoState(dns);
+        this._address = address;
+        this._name = name;
+        if (address != null) {
+            try {
+                _interfaze = NetworkInterface.getByInetAddress(address);
+            } catch (Exception exception) {
+                logger.log(Level.SEVERE, "LocalHostInfo() exception ", exception);
+            }
+        }
+    }
+
+    public String getName() {
+        return _name;
+    }
+
+    public InetAddress getInetAddress() {
+        return _address;
+    }
+
+    Inet4Address getInet4Address() {
+        if (this.getInetAddress() instanceof Inet4Address) {
+            return (Inet4Address) _address;
+        }
+        return null;
+    }
+
+    Inet6Address getInet6Address() {
+        if (this.getInetAddress() instanceof Inet6Address) {
+            return (Inet6Address) _address;
+        }
+        return null;
+    }
+
+    public NetworkInterface getInterface() {
+        return _interfaze;
+    }
+
+    public boolean conflictWithRecord(DNSRecord.Address record) {
+        DNSRecord.Address hostAddress = this.getDNSAddressRecord(record.getRecordType(), record.isUnique(), DNSConstants.DNS_TTL);
+        if (hostAddress != null) {
+            return hostAddress.sameType(record) && hostAddress.sameName(record) && (!hostAddress.sameValue(record));
+        }
+        return false;
+    }
+
+    synchronized String incrementHostName() {
+        hostNameCount++;
+        int plocal = _name.indexOf(".local.");
+        int punder = _name.lastIndexOf('-');
+        _name = _name.substring(0, (punder == -1 ? plocal : punder)) + "-" + hostNameCount + ".local.";
+        return _name;
+    }
+
+    boolean shouldIgnorePacket(DatagramPacket packet) {
+        boolean result = false;
+        if (this.getInetAddress() != null) {
+            InetAddress from = packet.getAddress();
+            if (from != null) {
+                if (from.isLinkLocalAddress() && (!this.getInetAddress().isLinkLocalAddress())) {
+                    // Ignore linklocal packets on regular interfaces, unless this is
+                    // also a linklocal interface. This is to avoid duplicates. This is
+                    // a terrible hack caused by the lack of an API to get the address
+                    // of the interface on which the packet was received.
+                    result = true;
+                }
+                if (from.isLoopbackAddress() && (!this.getInetAddress().isLoopbackAddress())) {
+                    // Ignore loopback packets on a regular interface unless this is also a loopback interface.
+                    result = true;
+                }
+            }
+        }
+        return result;
+    }
+
+    DNSRecord.Address getDNSAddressRecord(DNSRecordType type, boolean unique, int ttl) {
+        switch (type) {
+            case TYPE_A:
+                return this.getDNS4AddressRecord(unique, ttl);
+            case TYPE_A6:
+            case TYPE_AAAA:
+                return this.getDNS6AddressRecord(unique, ttl);
+            default:
+        }
+        return null;
+    }
+
+    private DNSRecord.Address getDNS4AddressRecord(boolean unique, int ttl) {
+        if ((this.getInetAddress() instanceof Inet4Address) || ((this.getInetAddress() instanceof Inet6Address) && (((Inet6Address) this.getInetAddress()).isIPv4CompatibleAddress()))) {
+            return new DNSRecord.IPv4Address(this.getName(), DNSRecordClass.CLASS_IN, unique, ttl, this.getInetAddress());
+        }
+        return null;
+    }
+
+    private DNSRecord.Address getDNS6AddressRecord(boolean unique, int ttl) {
+        if (this.getInetAddress() instanceof Inet6Address) {
+            return new DNSRecord.IPv6Address(this.getName(), DNSRecordClass.CLASS_IN, unique, ttl, this.getInetAddress());
+        }
+        return null;
+    }
+
+    DNSRecord.Pointer getDNSReverseAddressRecord(DNSRecordType type, boolean unique, int ttl) {
+        switch (type) {
+            case TYPE_A:
+                return this.getDNS4ReverseAddressRecord(unique, ttl);
+            case TYPE_A6:
+            case TYPE_AAAA:
+                return this.getDNS6ReverseAddressRecord(unique, ttl);
+            default:
+        }
+        return null;
+    }
+
+    private DNSRecord.Pointer getDNS4ReverseAddressRecord(boolean unique, int ttl) {
+        if (this.getInetAddress() instanceof Inet4Address) {
+            return new DNSRecord.Pointer(this.getInetAddress().getHostAddress() + ".in-addr.arpa.", DNSRecordClass.CLASS_IN, unique, ttl, this.getName());
+        }
+        if ((this.getInetAddress() instanceof Inet6Address) && (((Inet6Address) this.getInetAddress()).isIPv4CompatibleAddress())) {
+            byte[] rawAddress = this.getInetAddress().getAddress();
+            String address = (rawAddress[12] & 0xff) + "." + (rawAddress[13] & 0xff) + "." + (rawAddress[14] & 0xff) + "." + (rawAddress[15] & 0xff);
+            return new DNSRecord.Pointer(address + ".in-addr.arpa.", DNSRecordClass.CLASS_IN, unique, ttl, this.getName());
+        }
+        return null;
+    }
+
+    private DNSRecord.Pointer getDNS6ReverseAddressRecord(boolean unique, int ttl) {
+        if (this.getInetAddress() instanceof Inet6Address) {
+            return new DNSRecord.Pointer(this.getInetAddress().getHostAddress() + ".ip6.arpa.", DNSRecordClass.CLASS_IN, unique, ttl, this.getName());
+        }
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder(1024);
+        buf.append("local host info[");
+        buf.append(getName() != null ? getName() : "no name");
+        buf.append(", ");
+        buf.append(getInterface() != null ? getInterface().getDisplayName() : "???");
+        buf.append(":");
+        buf.append(getInetAddress() != null ? getInetAddress().getHostAddress() : "no address");
+        buf.append(", ");
+        buf.append(_state);
+        buf.append("]");
+        return buf.toString();
+    }
+
+    public Collection<DNSRecord> answers(boolean unique, int ttl) {
+        List<DNSRecord> list = new ArrayList<DNSRecord>();
+        DNSRecord answer = this.getDNS4AddressRecord(unique, ttl);
+        if (answer != null) {
+            list.add(answer);
+        }
+        answer = this.getDNS6AddressRecord(unique, ttl);
+        if (answer != null) {
+            list.add(answer);
+        }
+        return list;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public JmDNSImpl getDns() {
+        return this._state.getDns();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean advanceState(DNSTask task) {
+        return this._state.advanceState(task);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void removeAssociationWithTask(DNSTask task) {
+        this._state.removeAssociationWithTask(task);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean revertState() {
+        return this._state.revertState();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void associateWithTask(DNSTask task, DNSState state) {
+        this._state.associateWithTask(task, state);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isAssociatedWithTask(DNSTask task, DNSState state) {
+        return this._state.isAssociatedWithTask(task, state);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean cancelState() {
+        return this._state.cancelState();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean closeState() {
+        return this._state.closeState();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean recoverState() {
+        return this._state.recoverState();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isProbing() {
+        return this._state.isProbing();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isAnnouncing() {
+        return this._state.isAnnouncing();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isAnnounced() {
+        return this._state.isAnnounced();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isCanceling() {
+        return this._state.isCanceling();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isCanceled() {
+        return this._state.isCanceled();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isClosing() {
+        return this._state.isClosing();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isClosed() {
+        return this._state.isClosed();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean waitForAnnounced(long timeout) {
+        return _state.waitForAnnounced(timeout);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean waitForCanceled(long timeout) {
+        if (_address == null) {
+            // No need to wait this was never announced.
+            return true;
+        }
+        return _state.waitForCanceled(timeout);
+    }
+
+}
diff --git a/src/javax/jmdns/impl/JmDNSImpl.java b/src/javax/jmdns/impl/JmDNSImpl.java
new file mode 100644
index 0000000..3e64130
--- /dev/null
+++ b/src/javax/jmdns/impl/JmDNSImpl.java
@@ -0,0 +1,2223 @@
+// /Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+import java.net.SocketException;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.jmdns.JmDNS;
+import javax.jmdns.ServiceEvent;
+import javax.jmdns.ServiceInfo;
+import javax.jmdns.ServiceInfo.Fields;
+import javax.jmdns.ServiceListener;
+import javax.jmdns.ServiceTypeListener;
+import javax.jmdns.impl.ListenerStatus.ServiceListenerStatus;
+import javax.jmdns.impl.ListenerStatus.ServiceTypeListenerStatus;
+import javax.jmdns.impl.constants.DNSConstants;
+import javax.jmdns.impl.constants.DNSRecordClass;
+import javax.jmdns.impl.constants.DNSRecordType;
+import javax.jmdns.impl.constants.DNSState;
+import javax.jmdns.impl.tasks.DNSTask;
+
+// REMIND: multiple IP addresses
+
+/**
+ * mDNS implementation in Java.
+ *
+ * @author Arthur van Hoff, Rick Blair, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Scott Lewis
+ */
+public class JmDNSImpl extends JmDNS implements DNSStatefulObject, DNSTaskStarter {
+    private static Logger logger = Logger.getLogger(JmDNSImpl.class.getName());
+
+    public enum Operation {
+        Remove, Update, Add, RegisterServiceType, Noop
+    }
+
+    /**
+     * This is the multicast group, we are listening to for multicast DNS messages.
+     */
+    private volatile InetAddress                                     _group;
+    /**
+     * This is our multicast socket.
+     */
+    private volatile MulticastSocket                                 _socket;
+
+    /**
+     * Holds instances of JmDNS.DNSListener. Must by a synchronized collection, because it is updated from concurrent threads.
+     */
+    private final List<DNSListener>                                  _listeners;
+
+    /**
+     * Holds instances of ServiceListener's. Keys are Strings holding a fully qualified service type. Values are LinkedList's of ServiceListener's.
+     */
+    private final ConcurrentMap<String, List<ServiceListenerStatus>> _serviceListeners;
+
+    /**
+     * Holds instances of ServiceTypeListener's.
+     */
+    private final Set<ServiceTypeListenerStatus>                     _typeListeners;
+
+    /**
+     * Cache for DNSEntry's.
+     */
+    private final DNSCache                                           _cache;
+
+    /**
+     * This hashtable holds the services that have been registered. Keys are instances of String which hold an all lower-case version of the fully qualified service name. Values are instances of ServiceInfo.
+     */
+    private final ConcurrentMap<String, ServiceInfo>                 _services;
+
+    /**
+     * This hashtable holds the service types that have been registered or that have been received in an incoming datagram.<br/>
+     * Keys are instances of String which hold an all lower-case version of the fully qualified service type.<br/>
+     * Values hold the fully qualified service type.
+     */
+    private final ConcurrentMap<String, ServiceTypeEntry>            _serviceTypes;
+
+    private volatile Delegate                                        _delegate;
+
+    /**
+     * This is used to store type entries. The type is stored as a call variable and the map support the subtypes.
+     * <p>
+     * The key is the lowercase version as the value is the case preserved version.
+     * </p>
+     */
+    public static class ServiceTypeEntry extends AbstractMap<String, String> implements Cloneable {
+
+        private final Set<Map.Entry<String, String>> _entrySet;
+
+        private final String                         _type;
+
+        private static class SubTypeEntry implements Entry<String, String>, java.io.Serializable, Cloneable {
+
+            private static final long serialVersionUID = 9188503522395855322L;
+
+            private final String      _key;
+            private final String      _value;
+
+            public SubTypeEntry(String subtype) {
+                super();
+                _value = (subtype != null ? subtype : "");
+                _key = _value.toLowerCase();
+            }
+
+            /**
+             * {@inheritDoc}
+             */
+            @Override
+            public String getKey() {
+                return _key;
+            }
+
+            /**
+             * {@inheritDoc}
+             */
+            @Override
+            public String getValue() {
+                return _value;
+            }
+
+            /**
+             * Replaces the value corresponding to this entry with the specified value (optional operation). This implementation simply throws <tt>UnsupportedOperationException</tt>, as this class implements an <i>immutable</i> map entry.
+             *
+             * @param value
+             *            new value to be stored in this entry
+             * @return (Does not return)
+             * @exception UnsupportedOperationException
+             *                always
+             */
+            @Override
+            public String setValue(String value) {
+                throw new UnsupportedOperationException();
+            }
+
+            /**
+             * {@inheritDoc}
+             */
+            @Override
+            public boolean equals(Object entry) {
+                if (!(entry instanceof Map.Entry)) {
+                    return false;
+                }
+                return this.getKey().equals(((Map.Entry<?, ?>) entry).getKey()) && this.getValue().equals(((Map.Entry<?, ?>) entry).getValue());
+            }
+
+            /**
+             * {@inheritDoc}
+             */
+            @Override
+            public int hashCode() {
+                return (_key == null ? 0 : _key.hashCode()) ^ (_value == null ? 0 : _value.hashCode());
+            }
+
+            /*
+             * (non-Javadoc)
+             * @see java.lang.Object#clone()
+             */
+            @Override
+            public SubTypeEntry clone() {
+                // Immutable object
+                return this;
+            }
+
+            /**
+             * {@inheritDoc}
+             */
+            @Override
+            public String toString() {
+                return _key + "=" + _value;
+            }
+
+        }
+
+        public ServiceTypeEntry(String type) {
+            super();
+            this._type = type;
+            this._entrySet = new HashSet<Map.Entry<String, String>>();
+        }
+
+        /**
+         * The type associated with this entry.
+         *
+         * @return the type
+         */
+        public String getType() {
+            return _type;
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see java.util.AbstractMap#entrySet()
+         */
+        @Override
+        public Set<Map.Entry<String, String>> entrySet() {
+            return _entrySet;
+        }
+
+        /**
+         * Returns <code>true</code> if this set contains the specified element. More formally, returns <code>true</code> if and only if this set contains an element <code>e</code> such that
+         * <code>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</code>.
+         *
+         * @param subtype
+         *            element whose presence in this set is to be tested
+         * @return <code>true</code> if this set contains the specified element
+         */
+        public boolean contains(String subtype) {
+            return subtype != null && this.containsKey(subtype.toLowerCase());
+        }
+
+        /**
+         * Adds the specified element to this set if it is not already present. More formally, adds the specified element <code>e</code> to this set if this set contains no element <code>e2</code> such that
+         * <code>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</code>. If this set already contains the element, the call leaves the set unchanged and returns <code>false</code>.
+         *
+         * @param subtype
+         *            element to be added to this set
+         * @return <code>true</code> if this set did not already contain the specified element
+         */
+        public boolean add(String subtype) {
+            if (subtype == null || this.contains(subtype)) {
+                return false;
+            }
+            _entrySet.add(new SubTypeEntry(subtype));
+            return true;
+        }
+
+        /**
+         * Returns an iterator over the elements in this set. The elements are returned in no particular order (unless this set is an instance of some class that provides a guarantee).
+         *
+         * @return an iterator over the elements in this set
+         */
+        public Iterator<String> iterator() {
+            return this.keySet().iterator();
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see java.util.AbstractMap#clone()
+         */
+        @Override
+        public ServiceTypeEntry clone() {
+            ServiceTypeEntry entry = new ServiceTypeEntry(this.getType());
+            for (Map.Entry<String, String> subTypeEntry : this.entrySet()) {
+                entry.add(subTypeEntry.getValue());
+            }
+            return entry;
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see java.util.AbstractMap#toString()
+         */
+        @Override
+        public String toString() {
+            final StringBuilder aLog = new StringBuilder(200);
+            if (this.isEmpty()) {
+                aLog.append("empty");
+            } else {
+                for (String value : this.values()) {
+                    aLog.append(value);
+                    aLog.append(", ");
+                }
+                aLog.setLength(aLog.length() - 2);
+            }
+            return aLog.toString();
+        }
+
+    }
+
+    /**
+     * This is the shutdown hook, we registered with the java runtime.
+     */
+    protected Thread                                      _shutdown;
+
+    /**
+     * Handle on the local host
+     */
+    private HostInfo                                      _localHost;
+
+    private Thread                                        _incomingListener;
+
+    /**
+     * Throttle count. This is used to count the overall number of probes sent by JmDNS. When the last throttle increment happened .
+     */
+    private int                                           _throttle;
+
+    /**
+     * Last throttle increment.
+     */
+    private long                                          _lastThrottleIncrement;
+
+    private final ExecutorService                         _executor = Executors.newSingleThreadExecutor();
+
+    //
+    // 2009-09-16 ldeck: adding docbug patch with slight ammendments
+    // 'Fixes two deadlock conditions involving JmDNS.close() - ID: 1473279'
+    //
+    // ---------------------------------------------------
+    /**
+     * The timer that triggers our announcements. We can't use the main timer object, because that could cause a deadlock where Prober waits on JmDNS.this lock held by close(), close() waits for us to finish, and we wait for Prober to give us back
+     * the timer thread so we can announce. (Patch from docbug in 2006-04-19 still wasn't patched .. so I'm doing it!)
+     */
+    // private final Timer _cancelerTimer;
+    // ---------------------------------------------------
+
+    /**
+     * The source for random values. This is used to introduce random delays in responses. This reduces the potential for collisions on the network.
+     */
+    private final static Random                           _random   = new Random();
+
+    /**
+     * This lock is used to coordinate processing of incoming and outgoing messages. This is needed, because the Rendezvous Conformance Test does not forgive race conditions.
+     */
+    private final ReentrantLock                           _ioLock   = new ReentrantLock();
+
+    /**
+     * If an incoming package which needs an answer is truncated, we store it here. We add more incoming DNSRecords to it, until the JmDNS.Responder timer picks it up.<br/>
+     * FIXME [PJYF June 8 2010]: This does not work well with multiple planned answers for packages that came in from different clients.
+     */
+    private DNSIncoming                                   _plannedAnswer;
+
+    // State machine
+
+    /**
+     * This hashtable is used to maintain a list of service types being collected by this JmDNS instance. The key of the hashtable is a service type name, the value is an instance of JmDNS.ServiceCollector.
+     *
+     * @see #list
+     */
+    private final ConcurrentMap<String, ServiceCollector> _serviceCollectors;
+
+    private final String                                  _name;
+
+    /**
+     * Main method to display API information if run from java -jar
+     *
+     * @param argv
+     *            the command line arguments
+     */
+    public static void main(String[] argv) {
+        String version = null;
+        try {
+            final Properties pomProperties = new Properties();
+            pomProperties.load(JmDNSImpl.class.getResourceAsStream("/META-INF/maven/javax.jmdns/jmdns/pom.properties"));
+            version = pomProperties.getProperty("version");
+        } catch (Exception e) {
+            version = "RUNNING.IN.IDE.FULL";
+        }
+        System.out.println("JmDNS version \"" + version + "\"");
+        System.out.println(" ");
+
+        System.out.println("Running on java version \"" + System.getProperty("java.version") + "\"" + " (build " + System.getProperty("java.runtime.version") + ")" + " from " + System.getProperty("java.vendor"));
+
+        System.out.println("Operating environment \"" + System.getProperty("os.name") + "\"" + " version " + System.getProperty("os.version") + " on " + System.getProperty("os.arch"));
+
+        System.out.println("For more information on JmDNS please visit https://sourceforge.net/projects/jmdns/");
+    }
+
+    /**
+     * Create an instance of JmDNS and bind it to a specific network interface given its IP-address.
+     *
+     * @param address
+     *            IP address to bind to.
+     * @param name
+     *            name of the newly created JmDNS
+     * @exception IOException
+     */
+    public JmDNSImpl(InetAddress address, String name) throws IOException {
+        super();
+        if (logger.isLoggable(Level.FINER)) {
+            logger.finer("JmDNS instance created");
+        }
+        _cache = new DNSCache(100);
+
+        _listeners = Collections.synchronizedList(new ArrayList<DNSListener>());
+        _serviceListeners = new ConcurrentHashMap<String, List<ServiceListenerStatus>>();
+        _typeListeners = Collections.synchronizedSet(new HashSet<ServiceTypeListenerStatus>());
+        _serviceCollectors = new ConcurrentHashMap<String, ServiceCollector>();
+
+        _services = new ConcurrentHashMap<String, ServiceInfo>(20);
+        _serviceTypes = new ConcurrentHashMap<String, ServiceTypeEntry>(20);
+
+        _localHost = HostInfo.newHostInfo(address, this, name);
+        _name = (name != null ? name : _localHost.getName());
+
+        // _cancelerTimer = new Timer("JmDNS.cancelerTimer");
+
+        // (ldeck 2.1.1) preventing shutdown blocking thread
+        // -------------------------------------------------
+        // _shutdown = new Thread(new Shutdown(), "JmDNS.Shutdown");
+        // Runtime.getRuntime().addShutdownHook(_shutdown);
+
+        // -------------------------------------------------
+
+        // Bind to multicast socket
+        this.openMulticastSocket(this.getLocalHost());
+        this.start(this.getServices().values());
+
+        this.startReaper();
+    }
+
+    private void start(Collection<? extends ServiceInfo> serviceInfos) {
+        if (_incomingListener == null) {
+            _incomingListener = new SocketListener(this);
+            _incomingListener.start();
+        }
+        this.startProber();
+        for (ServiceInfo info : serviceInfos) {
+            try {
+                this.registerService(new ServiceInfoImpl(info));
+            } catch (final Exception exception) {
+                logger.log(Level.WARNING, "start() Registration exception ", exception);
+            }
+        }
+    }
+
+    private void openMulticastSocket(HostInfo hostInfo) throws IOException {
+        if (_group == null) {
+            if (hostInfo.getInetAddress() instanceof Inet6Address) {
+                _group = InetAddress.getByName(DNSConstants.MDNS_GROUP_IPV6);
+            } else {
+                _group = InetAddress.getByName(DNSConstants.MDNS_GROUP);
+            }
+        }
+        if (_socket != null) {
+            this.closeMulticastSocket();
+        }
+        _socket = new MulticastSocket(DNSConstants.MDNS_PORT);
+        if ((hostInfo != null) && (hostInfo.getInterface() != null)) {
+            try {
+                _socket.setNetworkInterface(hostInfo.getInterface());
+            } catch (SocketException e) {
+                if (logger.isLoggable(Level.FINE)) {
+                    logger.fine("openMulticastSocket() Set network interface exception: " + e.getMessage());
+                }
+            }
+        }
+        _socket.setTimeToLive(255);
+        _socket.joinGroup(_group);
+    }
+
+    private void closeMulticastSocket() {
+        // jP: 20010-01-18. See below. We'll need this monitor...
+        // assert (Thread.holdsLock(this));
+        if (logger.isLoggable(Level.FINER)) {
+            logger.finer("closeMulticastSocket()");
+        }
+        if (_socket != null) {
+            // close socket
+            try {
+                try {
+                    _socket.leaveGroup(_group);
+                } catch (SocketException exception) {
+                    //
+                }
+                _socket.close();
+                // jP: 20010-01-18. It isn't safe to join() on the listener
+                // thread - it attempts to lock the IoLock object, and deadlock
+                // ensues. Per issue #2933183, changed this to wait on the JmDNS
+                // monitor, checking on each notify (or timeout) that the
+                // listener thread has stopped.
+                //
+                while (_incomingListener != null && _incomingListener.isAlive()) {
+                    synchronized (this) {
+                        try {
+                            if (_incomingListener != null && _incomingListener.isAlive()) {
+                                // wait time is arbitrary, we're really expecting notification.
+                                if (logger.isLoggable(Level.FINER)) {
+                                    logger.finer("closeMulticastSocket(): waiting for jmDNS monitor");
+                                }
+                                this.wait(1000);
+                            }
+                        } catch (InterruptedException ignored) {
+                            // Ignored
+                        }
+                    }
+                }
+                _incomingListener = null;
+            } catch (final Exception exception) {
+                logger.log(Level.WARNING, "closeMulticastSocket() Close socket exception ", exception);
+            }
+            _socket = null;
+        }
+    }
+
+    // State machine
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean advanceState(DNSTask task) {
+        return this._localHost.advanceState(task);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean revertState() {
+        return this._localHost.revertState();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean cancelState() {
+        return this._localHost.cancelState();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean closeState() {
+        return this._localHost.closeState();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean recoverState() {
+        return this._localHost.recoverState();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public JmDNSImpl getDns() {
+        return this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void associateWithTask(DNSTask task, DNSState state) {
+        this._localHost.associateWithTask(task, state);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void removeAssociationWithTask(DNSTask task) {
+        this._localHost.removeAssociationWithTask(task);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isAssociatedWithTask(DNSTask task, DNSState state) {
+        return this._localHost.isAssociatedWithTask(task, state);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isProbing() {
+        return this._localHost.isProbing();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isAnnouncing() {
+        return this._localHost.isAnnouncing();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isAnnounced() {
+        return this._localHost.isAnnounced();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isCanceling() {
+        return this._localHost.isCanceling();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isCanceled() {
+        return this._localHost.isCanceled();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isClosing() {
+        return this._localHost.isClosing();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isClosed() {
+        return this._localHost.isClosed();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean waitForAnnounced(long timeout) {
+        return this._localHost.waitForAnnounced(timeout);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean waitForCanceled(long timeout) {
+        return this._localHost.waitForCanceled(timeout);
+    }
+
+    /**
+     * Return the DNSCache associated with the cache variable
+     *
+     * @return DNS cache
+     */
+    public DNSCache getCache() {
+        return _cache;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getName() {
+        return _name;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getHostName() {
+        return _localHost.getName();
+    }
+
+    /**
+     * Returns the local host info
+     *
+     * @return local host info
+     */
+    public HostInfo getLocalHost() {
+        return _localHost;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public InetAddress getInetAddress() throws IOException {
+        return _localHost.getInetAddress();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    @Deprecated
+    public InetAddress getInterface() throws IOException {
+        return _socket.getInterface();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ServiceInfo getServiceInfo(String type, String name) {
+        return this.getServiceInfo(type, name, false, DNSConstants.SERVICE_INFO_TIMEOUT);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ServiceInfo getServiceInfo(String type, String name, long timeout) {
+        return this.getServiceInfo(type, name, false, timeout);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ServiceInfo getServiceInfo(String type, String name, boolean persistent) {
+        return this.getServiceInfo(type, name, persistent, DNSConstants.SERVICE_INFO_TIMEOUT);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ServiceInfo getServiceInfo(String type, String name, boolean persistent, long timeout) {
+        final ServiceInfoImpl info = this.resolveServiceInfo(type, name, "", persistent);
+        this.waitForInfoData(info, timeout);
+        return (info.hasData() ? info : null);
+    }
+
+    ServiceInfoImpl resolveServiceInfo(String type, String name, String subtype, boolean persistent) {
+        this.cleanCache();
+        String loType = type.toLowerCase();
+        this.registerServiceType(type);
+        if (_serviceCollectors.putIfAbsent(loType, new ServiceCollector(type)) == null) {
+            this.addServiceListener(loType, _serviceCollectors.get(loType), ListenerStatus.SYNCHONEOUS);
+        }
+
+        // Check if the answer is in the cache.
+        final ServiceInfoImpl info = this.getServiceInfoFromCache(type, name, subtype, persistent);
+        // We still run the resolver to do the dispatch but if the info is already there it will quit immediately
+        this.startServiceInfoResolver(info);
+
+        return info;
+    }
+
+    ServiceInfoImpl getServiceInfoFromCache(String type, String name, String subtype, boolean persistent) {
+        // Check if the answer is in the cache.
+        ServiceInfoImpl info = new ServiceInfoImpl(type, name, subtype, 0, 0, 0, persistent, (byte[]) null);
+        DNSEntry pointerEntry = this.getCache().getDNSEntry(new DNSRecord.Pointer(type, DNSRecordClass.CLASS_ANY, false, 0, info.getQualifiedName()));
+        if (pointerEntry instanceof DNSRecord) {
+            ServiceInfoImpl cachedInfo = (ServiceInfoImpl) ((DNSRecord) pointerEntry).getServiceInfo(persistent);
+            if (cachedInfo != null) {
+                // To get a complete info record we need to retrieve the service, address and the text bytes.
+
+                Map<Fields, String> map = cachedInfo.getQualifiedNameMap();
+                byte[] srvBytes = null;
+                String server = "";
+                DNSEntry serviceEntry = this.getCache().getDNSEntry(info.getQualifiedName(), DNSRecordType.TYPE_SRV, DNSRecordClass.CLASS_ANY);
+                if (serviceEntry instanceof DNSRecord) {
+                    ServiceInfo cachedServiceEntryInfo = ((DNSRecord) serviceEntry).getServiceInfo(persistent);
+                    if (cachedServiceEntryInfo != null) {
+                        cachedInfo = new ServiceInfoImpl(map, cachedServiceEntryInfo.getPort(), cachedServiceEntryInfo.getWeight(), cachedServiceEntryInfo.getPriority(), persistent, (byte[]) null);
+                        srvBytes = cachedServiceEntryInfo.getTextBytes();
+                        server = cachedServiceEntryInfo.getServer();
+                    }
+                }
+                DNSEntry addressEntry = this.getCache().getDNSEntry(server, DNSRecordType.TYPE_A, DNSRecordClass.CLASS_ANY);
+                if (addressEntry instanceof DNSRecord) {
+                    ServiceInfo cachedAddressInfo = ((DNSRecord) addressEntry).getServiceInfo(persistent);
+                    if (cachedAddressInfo != null) {
+                        for (Inet4Address address : cachedAddressInfo.getInet4Addresses()) {
+                            cachedInfo.addAddress(address);
+                        }
+                        cachedInfo._setText(cachedAddressInfo.getTextBytes());
+                    }
+                }
+                addressEntry = this.getCache().getDNSEntry(server, DNSRecordType.TYPE_AAAA, DNSRecordClass.CLASS_ANY);
+                if (addressEntry instanceof DNSRecord) {
+                    ServiceInfo cachedAddressInfo = ((DNSRecord) addressEntry).getServiceInfo(persistent);
+                    if (cachedAddressInfo != null) {
+                        for (Inet6Address address : cachedAddressInfo.getInet6Addresses()) {
+                            cachedInfo.addAddress(address);
+                        }
+                        cachedInfo._setText(cachedAddressInfo.getTextBytes());
+                    }
+                }
+                DNSEntry textEntry = this.getCache().getDNSEntry(cachedInfo.getQualifiedName(), DNSRecordType.TYPE_TXT, DNSRecordClass.CLASS_ANY);
+                if (textEntry instanceof DNSRecord) {
+                    ServiceInfo cachedTextInfo = ((DNSRecord) textEntry).getServiceInfo(persistent);
+                    if (cachedTextInfo != null) {
+                        cachedInfo._setText(cachedTextInfo.getTextBytes());
+                    }
+                }
+                if (cachedInfo.getTextBytes().length == 0) {
+                    cachedInfo._setText(srvBytes);
+                }
+                if (cachedInfo.hasData()) {
+                    info = cachedInfo;
+                }
+            }
+        }
+        return info;
+    }
+
+    private void waitForInfoData(ServiceInfo info, long timeout) {
+        synchronized (info) {
+            long loops = (timeout / 200L);
+            if (loops < 1) {
+                loops = 1;
+            }
+            for (int i = 0; i < loops; i++) {
+                if (info.hasData()) {
+                    break;
+                }
+                try {
+                    info.wait(200);
+                } catch (final InterruptedException e) {
+                    /* Stub */
+                }
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void requestServiceInfo(String type, String name) {
+        this.requestServiceInfo(type, name, false, DNSConstants.SERVICE_INFO_TIMEOUT);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void requestServiceInfo(String type, String name, boolean persistent) {
+        this.requestServiceInfo(type, name, persistent, DNSConstants.SERVICE_INFO_TIMEOUT);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void requestServiceInfo(String type, String name, long timeout) {
+        this.requestServiceInfo(type, name, false, DNSConstants.SERVICE_INFO_TIMEOUT);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void requestServiceInfo(String type, String name, boolean persistent, long timeout) {
+        final ServiceInfoImpl info = this.resolveServiceInfo(type, name, "", persistent);
+        this.waitForInfoData(info, timeout);
+    }
+
+    void handleServiceResolved(ServiceEvent event) {
+        List<ServiceListenerStatus> list = _serviceListeners.get(event.getType().toLowerCase());
+        final List<ServiceListenerStatus> listCopy;
+        if ((list != null) && (!list.isEmpty())) {
+            if ((event.getInfo() != null) && event.getInfo().hasData()) {
+                final ServiceEvent localEvent = event;
+                synchronized (list) {
+                    listCopy = new ArrayList<ServiceListenerStatus>(list);
+                }
+                for (final ServiceListenerStatus listener : listCopy) {
+                    _executor.submit(new Runnable() {
+                        /** {@inheritDoc} */
+                        @Override
+                        public void run() {
+                            listener.serviceResolved(localEvent);
+                        }
+                    });
+                }
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void addServiceTypeListener(ServiceTypeListener listener) throws IOException {
+        ServiceTypeListenerStatus status = new ServiceTypeListenerStatus(listener, ListenerStatus.ASYNCHONEOUS);
+        _typeListeners.add(status);
+
+        // report cached service types
+        for (String type : _serviceTypes.keySet()) {
+            status.serviceTypeAdded(new ServiceEventImpl(this, type, "", null));
+        }
+
+        this.startTypeResolver();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void removeServiceTypeListener(ServiceTypeListener listener) {
+        ServiceTypeListenerStatus status = new ServiceTypeListenerStatus(listener, ListenerStatus.ASYNCHONEOUS);
+        _typeListeners.remove(status);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void addServiceListener(String type, ServiceListener listener) {
+        this.addServiceListener(type, listener, ListenerStatus.ASYNCHONEOUS);
+    }
+
+    private void addServiceListener(String type, ServiceListener listener, boolean synch) {
+        ServiceListenerStatus status = new ServiceListenerStatus(listener, synch);
+        final String loType = type.toLowerCase();
+        List<ServiceListenerStatus> list = _serviceListeners.get(loType);
+        if (list == null) {
+            if (_serviceListeners.putIfAbsent(loType, new LinkedList<ServiceListenerStatus>()) == null) {
+                if (_serviceCollectors.putIfAbsent(loType, new ServiceCollector(type)) == null) {
+                    // We have a problem here. The service collectors must be called synchronously so that their cache get cleaned up immediately or we will report .
+                    this.addServiceListener(loType, _serviceCollectors.get(loType), ListenerStatus.SYNCHONEOUS);
+                }
+            }
+            list = _serviceListeners.get(loType);
+        }
+        if (list != null) {
+            synchronized (list) {
+                if (!list.contains(listener)) {
+                    list.add(status);
+                }
+            }
+        }
+        // report cached service types
+        final List<ServiceEvent> serviceEvents = new ArrayList<ServiceEvent>();
+        Collection<DNSEntry> dnsEntryLits = this.getCache().allValues();
+        for (DNSEntry entry : dnsEntryLits) {
+            final DNSRecord record = (DNSRecord) entry;
+            if (record.getRecordType() == DNSRecordType.TYPE_SRV) {
+                if (record.getKey().endsWith(loType)) {
+                    // Do not used the record embedded method for generating event this will not work.
+                    // serviceEvents.add(record.getServiceEvent(this));
+                    serviceEvents.add(new ServiceEventImpl(this, record.getType(), toUnqualifiedName(record.getType(), record.getName()), record.getServiceInfo()));
+                }
+            }
+        }
+        // Actually call listener with all service events added above
+        for (ServiceEvent serviceEvent : serviceEvents) {
+            status.serviceAdded(serviceEvent);
+        }
+        // Create/start ServiceResolver
+        this.startServiceResolver(type);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void removeServiceListener(String type, ServiceListener listener) {
+        String loType = type.toLowerCase();
+        List<ServiceListenerStatus> list = _serviceListeners.get(loType);
+        if (list != null) {
+            synchronized (list) {
+                ServiceListenerStatus status = new ServiceListenerStatus(listener, ListenerStatus.ASYNCHONEOUS);
+                list.remove(status);
+                if (list.isEmpty()) {
+                    _serviceListeners.remove(loType, list);
+                }
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void registerService(ServiceInfo infoAbstract) throws IOException {
+        if (this.isClosing() || this.isClosed()) {
+            throw new IllegalStateException("This DNS is closed.");
+        }
+        final ServiceInfoImpl info = (ServiceInfoImpl) infoAbstract;
+
+        if (info.getDns() != null) {
+            if (info.getDns() != this) {
+                throw new IllegalStateException("A service information can only be registered with a single instamce of JmDNS.");
+            } else if (_services.get(info.getKey()) != null) {
+                throw new IllegalStateException("A service information can only be registered once.");
+            }
+        }
+        info.setDns(this);
+
+        this.registerServiceType(info.getTypeWithSubtype());
+
+        // bind the service to this address
+        info.recoverState();
+        info.setServer(_localHost.getName());
+        info.addAddress(_localHost.getInet4Address());
+        info.addAddress(_localHost.getInet6Address());
+
+        this.waitForAnnounced(DNSConstants.SERVICE_INFO_TIMEOUT);
+
+        this.makeServiceNameUnique(info);
+        while (_services.putIfAbsent(info.getKey(), info) != null) {
+            this.makeServiceNameUnique(info);
+        }
+
+        this.startProber();
+        info.waitForAnnounced(DNSConstants.SERVICE_INFO_TIMEOUT);
+
+        if (logger.isLoggable(Level.FINE)) {
+            logger.fine("registerService() JmDNS registered service as " + info);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void unregisterService(ServiceInfo infoAbstract) {
+        final ServiceInfoImpl info = (ServiceInfoImpl) _services.get(infoAbstract.getKey());
+
+        if (info != null) {
+            info.cancelState();
+            this.startCanceler();
+            info.waitForCanceled(DNSConstants.CLOSE_TIMEOUT);
+
+            _services.remove(info.getKey(), info);
+            if (logger.isLoggable(Level.FINE)) {
+                logger.fine("unregisterService() JmDNS unregistered service as " + info);
+            }
+        } else {
+            logger.warning("Removing unregistered service info: " + infoAbstract.getKey());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void unregisterAllServices() {
+        if (logger.isLoggable(Level.FINER)) {
+            logger.finer("unregisterAllServices()");
+        }
+
+        for (String name : _services.keySet()) {
+            ServiceInfoImpl info = (ServiceInfoImpl) _services.get(name);
+            if (info != null) {
+                if (logger.isLoggable(Level.FINER)) {
+                    logger.finer("Cancelling service info: " + info);
+                }
+                info.cancelState();
+            }
+        }
+        this.startCanceler();
+
+        for (String name : _services.keySet()) {
+            ServiceInfoImpl info = (ServiceInfoImpl) _services.get(name);
+            if (info != null) {
+                if (logger.isLoggable(Level.FINER)) {
+                    logger.finer("Wait for service info cancel: " + info);
+                }
+                info.waitForCanceled(DNSConstants.CLOSE_TIMEOUT);
+                _services.remove(name, info);
+            }
+        }
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean registerServiceType(String type) {
+        boolean typeAdded = false;
+        Map<Fields, String> map = ServiceInfoImpl.decodeQualifiedNameMapForType(type);
+        String domain = map.get(Fields.Domain);
+        String protocol = map.get(Fields.Protocol);
+        String application = map.get(Fields.Application);
+        String subtype = map.get(Fields.Subtype);
+
+        final String name = (application.length() > 0 ? "_" + application + "." : "") + (protocol.length() > 0 ? "_" + protocol + "." : "") + domain + ".";
+        final String loname = name.toLowerCase();
+        if (logger.isLoggable(Level.FINE)) {
+            logger.fine(this.getName() + ".registering service type: " + type + " as: " + name + (subtype.length() > 0 ? " subtype: " + subtype : ""));
+        }
+        if (!_serviceTypes.containsKey(loname) && !application.toLowerCase().equals("dns-sd") && !domain.toLowerCase().endsWith("in-addr.arpa") && !domain.toLowerCase().endsWith("ip6.arpa")) {
+            typeAdded = _serviceTypes.putIfAbsent(loname, new ServiceTypeEntry(name)) == null;
+            if (typeAdded) {
+                final ServiceTypeListenerStatus[] list = _typeListeners.toArray(new ServiceTypeListenerStatus[_typeListeners.size()]);
+                final ServiceEvent event = new ServiceEventImpl(this, name, "", null);
+                for (final ServiceTypeListenerStatus status : list) {
+                    _executor.submit(new Runnable() {
+                        /** {@inheritDoc} */
+                        @Override
+                        public void run() {
+                            status.serviceTypeAdded(event);
+                        }
+                    });
+                }
+            }
+        }
+        if (subtype.length() > 0) {
+            ServiceTypeEntry subtypes = _serviceTypes.get(loname);
+            if ((subtypes != null) && (!subtypes.contains(subtype))) {
+                synchronized (subtypes) {
+                    if (!subtypes.contains(subtype)) {
+                        typeAdded = true;
+                        subtypes.add(subtype);
+                        final ServiceTypeListenerStatus[] list = _typeListeners.toArray(new ServiceTypeListenerStatus[_typeListeners.size()]);
+                        final ServiceEvent event = new ServiceEventImpl(this, "_" + subtype + "._sub." + name, "", null);
+                        for (final ServiceTypeListenerStatus status : list) {
+                            _executor.submit(new Runnable() {
+                                /** {@inheritDoc} */
+                                @Override
+                                public void run() {
+                                    status.subTypeForServiceTypeAdded(event);
+                                }
+                            });
+                        }
+                    }
+                }
+            }
+        }
+        return typeAdded;
+    }
+
+    /**
+     * Generate a possibly unique name for a service using the information we have in the cache.
+     *
+     * @return returns true, if the name of the service info had to be changed.
+     */
+    private boolean makeServiceNameUnique(ServiceInfoImpl info) {
+        final String originalQualifiedName = info.getKey();
+        final long now = System.currentTimeMillis();
+
+        boolean collision;
+        do {
+            collision = false;
+
+            // Check for collision in cache
+            for (DNSEntry dnsEntry : this.getCache().getDNSEntryList(info.getKey())) {
+                if (DNSRecordType.TYPE_SRV.equals(dnsEntry.getRecordType()) && !dnsEntry.isExpired(now)) {
+                    final DNSRecord.Service s = (DNSRecord.Service) dnsEntry;
+                    if (s.getPort() != info.getPort() || !s.getServer().equals(_localHost.getName())) {
+                        if (logger.isLoggable(Level.FINER)) {
+                            logger.finer("makeServiceNameUnique() JmDNS.makeServiceNameUnique srv collision:" + dnsEntry + " s.server=" + s.getServer() + " " + _localHost.getName() + " equals:" + (s.getServer().equals(_localHost.getName())));
+                        }
+                        info.setName(incrementName(info.getName()));
+                        collision = true;
+                        break;
+                    }
+                }
+            }
+
+            // Check for collision with other service infos published by JmDNS
+            final ServiceInfo selfService = _services.get(info.getKey());
+            if (selfService != null && selfService != info) {
+                info.setName(incrementName(info.getName()));
+                collision = true;
+            }
+        }
+        while (collision);
+
+        return !(originalQualifiedName.equals(info.getKey()));
+    }
+
+    String incrementName(String name) {
+        String aName = name;
+        try {
+            final int l = aName.lastIndexOf('(');
+            final int r = aName.lastIndexOf(')');
+            if ((l >= 0) && (l < r)) {
+                aName = aName.substring(0, l) + "(" + (Integer.parseInt(aName.substring(l + 1, r)) + 1) + ")";
+            } else {
+                aName += " (2)";
+            }
+        } catch (final NumberFormatException e) {
+            aName += " (2)";
+        }
+        return aName;
+    }
+
+    /**
+     * Add a listener for a question. The listener will receive updates of answers to the question as they arrive, or from the cache if they are already available.
+     *
+     * @param listener
+     *            DSN listener
+     * @param question
+     *            DNS query
+     */
+    public void addListener(DNSListener listener, DNSQuestion question) {
+        final long now = System.currentTimeMillis();
+
+        // add the new listener
+        _listeners.add(listener);
+
+        // report existing matched records
+
+        if (question != null) {
+            for (DNSEntry dnsEntry : this.getCache().getDNSEntryList(question.getName().toLowerCase())) {
+                if (question.answeredBy(dnsEntry) && !dnsEntry.isExpired(now)) {
+                    listener.updateRecord(this.getCache(), now, dnsEntry);
+                }
+            }
+        }
+    }
+
+    /**
+     * Remove a listener from all outstanding questions. The listener will no longer receive any updates.
+     *
+     * @param listener
+     *            DSN listener
+     */
+    public void removeListener(DNSListener listener) {
+        _listeners.remove(listener);
+    }
+
+    /**
+     * Renew a service when the record become stale. If there is no service collector for the type this method does nothing.
+     *
+     * @param record
+     *            DNS record
+     */
+    public void renewServiceCollector(DNSRecord record) {
+        ServiceInfo info = record.getServiceInfo();
+        if (_serviceCollectors.containsKey(info.getType().toLowerCase())) {
+            // Create/start ServiceResolver
+            this.startServiceResolver(info.getType());
+        }
+    }
+
+    // Remind: Method updateRecord should receive a better name.
+    /**
+     * Notify all listeners that a record was updated.
+     *
+     * @param now
+     *            update date
+     * @param rec
+     *            DNS record
+     * @param operation
+     *            DNS cache operation
+     */
+    public void updateRecord(long now, DNSRecord rec, Operation operation) {
+        // We do not want to block the entire DNS while we are updating the record for each listener (service info)
+        {
+            List<DNSListener> listenerList = null;
+            synchronized (_listeners) {
+                listenerList = new ArrayList<DNSListener>(_listeners);
+            }
+            for (DNSListener listener : listenerList) {
+                listener.updateRecord(this.getCache(), now, rec);
+            }
+        }
+        if (DNSRecordType.TYPE_PTR.equals(rec.getRecordType()))
+        // if (DNSRecordType.TYPE_PTR.equals(rec.getRecordType()) || DNSRecordType.TYPE_SRV.equals(rec.getRecordType()))
+        {
+            ServiceEvent event = rec.getServiceEvent(this);
+            if ((event.getInfo() == null) || !event.getInfo().hasData()) {
+                // We do not care about the subtype because the info is only used if complete and the subtype will then be included.
+                ServiceInfo info = this.getServiceInfoFromCache(event.getType(), event.getName(), "", false);
+                if (info.hasData()) {
+                    event = new ServiceEventImpl(this, event.getType(), event.getName(), info);
+                }
+            }
+
+            List<ServiceListenerStatus> list = _serviceListeners.get(event.getType().toLowerCase());
+            final List<ServiceListenerStatus> serviceListenerList;
+            if (list != null) {
+                synchronized (list) {
+                    serviceListenerList = new ArrayList<ServiceListenerStatus>(list);
+                }
+            } else {
+                serviceListenerList = Collections.emptyList();
+            }
+            if (logger.isLoggable(Level.FINEST)) {
+                logger.finest(this.getName() + ".updating record for event: " + event + " list " + serviceListenerList + " operation: " + operation);
+            }
+            if (!serviceListenerList.isEmpty()) {
+                final ServiceEvent localEvent = event;
+
+                switch (operation) {
+                    case Add:
+                        for (final ServiceListenerStatus listener : serviceListenerList) {
+                            if (listener.isSynchronous()) {
+                                listener.serviceAdded(localEvent);
+                            } else {
+                                _executor.submit(new Runnable() {
+                                    /** {@inheritDoc} */
+                                    @Override
+                                    public void run() {
+                                        listener.serviceAdded(localEvent);
+                                    }
+                                });
+                            }
+                        }
+                        break;
+                    case Remove:
+                        for (final ServiceListenerStatus listener : serviceListenerList) {
+                            if (listener.isSynchronous()) {
+                                listener.serviceRemoved(localEvent);
+                            } else {
+                                _executor.submit(new Runnable() {
+                                    /** {@inheritDoc} */
+                                    @Override
+                                    public void run() {
+                                        listener.serviceRemoved(localEvent);
+                                    }
+                                });
+                            }
+                        }
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+    }
+
+    void handleRecord(DNSRecord record, long now) {
+        DNSRecord newRecord = record;
+
+        Operation cacheOperation = Operation.Noop;
+        final boolean expired = newRecord.isExpired(now);
+        if (logger.isLoggable(Level.FINE)) {
+            logger.fine(this.getName() + " handle response: " + newRecord);
+        }
+
+        // update the cache
+        if (!newRecord.isServicesDiscoveryMetaQuery() && !newRecord.isDomainDiscoveryQuery()) {
+            final boolean unique = newRecord.isUnique();
+            final DNSRecord cachedRecord = (DNSRecord) this.getCache().getDNSEntry(newRecord);
+            if (logger.isLoggable(Level.FINE)) {
+                logger.fine(this.getName() + " handle response cached record: " + cachedRecord);
+            }
+            if (unique) {
+                for (DNSEntry entry : this.getCache().getDNSEntryList(newRecord.getKey())) {
+                    if (newRecord.getRecordType().equals(entry.getRecordType()) && newRecord.getRecordClass().equals(entry.getRecordClass()) && (entry != cachedRecord)) {
+                        ((DNSRecord) entry).setWillExpireSoon(now);
+                    }
+                }
+            }
+            if (cachedRecord != null) {
+                if (expired) {
+                    // if the record has a 0 ttl that means we have a cancel record we need to delay the removal by 1s
+                    if (newRecord.getTTL() == 0) {
+                        cacheOperation = Operation.Noop;
+                        cachedRecord.setWillExpireSoon(now);
+                        // the actual record will be disposed of by the record reaper.
+                    } else {
+                        cacheOperation = Operation.Remove;
+                        this.getCache().removeDNSEntry(cachedRecord);
+                    }
+                } else {
+                    // If the record content has changed we need to inform our listeners.
+                    if (!newRecord.sameValue(cachedRecord) || (!newRecord.sameSubtype(cachedRecord) && (newRecord.getSubtype().length() > 0))) {
+                        if (newRecord.isSingleValued()) {
+                            cacheOperation = Operation.Update;
+                            this.getCache().replaceDNSEntry(newRecord, cachedRecord);
+                        } else {
+                            // Address record can have more than one value on multi-homed machines
+                            cacheOperation = Operation.Add;
+                            this.getCache().addDNSEntry(newRecord);
+                        }
+                    } else {
+                        cachedRecord.resetTTL(newRecord);
+                        newRecord = cachedRecord;
+                    }
+                }
+            } else {
+                if (!expired) {
+                    cacheOperation = Operation.Add;
+                    this.getCache().addDNSEntry(newRecord);
+                }
+            }
+        }
+
+        // Register new service types
+        if (newRecord.getRecordType() == DNSRecordType.TYPE_PTR) {
+            // handle DNSConstants.DNS_META_QUERY records
+            boolean typeAdded = false;
+            if (newRecord.isServicesDiscoveryMetaQuery()) {
+                // The service names are in the alias.
+                if (!expired) {
+                    typeAdded = this.registerServiceType(((DNSRecord.Pointer) newRecord).getAlias());
+                }
+                return;
+            }
+            typeAdded |= this.registerServiceType(newRecord.getName());
+            if (typeAdded && (cacheOperation == Operation.Noop)) {
+                cacheOperation = Operation.RegisterServiceType;
+            }
+        }
+
+        // notify the listeners
+        if (cacheOperation != Operation.Noop) {
+            this.updateRecord(now, newRecord, cacheOperation);
+        }
+
+    }
+
+    /**
+     * Handle an incoming response. Cache answers, and pass them on to the appropriate questions.
+     *
+     * @exception IOException
+     */
+    void handleResponse(DNSIncoming msg) throws IOException {
+        final long now = System.currentTimeMillis();
+
+        boolean hostConflictDetected = false;
+        boolean serviceConflictDetected = false;
+
+        for (DNSRecord newRecord : msg.getAllAnswers()) {
+            this.handleRecord(newRecord, now);
+
+            if (DNSRecordType.TYPE_A.equals(newRecord.getRecordType()) || DNSRecordType.TYPE_AAAA.equals(newRecord.getRecordType())) {
+                hostConflictDetected |= newRecord.handleResponse(this);
+            } else {
+                serviceConflictDetected |= newRecord.handleResponse(this);
+            }
+
+        }
+
+        if (hostConflictDetected || serviceConflictDetected) {
+            this.startProber();
+        }
+    }
+
+    /**
+     * Handle an incoming query. See if we can answer any part of it given our service infos.
+     *
+     * @param in
+     * @param addr
+     * @param port
+     * @exception IOException
+     */
+    void handleQuery(DNSIncoming in, InetAddress addr, int port) throws IOException {
+        if (logger.isLoggable(Level.FINE)) {
+            logger.fine(this.getName() + ".handle query: " + in);
+        }
+        // Track known answers
+        boolean conflictDetected = false;
+        final long expirationTime = System.currentTimeMillis() + DNSConstants.KNOWN_ANSWER_TTL;
+        for (DNSRecord answer : in.getAllAnswers()) {
+            conflictDetected |= answer.handleQuery(this, expirationTime);
+        }
+
+        this.ioLock();
+        try {
+
+            if (_plannedAnswer != null) {
+                _plannedAnswer.append(in);
+            } else {
+                DNSIncoming plannedAnswer = in.clone();
+                if (in.isTruncated()) {
+                    _plannedAnswer = plannedAnswer;
+                }
+                this.startResponder(plannedAnswer, port);
+            }
+
+        } finally {
+            this.ioUnlock();
+        }
+
+        final long now = System.currentTimeMillis();
+        for (DNSRecord answer : in.getAnswers()) {
+            this.handleRecord(answer, now);
+        }
+
+        if (conflictDetected) {
+            this.startProber();
+        }
+    }
+
+    public void respondToQuery(DNSIncoming in) {
+        this.ioLock();
+        try {
+            if (_plannedAnswer == in) {
+                _plannedAnswer = null;
+            }
+        } finally {
+            this.ioUnlock();
+        }
+    }
+
+    /**
+     * Add an answer to a question. Deal with the case when the outgoing packet overflows
+     *
+     * @param in
+     * @param addr
+     * @param port
+     * @param out
+     * @param rec
+     * @return outgoing answer
+     * @exception IOException
+     */
+    public DNSOutgoing addAnswer(DNSIncoming in, InetAddress addr, int port, DNSOutgoing out, DNSRecord rec) throws IOException {
+        DNSOutgoing newOut = out;
+        if (newOut == null) {
+            newOut = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA, false, in.getSenderUDPPayload());
+        }
+        try {
+            newOut.addAnswer(in, rec);
+        } catch (final IOException e) {
+            newOut.setFlags(newOut.getFlags() | DNSConstants.FLAGS_TC);
+            newOut.setId(in.getId());
+            send(newOut);
+
+            newOut = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA, false, in.getSenderUDPPayload());
+            newOut.addAnswer(in, rec);
+        }
+        return newOut;
+    }
+
+    /**
+     * Send an outgoing multicast DNS message.
+     *
+     * @param out
+     * @exception IOException
+     */
+    public void send(DNSOutgoing out) throws IOException {
+        if (!out.isEmpty()) {
+            byte[] message = out.data();
+            final DatagramPacket packet = new DatagramPacket(message, message.length, _group, DNSConstants.MDNS_PORT);
+
+            if (logger.isLoggable(Level.FINEST)) {
+                try {
+                    final DNSIncoming msg = new DNSIncoming(packet);
+                    if (logger.isLoggable(Level.FINEST)) {
+                        logger.finest("send(" + this.getName() + ") JmDNS out:" + msg.print(true));
+                    }
+                } catch (final IOException e) {
+                    logger.throwing(getClass().toString(), "send(" + this.getName() + ") - JmDNS can not parse what it sends!!!", e);
+                }
+            }
+            final MulticastSocket ms = _socket;
+            if (ms != null && !ms.isClosed()) {
+                ms.send(packet);
+            }
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSTaskStarter#purgeTimer()
+     */
+    @Override
+    public void purgeTimer() {
+        DNSTaskStarter.Factory.getInstance().getStarter(this.getDns()).purgeTimer();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSTaskStarter#purgeStateTimer()
+     */
+    @Override
+    public void purgeStateTimer() {
+        DNSTaskStarter.Factory.getInstance().getStarter(this.getDns()).purgeStateTimer();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSTaskStarter#cancelTimer()
+     */
+    @Override
+    public void cancelTimer() {
+        DNSTaskStarter.Factory.getInstance().getStarter(this.getDns()).cancelTimer();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSTaskStarter#cancelStateTimer()
+     */
+    @Override
+    public void cancelStateTimer() {
+        DNSTaskStarter.Factory.getInstance().getStarter(this.getDns()).cancelStateTimer();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSTaskStarter#startProber()
+     */
+    @Override
+    public void startProber() {
+        DNSTaskStarter.Factory.getInstance().getStarter(this.getDns()).startProber();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSTaskStarter#startAnnouncer()
+     */
+    @Override
+    public void startAnnouncer() {
+        DNSTaskStarter.Factory.getInstance().getStarter(this.getDns()).startAnnouncer();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSTaskStarter#startRenewer()
+     */
+    @Override
+    public void startRenewer() {
+        DNSTaskStarter.Factory.getInstance().getStarter(this.getDns()).startRenewer();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSTaskStarter#startCanceler()
+     */
+    @Override
+    public void startCanceler() {
+        DNSTaskStarter.Factory.getInstance().getStarter(this.getDns()).startCanceler();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSTaskStarter#startReaper()
+     */
+    @Override
+    public void startReaper() {
+        DNSTaskStarter.Factory.getInstance().getStarter(this.getDns()).startReaper();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSTaskStarter#startServiceInfoResolver(javax.jmdns.impl.ServiceInfoImpl)
+     */
+    @Override
+    public void startServiceInfoResolver(ServiceInfoImpl info) {
+        DNSTaskStarter.Factory.getInstance().getStarter(this.getDns()).startServiceInfoResolver(info);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSTaskStarter#startTypeResolver()
+     */
+    @Override
+    public void startTypeResolver() {
+        DNSTaskStarter.Factory.getInstance().getStarter(this.getDns()).startTypeResolver();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSTaskStarter#startServiceResolver(java.lang.String)
+     */
+    @Override
+    public void startServiceResolver(String type) {
+        DNSTaskStarter.Factory.getInstance().getStarter(this.getDns()).startServiceResolver(type);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.DNSTaskStarter#startResponder(javax.jmdns.impl.DNSIncoming, int)
+     */
+    @Override
+    public void startResponder(DNSIncoming in, int port) {
+        DNSTaskStarter.Factory.getInstance().getStarter(this.getDns()).startResponder(in, port);
+    }
+
+    // REMIND: Why is this not an anonymous inner class?
+    /**
+     * Shutdown operations.
+     */
+    protected class Shutdown implements Runnable {
+        /** {@inheritDoc} */
+        @Override
+        public void run() {
+            try {
+                _shutdown = null;
+                close();
+            } catch (Throwable exception) {
+                System.err.println("Error while shuting down. " + exception);
+            }
+        }
+    }
+
+    private final Object _recoverLock = new Object();
+
+    /**
+     * Recover jmdns when there is an error.
+     */
+    public void recover() {
+        logger.finer(this.getName() + "recover()");
+        // We have an IO error so lets try to recover if anything happens lets close it.
+        // This should cover the case of the IP address changing under our feet
+        if (this.isClosing() || this.isClosed() || this.isCanceling() || this.isCanceled()) {
+            return;
+        }
+
+        // We need some definite lock here as we may have multiple timer running in the same thread that will not be stopped by the reentrant lock
+        // in the state object. This is only a problem in this case as we are going to execute in seperate thread so that the timer can clear.
+        synchronized (_recoverLock) {
+            // Stop JmDNS
+            // This protects against recursive calls
+            if (this.cancelState()) {
+                logger.finer(this.getName() + "recover() thread " + Thread.currentThread().getName());
+                Thread recover = new Thread(this.getName() + ".recover()") {
+                    /**
+                     * {@inheritDoc}
+                     */
+                    @Override
+                    public void run() {
+                        __recover();
+                    }
+                };
+                recover.start();
+            }
+        }
+    }
+
+    void __recover() {
+        // Synchronize only if we are not already in process to prevent dead locks
+        //
+        if (logger.isLoggable(Level.FINER)) {
+            logger.finer(this.getName() + "recover() Cleanning up");
+        }
+
+        logger.warning("RECOVERING");
+        // Purge the timer
+        this.purgeTimer();
+
+        // We need to keep a copy for reregistration
+        final Collection<ServiceInfo> oldServiceInfos = new ArrayList<ServiceInfo>(getServices().values());
+
+        // Cancel all services
+        this.unregisterAllServices();
+        this.disposeServiceCollectors();
+
+        this.waitForCanceled(DNSConstants.CLOSE_TIMEOUT);
+
+        // Purge the canceler timer
+        this.purgeStateTimer();
+
+        //
+        // close multicast socket
+        this.closeMulticastSocket();
+
+        //
+        this.getCache().clear();
+        if (logger.isLoggable(Level.FINER)) {
+            logger.finer(this.getName() + "recover() All is clean");
+        }
+
+        if (this.isCanceled()) {
+            //
+            // All is clear now start the services
+            //
+            for (ServiceInfo info : oldServiceInfos) {
+                ((ServiceInfoImpl) info).recoverState();
+            }
+            this.recoverState();
+
+            try {
+                this.openMulticastSocket(this.getLocalHost());
+                this.start(oldServiceInfos);
+            } catch (final Exception exception) {
+                logger.log(Level.WARNING, this.getName() + "recover() Start services exception ", exception);
+            }
+            logger.log(Level.WARNING, this.getName() + "recover() We are back!");
+        } else {
+            // We have a problem. We could not clear the state.
+            logger.log(Level.WARNING, this.getName() + "recover() Could not recover we are Down!");
+            if (this.getDelegate() != null) {
+                this.getDelegate().cannotRecoverFromIOError(this.getDns(), oldServiceInfos);
+            }
+        }
+
+    }
+
+    public void cleanCache() {
+        long now = System.currentTimeMillis();
+        for (DNSEntry entry : this.getCache().allValues()) {
+            try {
+                DNSRecord record = (DNSRecord) entry;
+                if (record.isExpired(now)) {
+                    this.updateRecord(now, record, Operation.Remove);
+                    this.getCache().removeDNSEntry(record);
+                } else if (record.isStale(now)) {
+                    // we should query for the record we care about i.e. those in the service collectors
+                    this.renewServiceCollector(record);
+                }
+            } catch (Exception exception) {
+                logger.log(Level.SEVERE, this.getName() + ".Error while reaping records: " + entry, exception);
+                logger.severe(this.toString());
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void close() {
+        if (this.isClosing()) {
+            return;
+        }
+
+        if (logger.isLoggable(Level.FINER)) {
+            logger.finer("Cancelling JmDNS: " + this);
+        }
+        // Stop JmDNS
+        // This protects against recursive calls
+        if (this.closeState()) {
+            // We got the tie break now clean up
+
+            // Stop the timer
+            logger.finer("Canceling the timer");
+            this.cancelTimer();
+
+            // Cancel all services
+            this.unregisterAllServices();
+            this.disposeServiceCollectors();
+
+            if (logger.isLoggable(Level.FINER)) {
+                logger.finer("Wait for JmDNS cancel: " + this);
+            }
+            this.waitForCanceled(DNSConstants.CLOSE_TIMEOUT);
+
+            // Stop the canceler timer
+            logger.finer("Canceling the state timer");
+            this.cancelStateTimer();
+
+            // Stop the executor
+            _executor.shutdown();
+
+            // close socket
+            this.closeMulticastSocket();
+
+            // remove the shutdown hook
+            if (_shutdown != null) {
+                Runtime.getRuntime().removeShutdownHook(_shutdown);
+            }
+
+            if (logger.isLoggable(Level.FINER)) {
+                logger.finer("JmDNS closed.");
+            }
+        }
+        advanceState(null);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    @Deprecated
+    public void printServices() {
+        System.err.println(toString());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        final StringBuilder aLog = new StringBuilder(2048);
+        aLog.append("\t---- Local Host -----");
+        aLog.append("\n\t");
+        aLog.append(_localHost);
+        aLog.append("\n\t---- Services -----");
+        for (String key : _services.keySet()) {
+            aLog.append("\n\t\tService: ");
+            aLog.append(key);
+            aLog.append(": ");
+            aLog.append(_services.get(key));
+        }
+        aLog.append("\n");
+        aLog.append("\t---- Types ----");
+        for (String key : _serviceTypes.keySet()) {
+            ServiceTypeEntry subtypes = _serviceTypes.get(key);
+            aLog.append("\n\t\tType: ");
+            aLog.append(subtypes.getType());
+            aLog.append(": ");
+            aLog.append(subtypes.isEmpty() ? "no subtypes" : subtypes);
+        }
+        aLog.append("\n");
+        aLog.append(_cache.toString());
+        aLog.append("\n");
+        aLog.append("\t---- Service Collectors ----");
+        for (String key : _serviceCollectors.keySet()) {
+            aLog.append("\n\t\tService Collector: ");
+            aLog.append(key);
+            aLog.append(": ");
+            aLog.append(_serviceCollectors.get(key));
+        }
+        aLog.append("\n");
+        aLog.append("\t---- Service Listeners ----");
+        for (String key : _serviceListeners.keySet()) {
+            aLog.append("\n\t\tService Listener: ");
+            aLog.append(key);
+            aLog.append(": ");
+            aLog.append(_serviceListeners.get(key));
+        }
+        return aLog.toString();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ServiceInfo[] list(String type) {
+        return this.list(type, DNSConstants.SERVICE_INFO_TIMEOUT);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ServiceInfo[] list(String type, long timeout) {
+        this.cleanCache();
+        // Implementation note: The first time a list for a given type is
+        // requested, a ServiceCollector is created which collects service
+        // infos. This greatly speeds up the performance of subsequent calls
+        // to this method. The caveats are, that 1) the first call to this
+        // method for a given type is slow, and 2) we spawn a ServiceCollector
+        // instance for each service type which increases network traffic a
+        // little.
+
+        String loType = type.toLowerCase();
+
+        boolean newCollectorCreated = false;
+        if (this.isCanceling() || this.isCanceled()) {
+            return new ServiceInfo[0];
+        }
+
+        ServiceCollector collector = _serviceCollectors.get(loType);
+        if (collector == null) {
+            newCollectorCreated = _serviceCollectors.putIfAbsent(loType, new ServiceCollector(type)) == null;
+            collector = _serviceCollectors.get(loType);
+            if (newCollectorCreated) {
+                this.addServiceListener(type, collector, ListenerStatus.SYNCHONEOUS);
+            }
+        }
+        if (logger.isLoggable(Level.FINER)) {
+            logger.finer(this.getName() + ".collector: " + collector);
+        }
+        // At this stage the collector should never be null but it keeps findbugs happy.
+        return (collector != null ? collector.list(timeout) : new ServiceInfo[0]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Map<String, ServiceInfo[]> listBySubtype(String type) {
+        return this.listBySubtype(type, DNSConstants.SERVICE_INFO_TIMEOUT);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Map<String, ServiceInfo[]> listBySubtype(String type, long timeout) {
+        Map<String, List<ServiceInfo>> map = new HashMap<String, List<ServiceInfo>>(5);
+        for (ServiceInfo info : this.list(type, timeout)) {
+            String subtype = info.getSubtype().toLowerCase();
+            if (!map.containsKey(subtype)) {
+                map.put(subtype, new ArrayList<ServiceInfo>(10));
+            }
+            map.get(subtype).add(info);
+        }
+
+        Map<String, ServiceInfo[]> result = new HashMap<String, ServiceInfo[]>(map.size());
+        for (String subtype : map.keySet()) {
+            List<ServiceInfo> infoForSubType = map.get(subtype);
+            result.put(subtype, infoForSubType.toArray(new ServiceInfo[infoForSubType.size()]));
+        }
+
+        return result;
+    }
+
+    /**
+     * This method disposes all ServiceCollector instances which have been created by calls to method <code>list(type)</code>.
+     *
+     * @see #list
+     */
+    private void disposeServiceCollectors() {
+        if (logger.isLoggable(Level.FINER)) {
+            logger.finer("disposeServiceCollectors()");
+        }
+        for (String type : _serviceCollectors.keySet()) {
+            ServiceCollector collector = _serviceCollectors.get(type);
+            if (collector != null) {
+                this.removeServiceListener(type, collector);
+                _serviceCollectors.remove(type, collector);
+            }
+        }
+    }
+
+    /**
+     * Instances of ServiceCollector are used internally to speed up the performance of method <code>list(type)</code>.
+     *
+     * @see #list
+     */
+    private static class ServiceCollector implements ServiceListener {
+        // private static Logger logger = Logger.getLogger(ServiceCollector.class.getName());
+
+        /**
+         * A set of collected service instance names.
+         */
+        private final ConcurrentMap<String, ServiceInfo>  _infos;
+
+        /**
+         * A set of collected service event waiting to be resolved.
+         */
+        private final ConcurrentMap<String, ServiceEvent> _events;
+
+        /**
+         * This is the type we are listening for (only used for debugging).
+         */
+        private final String                              _type;
+
+        /**
+         * This is used to force a wait on the first invocation of list.
+         */
+        private volatile boolean                          _needToWaitForInfos;
+
+        public ServiceCollector(String type) {
+            super();
+            _infos = new ConcurrentHashMap<String, ServiceInfo>();
+            _events = new ConcurrentHashMap<String, ServiceEvent>();
+            _type = type;
+            _needToWaitForInfos = true;
+        }
+
+        /**
+         * A service has been added.
+         *
+         * @param event
+         *            service event
+         */
+        @Override
+        public void serviceAdded(ServiceEvent event) {
+            synchronized (this) {
+                ServiceInfo info = event.getInfo();
+                if ((info != null) && (info.hasData())) {
+                    _infos.put(event.getName(), info);
+                } else {
+                    String subtype = (info != null ? info.getSubtype() : "");
+                    info = ((JmDNSImpl) event.getDNS()).resolveServiceInfo(event.getType(), event.getName(), subtype, true);
+                    if (info != null) {
+                        _infos.put(event.getName(), info);
+                    } else {
+                        _events.put(event.getName(), event);
+                    }
+                }
+            }
+        }
+
+        /**
+         * A service has been removed.
+         *
+         * @param event
+         *            service event
+         */
+        @Override
+        public void serviceRemoved(ServiceEvent event) {
+            synchronized (this) {
+                _infos.remove(event.getName());
+                _events.remove(event.getName());
+            }
+        }
+
+        /**
+         * A service has been resolved. Its details are now available in the ServiceInfo record.
+         *
+         * @param event
+         *            service event
+         */
+        @Override
+        public void serviceResolved(ServiceEvent event) {
+            synchronized (this) {
+                _infos.put(event.getName(), event.getInfo());
+                _events.remove(event.getName());
+            }
+        }
+
+        /**
+         * Returns an array of all service infos which have been collected by this ServiceCollector.
+         *
+         * @param timeout
+         *            timeout if the info list is empty.
+         * @return Service Info array
+         */
+        public ServiceInfo[] list(long timeout) {
+            if (_infos.isEmpty() || !_events.isEmpty() || _needToWaitForInfos) {
+                long loops = (timeout / 200L);
+                if (loops < 1) {
+                    loops = 1;
+                }
+                for (int i = 0; i < loops; i++) {
+                    try {
+                        Thread.sleep(200);
+                    } catch (final InterruptedException e) {
+                        /* Stub */
+                    }
+                    if (_events.isEmpty() && !_infos.isEmpty() && !_needToWaitForInfos) {
+                        break;
+                    }
+                }
+            }
+            _needToWaitForInfos = false;
+            return _infos.values().toArray(new ServiceInfo[_infos.size()]);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public String toString() {
+            final StringBuffer aLog = new StringBuffer();
+            aLog.append("\n\tType: ");
+            aLog.append(_type);
+            if (_infos.isEmpty()) {
+                aLog.append("\n\tNo services collected.");
+            } else {
+                aLog.append("\n\tServices");
+                for (String key : _infos.keySet()) {
+                    aLog.append("\n\t\tService: ");
+                    aLog.append(key);
+                    aLog.append(": ");
+                    aLog.append(_infos.get(key));
+                }
+            }
+            if (_events.isEmpty()) {
+                aLog.append("\n\tNo event queued.");
+            } else {
+                aLog.append("\n\tEvents");
+                for (String key : _events.keySet()) {
+                    aLog.append("\n\t\tEvent: ");
+                    aLog.append(key);
+                    aLog.append(": ");
+                    aLog.append(_events.get(key));
+                }
+            }
+            return aLog.toString();
+        }
+    }
+
+    static String toUnqualifiedName(String type, String qualifiedName) {
+        String loType = type.toLowerCase();
+        String loQualifiedName = qualifiedName.toLowerCase();
+        if (loQualifiedName.endsWith(loType) && !(loQualifiedName.equals(loType))) {
+            return qualifiedName.substring(0, qualifiedName.length() - type.length() - 1);
+        }
+        return qualifiedName;
+    }
+
+    public Map<String, ServiceInfo> getServices() {
+        return _services;
+    }
+
+    public void setLastThrottleIncrement(long lastThrottleIncrement) {
+        this._lastThrottleIncrement = lastThrottleIncrement;
+    }
+
+    public long getLastThrottleIncrement() {
+        return _lastThrottleIncrement;
+    }
+
+    public void setThrottle(int throttle) {
+        this._throttle = throttle;
+    }
+
+    public int getThrottle() {
+        return _throttle;
+    }
+
+    public static Random getRandom() {
+        return _random;
+    }
+
+    public void ioLock() {
+        _ioLock.lock();
+    }
+
+    public void ioUnlock() {
+        _ioLock.unlock();
+    }
+
+    public void setPlannedAnswer(DNSIncoming plannedAnswer) {
+        this._plannedAnswer = plannedAnswer;
+    }
+
+    public DNSIncoming getPlannedAnswer() {
+        return _plannedAnswer;
+    }
+
+    void setLocalHost(HostInfo localHost) {
+        this._localHost = localHost;
+    }
+
+    public Map<String, ServiceTypeEntry> getServiceTypes() {
+        return _serviceTypes;
+    }
+
+    public MulticastSocket getSocket() {
+        return _socket;
+    }
+
+    public InetAddress getGroup() {
+        return _group;
+    }
+
+    @Override
+    public Delegate getDelegate() {
+        return this._delegate;
+    }
+
+    @Override
+    public Delegate setDelegate(Delegate delegate) {
+        Delegate previous = this._delegate;
+        this._delegate = delegate;
+        return previous;
+    }
+
+}
diff --git a/src/javax/jmdns/impl/JmmDNSImpl.java b/src/javax/jmdns/impl/JmmDNSImpl.java
new file mode 100644
index 0000000..3eb78f1
--- /dev/null
+++ b/src/javax/jmdns/impl/JmmDNSImpl.java
@@ -0,0 +1,599 @@
+/**
+ *
+ */
+package javax.jmdns.impl;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.jmdns.JmDNS;
+import javax.jmdns.JmmDNS;
+import javax.jmdns.NetworkTopologyDiscovery;
+import javax.jmdns.NetworkTopologyEvent;
+import javax.jmdns.NetworkTopologyListener;
+import javax.jmdns.ServiceInfo;
+import javax.jmdns.ServiceListener;
+import javax.jmdns.ServiceTypeListener;
+import javax.jmdns.impl.constants.DNSConstants;
+
+/**
+ * This class enable multihomming mDNS. It will open a mDNS per IP address of the machine.
+ *
+ * @author C&eacute;drik Lime, Pierre Frisch
+ */
+public class JmmDNSImpl implements JmmDNS, NetworkTopologyListener, ServiceInfoImpl.Delegate {
+    private static Logger                            logger = Logger.getLogger(JmmDNSImpl.class.getName());
+
+    private final Set<NetworkTopologyListener>       _networkListeners;
+
+    /**
+     * Every JmDNS created.
+     */
+    private final ConcurrentMap<InetAddress, JmDNS>  _knownMDNS;
+
+    /**
+     * This enable the service info text update.
+     */
+    private final ConcurrentMap<String, ServiceInfo> _services;
+
+    private final ExecutorService                    _ListenerExecutor;
+
+    private final ExecutorService                    _jmDNSExecutor;
+
+    private final Timer                              _timer;
+
+    /**
+     *
+     */
+    public JmmDNSImpl() {
+        super();
+        _networkListeners = Collections.synchronizedSet(new HashSet<NetworkTopologyListener>());
+        _knownMDNS = new ConcurrentHashMap<InetAddress, JmDNS>();
+        _services = new ConcurrentHashMap<String, ServiceInfo>(20);
+        _ListenerExecutor = Executors.newSingleThreadExecutor();
+        _jmDNSExecutor = Executors.newCachedThreadPool();
+        _timer = new Timer("Multihommed mDNS.Timer", true);
+        (new NetworkChecker(this, NetworkTopologyDiscovery.Factory.getInstance())).start(_timer);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see java.io.Closeable#close()
+     */
+    @Override
+    public void close() throws IOException {
+        if (logger.isLoggable(Level.FINER)) {
+            logger.finer("Cancelling JmmDNS: " + this);
+        }
+        _timer.cancel();
+        _ListenerExecutor.shutdown();
+        // We need to cancel all the DNS
+        ExecutorService executor = Executors.newCachedThreadPool();
+        for (final JmDNS mDNS : _knownMDNS.values()) {
+            executor.submit(new Runnable() {
+                /**
+                 * {@inheritDoc}
+                 */
+                @Override
+                public void run() {
+                    try {
+                        mDNS.close();
+                    } catch (IOException exception) {
+                        // JmDNS never throws this is only because of the closeable interface
+                    }
+                }
+            });
+        }
+        executor.shutdown();
+        try {
+            executor.awaitTermination(DNSConstants.CLOSE_TIMEOUT, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException exception) {
+            logger.log(Level.WARNING, "Exception ", exception);
+        }
+        _knownMDNS.clear();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#getNames()
+     */
+    @Override
+    public String[] getNames() {
+        Set<String> result = new HashSet<String>();
+        for (JmDNS mDNS : _knownMDNS.values()) {
+            result.add(mDNS.getName());
+        }
+        return result.toArray(new String[result.size()]);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#getHostNames()
+     */
+    @Override
+    public String[] getHostNames() {
+        Set<String> result = new HashSet<String>();
+        for (JmDNS mDNS : _knownMDNS.values()) {
+            result.add(mDNS.getHostName());
+        }
+        return result.toArray(new String[result.size()]);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#getInetAddresses()
+     */
+    @Override
+    public InetAddress[] getInetAddresses() throws IOException {
+        Set<InetAddress> result = new HashSet<InetAddress>();
+        for (JmDNS mDNS : _knownMDNS.values()) {
+            result.add(mDNS.getInetAddress());
+        }
+        return result.toArray(new InetAddress[result.size()]);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#getInterfaces()
+     */
+    @Override
+    @Deprecated
+    public InetAddress[] getInterfaces() throws IOException {
+        Set<InetAddress> result = new HashSet<InetAddress>();
+        for (JmDNS mDNS : _knownMDNS.values()) {
+            result.add(mDNS.getInterface());
+        }
+        return result.toArray(new InetAddress[result.size()]);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#getServiceInfos(java.lang.String, java.lang.String)
+     */
+    @Override
+    public ServiceInfo[] getServiceInfos(String type, String name) {
+        return this.getServiceInfos(type, name, false, DNSConstants.SERVICE_INFO_TIMEOUT);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#getServiceInfos(java.lang.String, java.lang.String, long)
+     */
+    @Override
+    public ServiceInfo[] getServiceInfos(String type, String name, long timeout) {
+        return this.getServiceInfos(type, name, false, timeout);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#getServiceInfos(java.lang.String, java.lang.String, boolean)
+     */
+    @Override
+    public ServiceInfo[] getServiceInfos(String type, String name, boolean persistent) {
+        return this.getServiceInfos(type, name, persistent, DNSConstants.SERVICE_INFO_TIMEOUT);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#getServiceInfos(java.lang.String, java.lang.String, boolean, long)
+     */
+    @Override
+    public ServiceInfo[] getServiceInfos(final String type, final String name, final boolean persistent, final long timeout) {
+        // We need to run this in parallel to respect the timeout.
+        final Set<ServiceInfo> result = Collections.synchronizedSet(new HashSet<ServiceInfo>(_knownMDNS.size()));
+        ExecutorService executor = Executors.newCachedThreadPool();
+        for (final JmDNS mDNS : _knownMDNS.values()) {
+            executor.submit(new Runnable() {
+                /**
+                 * {@inheritDoc}
+                 */
+                @Override
+                public void run() {
+                    result.add(mDNS.getServiceInfo(type, name, persistent, timeout));
+                }
+            });
+        }
+        executor.shutdown();
+        try {
+            executor.awaitTermination(timeout, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException exception) {
+            logger.log(Level.WARNING, "Exception ", exception);
+        }
+        return result.toArray(new ServiceInfo[result.size()]);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#requestServiceInfo(java.lang.String, java.lang.String)
+     */
+    @Override
+    public void requestServiceInfo(String type, String name) {
+        this.requestServiceInfo(type, name, false, DNSConstants.SERVICE_INFO_TIMEOUT);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#requestServiceInfo(java.lang.String, java.lang.String, boolean)
+     */
+    @Override
+    public void requestServiceInfo(String type, String name, boolean persistent) {
+        this.requestServiceInfo(type, name, persistent, DNSConstants.SERVICE_INFO_TIMEOUT);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#requestServiceInfo(java.lang.String, java.lang.String, long)
+     */
+    @Override
+    public void requestServiceInfo(String type, String name, long timeout) {
+        this.requestServiceInfo(type, name, false, timeout);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#requestServiceInfo(java.lang.String, java.lang.String, boolean, long)
+     */
+    @Override
+    public void requestServiceInfo(final String type, final String name, final boolean persistent, final long timeout) {
+        // We need to run this in parallel to respect the timeout.
+        for (final JmDNS mDNS : _knownMDNS.values()) {
+            _jmDNSExecutor.submit(new Runnable() {
+                /**
+                 * {@inheritDoc}
+                 */
+                @Override
+                public void run() {
+                    mDNS.requestServiceInfo(type, name, persistent, timeout);
+                }
+            });
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#addServiceTypeListener(javax.jmdns.ServiceTypeListener)
+     */
+    @Override
+    public void addServiceTypeListener(ServiceTypeListener listener) throws IOException {
+        for (JmDNS mDNS : _knownMDNS.values()) {
+            mDNS.addServiceTypeListener(listener);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#removeServiceTypeListener(javax.jmdns.ServiceTypeListener)
+     */
+    @Override
+    public void removeServiceTypeListener(ServiceTypeListener listener) {
+        for (JmDNS mDNS : _knownMDNS.values()) {
+            mDNS.removeServiceTypeListener(listener);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#addServiceListener(java.lang.String, javax.jmdns.ServiceListener)
+     */
+    @Override
+    public void addServiceListener(String type, ServiceListener listener) {
+        for (JmDNS mDNS : _knownMDNS.values()) {
+            mDNS.addServiceListener(type, listener);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#removeServiceListener(java.lang.String, javax.jmdns.ServiceListener)
+     */
+    @Override
+    public void removeServiceListener(String type, ServiceListener listener) {
+        for (JmDNS mDNS : _knownMDNS.values()) {
+            mDNS.removeServiceListener(type, listener);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.ServiceInfoImpl.Delegate#textValueUpdated(javax.jmdns.ServiceInfo, byte[])
+     */
+    @Override
+    public void textValueUpdated(ServiceInfo target, byte[] value) {
+        synchronized (_services) {
+            for (JmDNS mDNS : _knownMDNS.values()) {
+                ServiceInfo info = ((JmDNSImpl) mDNS).getServices().get(target.getQualifiedName());
+                if (info != null) {
+                    info.setText(value);
+                } else {
+                    logger.warning("We have a mDNS that does not know about the service info being updated.");
+                }
+            }
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#registerService(javax.jmdns.ServiceInfo)
+     */
+    @Override
+    public void registerService(ServiceInfo info) throws IOException {
+        // This is really complex. We need to clone the service info for each DNS but then we loose the ability to update it.
+        synchronized (_services) {
+            for (JmDNS mDNS : _knownMDNS.values()) {
+                mDNS.registerService(info.clone());
+            }
+            ((ServiceInfoImpl) info).setDelegate(this);
+            _services.put(info.getQualifiedName(), info);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#unregisterService(javax.jmdns.ServiceInfo)
+     */
+    @Override
+    public void unregisterService(ServiceInfo info) {
+        synchronized (_services) {
+            for (JmDNS mDNS : _knownMDNS.values()) {
+                mDNS.unregisterService(info);
+            }
+            ((ServiceInfoImpl) info).setDelegate(null);
+            _services.remove(info.getQualifiedName());
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#unregisterAllServices()
+     */
+    @Override
+    public void unregisterAllServices() {
+        synchronized (_services) {
+            for (JmDNS mDNS : _knownMDNS.values()) {
+                mDNS.unregisterAllServices();
+            }
+            _services.clear();
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#registerServiceType(java.lang.String)
+     */
+    @Override
+    public void registerServiceType(String type) {
+        for (JmDNS mDNS : _knownMDNS.values()) {
+            mDNS.registerServiceType(type);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#list(java.lang.String)
+     */
+    @Override
+    public ServiceInfo[] list(String type) {
+        return this.list(type, DNSConstants.SERVICE_INFO_TIMEOUT);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#list(java.lang.String, long)
+     */
+    @Override
+    public ServiceInfo[] list(final String type, final long timeout) {
+        // We need to run this in parallel to respect the timeout.
+        final Set<ServiceInfo> result = Collections.synchronizedSet(new HashSet<ServiceInfo>(_knownMDNS.size() * 5));
+        ExecutorService executor = Executors.newCachedThreadPool();
+        for (final JmDNS mDNS : _knownMDNS.values()) {
+            executor.submit(new Runnable() {
+                /**
+                 * {@inheritDoc}
+                 */
+                @Override
+                public void run() {
+                    result.addAll(Arrays.asList(mDNS.list(type, timeout)));
+                }
+            });
+        }
+        executor.shutdown();
+        try {
+            executor.awaitTermination(timeout, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException exception) {
+            logger.log(Level.WARNING, "Exception ", exception);
+        }
+        return result.toArray(new ServiceInfo[result.size()]);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#listBySubtype(java.lang.String)
+     */
+    @Override
+    public Map<String, ServiceInfo[]> listBySubtype(String type) {
+        return this.listBySubtype(type, DNSConstants.SERVICE_INFO_TIMEOUT);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#listBySubtype(java.lang.String, long)
+     */
+    @Override
+    public Map<String, ServiceInfo[]> listBySubtype(final String type, final long timeout) {
+        Map<String, List<ServiceInfo>> map = new HashMap<String, List<ServiceInfo>>(5);
+        for (ServiceInfo info : this.list(type, timeout)) {
+            String subtype = info.getSubtype();
+            if (!map.containsKey(subtype)) {
+                map.put(subtype, new ArrayList<ServiceInfo>(10));
+            }
+            map.get(subtype).add(info);
+        }
+
+        Map<String, ServiceInfo[]> result = new HashMap<String, ServiceInfo[]>(map.size());
+        for (String subtype : map.keySet()) {
+            List<ServiceInfo> infoForSubType = map.get(subtype);
+            result.put(subtype, infoForSubType.toArray(new ServiceInfo[infoForSubType.size()]));
+        }
+
+        return result;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#addNetworkTopologyListener(javax.jmdns.NetworkTopologyListener)
+     */
+    @Override
+    public void addNetworkTopologyListener(NetworkTopologyListener listener) {
+        _networkListeners.add(listener);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#removeNetworkTopologyListener(javax.jmdns.NetworkTopologyListener)
+     */
+    @Override
+    public void removeNetworkTopologyListener(NetworkTopologyListener listener) {
+        _networkListeners.remove(listener);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS#networkListeners()
+     */
+    @Override
+    public NetworkTopologyListener[] networkListeners() {
+        return _networkListeners.toArray(new NetworkTopologyListener[_networkListeners.size()]);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.NetworkTopologyListener#inetAddressAdded(javax.jmdns.NetworkTopologyEvent)
+     */
+    @Override
+    public void inetAddressAdded(NetworkTopologyEvent event) {
+        InetAddress address = event.getInetAddress();
+        try {
+            synchronized (this) {
+                if (!_knownMDNS.containsKey(address)) {
+                    _knownMDNS.put(address, JmDNS.create(address));
+                    final NetworkTopologyEvent jmdnsEvent = new NetworkTopologyEventImpl(_knownMDNS.get(address), address);
+                    for (final NetworkTopologyListener listener : this.networkListeners()) {
+                        _ListenerExecutor.submit(new Runnable() {
+                            /**
+                             * {@inheritDoc}
+                             */
+                            @Override
+                            public void run() {
+                                listener.inetAddressAdded(jmdnsEvent);
+                            }
+                        });
+                    }
+                }
+            }
+        } catch (Exception e) {
+            logger.warning("Unexpected unhandled exception: " + e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.NetworkTopologyListener#inetAddressRemoved(javax.jmdns.NetworkTopologyEvent)
+     */
+    @Override
+    public void inetAddressRemoved(NetworkTopologyEvent event) {
+        InetAddress address = event.getInetAddress();
+        try {
+            synchronized (this) {
+                if (_knownMDNS.containsKey(address)) {
+                    JmDNS mDNS = _knownMDNS.remove(address);
+                    mDNS.close();
+                    final NetworkTopologyEvent jmdnsEvent = new NetworkTopologyEventImpl(mDNS, address);
+                    for (final NetworkTopologyListener listener : this.networkListeners()) {
+                        _ListenerExecutor.submit(new Runnable() {
+                            /**
+                             * {@inheritDoc}
+                             */
+                            @Override
+                            public void run() {
+                                listener.inetAddressRemoved(jmdnsEvent);
+                            }
+                        });
+                    }
+                }
+            }
+        } catch (Exception e) {
+            logger.warning("Unexpected unhandled exception: " + e);
+        }
+    }
+
+    /**
+     * Checks the network state.<br/>
+     * If the network change, this class will reconfigure the list of DNS do adapt to the new configuration.
+     */
+    static class NetworkChecker extends TimerTask {
+        private static Logger                  logger1 = Logger.getLogger(NetworkChecker.class.getName());
+
+        private final NetworkTopologyListener  _mmDNS;
+
+        private final NetworkTopologyDiscovery _topology;
+
+        private Set<InetAddress>               _knownAddresses;
+
+        public NetworkChecker(NetworkTopologyListener mmDNS, NetworkTopologyDiscovery topology) {
+            super();
+            this._mmDNS = mmDNS;
+            this._topology = topology;
+            _knownAddresses = Collections.synchronizedSet(new HashSet<InetAddress>());
+        }
+
+        public void start(Timer timer) {
+            timer.schedule(this, 0, DNSConstants.NETWORK_CHECK_INTERVAL);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void run() {
+            try {
+                InetAddress[] curentAddresses = _topology.getInetAddresses();
+                Set<InetAddress> current = new HashSet<InetAddress>(curentAddresses.length);
+                for (InetAddress address : curentAddresses) {
+                    current.add(address);
+                    if (!_knownAddresses.contains(address)) {
+                        final NetworkTopologyEvent event = new NetworkTopologyEventImpl(_mmDNS, address);
+                        _mmDNS.inetAddressAdded(event);
+                    }
+                }
+                for (InetAddress address : _knownAddresses) {
+                    if (!current.contains(address)) {
+                        final NetworkTopologyEvent event = new NetworkTopologyEventImpl(_mmDNS, address);
+                        _mmDNS.inetAddressRemoved(event);
+                    }
+                }
+                _knownAddresses = current;
+            } catch (Exception e) {
+                logger1.warning("Unexpected unhandled exception: " + e);
+            }
+        }
+
+    }
+
+}
diff --git a/src/javax/jmdns/impl/ListenerStatus.java b/src/javax/jmdns/impl/ListenerStatus.java
new file mode 100644
index 0000000..a33842c
--- /dev/null
+++ b/src/javax/jmdns/impl/ListenerStatus.java
@@ -0,0 +1,286 @@
+/**
+ *
+ */
+package javax.jmdns.impl;
+
+import java.util.EventListener;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.logging.Logger;
+
+import javax.jmdns.JmDNS;
+import javax.jmdns.ServiceEvent;
+import javax.jmdns.ServiceInfo;
+import javax.jmdns.ServiceListener;
+import javax.jmdns.ServiceTypeListener;
+
+/**
+ * This class track the status of listener.<br/>
+ * The main purpose of this class is to collapse consecutive events so that we can guarantee the correct call back sequence.
+ * 
+ * @param <T>
+ *            listener type
+ */
+public class ListenerStatus<T extends EventListener> {
+
+    public static class ServiceListenerStatus extends ListenerStatus<ServiceListener> {
+        private static Logger                            logger = Logger.getLogger(ServiceListenerStatus.class.getName());
+
+        private final ConcurrentMap<String, ServiceInfo> _addedServices;
+
+        /**
+         * @param listener
+         *            listener being tracked.
+         * @param synch
+         *            true if that listener can be called asynchronously
+         */
+        public ServiceListenerStatus(ServiceListener listener, boolean synch) {
+            super(listener, synch);
+            _addedServices = new ConcurrentHashMap<String, ServiceInfo>(32);
+        }
+
+        /**
+         * A service has been added.<br/>
+         * <b>Note:</b>This event is only the service added event. The service info associated with this event does not include resolution information.<br/>
+         * To get the full resolved information you need to listen to {@link #serviceResolved(ServiceEvent)} or call {@link JmDNS#getServiceInfo(String, String, long)}
+         * 
+         * <pre>
+         *  ServiceInfo info = event.getDNS().getServiceInfo(event.getType(), event.getName())
+         * </pre>
+         * <p>
+         * Please note that service resolution may take a few second to resolve.
+         * </p>
+         * 
+         * @param event
+         *            The ServiceEvent providing the name and fully qualified type of the service.
+         */
+        void serviceAdded(ServiceEvent event) {
+            String qualifiedName = event.getName() + "." + event.getType();
+            if (null == _addedServices.putIfAbsent(qualifiedName, event.getInfo().clone())) {
+                this.getListener().serviceAdded(event);
+                ServiceInfo info = event.getInfo();
+                if ((info != null) && (info.hasData())) {
+                    this.getListener().serviceResolved(event);
+                }
+            } else {
+                logger.finer("Service Added called for a service already added: " + event);
+            }
+        }
+
+        /**
+         * A service has been removed.
+         * 
+         * @param event
+         *            The ServiceEvent providing the name and fully qualified type of the service.
+         */
+        void serviceRemoved(ServiceEvent event) {
+            String qualifiedName = event.getName() + "." + event.getType();
+            if (_addedServices.remove(qualifiedName, _addedServices.get(qualifiedName))) {
+                this.getListener().serviceRemoved(event);
+            } else {
+                logger.finer("Service Removed called for a service already removed: " + event);
+            }
+        }
+
+        /**
+         * A service has been resolved. Its details are now available in the ServiceInfo record.<br/>
+         * <b>Note:</b>This call back will never be called if the service does not resolve.<br/>
+         * 
+         * @param event
+         *            The ServiceEvent providing the name, the fully qualified type of the service, and the service info record.
+         */
+        synchronized void serviceResolved(ServiceEvent event) {
+            ServiceInfo info = event.getInfo();
+            if ((info != null) && (info.hasData())) {
+                String qualifiedName = event.getName() + "." + event.getType();
+                ServiceInfo previousServiceInfo = _addedServices.get(qualifiedName);
+                if (!_sameInfo(info, previousServiceInfo)) {
+                    if (null == previousServiceInfo) {
+                        if (null == _addedServices.putIfAbsent(qualifiedName, info.clone())) {
+                            this.getListener().serviceResolved(event);
+                        }
+                    } else {
+                        if (_addedServices.replace(qualifiedName, previousServiceInfo, info.clone())) {
+                            this.getListener().serviceResolved(event);
+                        }
+                    }
+                } else {
+                    logger.finer("Service Resolved called for a service already resolved: " + event);
+                }
+            } else {
+                logger.warning("Service Resolved called for an unresolved event: " + event);
+
+            }
+        }
+
+        private static final boolean _sameInfo(ServiceInfo info, ServiceInfo lastInfo) {
+            if (info == null) return false;
+            if (lastInfo == null) return false;
+            if (!info.equals(lastInfo)) return false;
+            byte[] text = info.getTextBytes();
+            byte[] lastText = lastInfo.getTextBytes();
+            if (text.length != lastText.length) return false;
+            for (int i = 0; i < text.length; i++) {
+                if (text[i] != lastText[i]) return false;
+            }
+            return true;
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see java.lang.Object#toString()
+         */
+        @Override
+        public String toString() {
+            StringBuilder aLog = new StringBuilder(2048);
+            aLog.append("[Status for ");
+            aLog.append(this.getListener().toString());
+            if (_addedServices.isEmpty()) {
+                aLog.append(" no type event ");
+            } else {
+                aLog.append(" (");
+                for (String service : _addedServices.keySet()) {
+                    aLog.append(service + ", ");
+                }
+                aLog.append(") ");
+            }
+            aLog.append("]");
+            return aLog.toString();
+        }
+
+    }
+
+    public static class ServiceTypeListenerStatus extends ListenerStatus<ServiceTypeListener> {
+        private static Logger                       logger = Logger.getLogger(ServiceTypeListenerStatus.class.getName());
+
+        private final ConcurrentMap<String, String> _addedTypes;
+
+        /**
+         * @param listener
+         *            listener being tracked.
+         * @param synch
+         *            true if that listener can be called asynchronously
+         */
+        public ServiceTypeListenerStatus(ServiceTypeListener listener, boolean synch) {
+            super(listener, synch);
+            _addedTypes = new ConcurrentHashMap<String, String>(32);
+        }
+
+        /**
+         * A new service type was discovered.
+         * 
+         * @param event
+         *            The service event providing the fully qualified type of the service.
+         */
+        void serviceTypeAdded(ServiceEvent event) {
+            if (null == _addedTypes.putIfAbsent(event.getType(), event.getType())) {
+                this.getListener().serviceTypeAdded(event);
+            } else {
+                logger.finest("Service Type Added called for a service type already added: " + event);
+            }
+        }
+
+        /**
+         * A new subtype for the service type was discovered.
+         * 
+         * <pre>
+         * &lt;sub&gt;._sub.&lt;app&gt;.&lt;protocol&gt;.&lt;servicedomain&gt;.&lt;parentdomain&gt;.
+         * </pre>
+         * 
+         * @param event
+         *            The service event providing the fully qualified type of the service with subtype.
+         */
+        void subTypeForServiceTypeAdded(ServiceEvent event) {
+            if (null == _addedTypes.putIfAbsent(event.getType(), event.getType())) {
+                this.getListener().subTypeForServiceTypeAdded(event);
+            } else {
+                logger.finest("Service Sub Type Added called for a service sub type already added: " + event);
+            }
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see java.lang.Object#toString()
+         */
+        @Override
+        public String toString() {
+            StringBuilder aLog = new StringBuilder(2048);
+            aLog.append("[Status for ");
+            aLog.append(this.getListener().toString());
+            if (_addedTypes.isEmpty()) {
+                aLog.append(" no type event ");
+            } else {
+                aLog.append(" (");
+                for (String type : _addedTypes.keySet()) {
+                    aLog.append(type + ", ");
+                }
+                aLog.append(") ");
+            }
+            aLog.append("]");
+            return aLog.toString();
+        }
+
+    }
+
+    public final static boolean SYNCHONEOUS  = true;
+    public final static boolean ASYNCHONEOUS = false;
+
+    private final T             _listener;
+
+    private final boolean       _synch;
+
+    /**
+     * @param listener
+     *            listener being tracked.
+     * @param synch
+     *            true if that listener can be called asynchronously
+     */
+    public ListenerStatus(T listener, boolean synch) {
+        super();
+        _listener = listener;
+        _synch = synch;
+    }
+
+    /**
+     * @return the listener
+     */
+    public T getListener() {
+        return _listener;
+    }
+
+    /**
+     * Return <cod>true</code> if the listener must be called synchronously.
+     * 
+     * @return the synch
+     */
+    public boolean isSynchronous() {
+        return _synch;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return this.getListener().hashCode();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        return (obj instanceof ListenerStatus) && this.getListener().equals(((ListenerStatus<?>) obj).getListener());
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "[Status for " + this.getListener().toString() + "]";
+    }
+}
diff --git a/src/javax/jmdns/impl/NameRegister.java b/src/javax/jmdns/impl/NameRegister.java
new file mode 100644
index 0000000..9e68b06
--- /dev/null
+++ b/src/javax/jmdns/impl/NameRegister.java
@@ -0,0 +1,168 @@
+/**
+ *
+ */
+package javax.jmdns.impl;
+
+import java.net.InetAddress;
+
+/**
+ *
+ */
+public interface NameRegister {
+
+    /**
+     *
+     */
+    public enum NameType {
+        /**
+         * This name represents a host name
+         */
+        HOST,
+        /**
+         * This name represents a service name
+         */
+        SERVICE,
+    }
+
+    public static class UniqueNamePerInterface implements NameRegister {
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.NameRegister#register(java.net.InetAddress, java.lang.String, javax.jmdns.impl.NameRegister.NameType)
+         */
+        @Override
+        public void register(InetAddress networkInterface, String name, NameType type) {
+            // TODO Auto-generated method stub
+
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.NameRegister#checkName(java.net.InetAddress, java.lang.String, javax.jmdns.impl.NameRegister.NameType)
+         */
+        @Override
+        public boolean checkName(InetAddress networkInterface, String name, NameType type) {
+            // TODO Auto-generated method stub
+            return false;
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.NameRegister#incrementHostName(java.net.InetAddress, java.lang.String, javax.jmdns.impl.NameRegister.NameType)
+         */
+        @Override
+        public String incrementHostName(InetAddress networkInterface, String name, NameType type) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+    }
+
+    public static class UniqueNameAcrossInterface implements NameRegister {
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.NameRegister#register(java.net.InetAddress, java.lang.String, javax.jmdns.impl.NameRegister.NameType)
+         */
+        @Override
+        public void register(InetAddress networkInterface, String name, NameType type) {
+            // TODO Auto-generated method stub
+
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.NameRegister#checkName(java.net.InetAddress, java.lang.String, javax.jmdns.impl.NameRegister.NameType)
+         */
+        @Override
+        public boolean checkName(InetAddress networkInterface, String name, NameType type) {
+            // TODO Auto-generated method stub
+            return false;
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.jmdns.impl.NameRegister#incrementHostName(java.net.InetAddress, java.lang.String, javax.jmdns.impl.NameRegister.NameType)
+         */
+        @Override
+        public String incrementHostName(InetAddress networkInterface, String name, NameType type) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+    }
+
+    public static class Factory {
+
+        private static volatile NameRegister _register;
+
+        /**
+         * Register a Name register.
+         *
+         * @param register
+         *            new register
+         * @throws IllegalStateException
+         *             the register can only be set once
+         */
+        public static void setRegistry(NameRegister register) throws IllegalStateException {
+            if (_register != null) {
+                throw new IllegalStateException("The register can only be set once.");
+            }
+            if (register != null) {
+                _register = register;
+            }
+        }
+
+        /**
+         * Returns the name register.
+         *
+         * @return name register
+         */
+        public static NameRegister getRegistry() {
+            if (_register == null) {
+                _register = new UniqueNamePerInterface();
+            }
+            return _register;
+        }
+
+    }
+
+    /**
+     * Registers a name that is defended by this group of mDNS.
+     *
+     * @param networkInterface
+     *            IP address to handle
+     * @param name
+     *            name to register
+     * @param type
+     *            name type to register
+     */
+    public abstract void register(InetAddress networkInterface, String name, NameType type);
+
+    /**
+     * Checks a name that is defended by this group of mDNS.
+     *
+     * @param networkInterface
+     *            IP address to handle
+     * @param name
+     *            name to check
+     * @param type
+     *            name type to check
+     * @return <code>true</code> if the name is not in conflict, <code>flase</code> otherwise.
+     */
+    public abstract boolean checkName(InetAddress networkInterface, String name, NameType type);
+
+    /**
+     * Increments a name that is defended by this group of mDNS after it has been found in conflict.
+     *
+     * @param networkInterface
+     *            IP address to handle
+     * @param name
+     *            name to increment
+     * @param type
+     *            name type to increments
+     * @return new name
+     */
+    public abstract String incrementHostName(InetAddress networkInterface, String name, NameType type);
+
+}
diff --git a/src/javax/jmdns/impl/NetworkTopologyDiscoveryImpl.java b/src/javax/jmdns/impl/NetworkTopologyDiscoveryImpl.java
new file mode 100644
index 0000000..aa692f3
--- /dev/null
+++ b/src/javax/jmdns/impl/NetworkTopologyDiscoveryImpl.java
@@ -0,0 +1,132 @@
+/**
+ *
+ */
+package javax.jmdns.impl;
+
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.jmdns.NetworkTopologyDiscovery;
+
+/**
+ * This class implements NetworkTopologyDiscovery.
+ *
+ * @author Pierre Frisch
+ */
+public class NetworkTopologyDiscoveryImpl implements NetworkTopologyDiscovery {
+    private final static Logger logger = Logger.getLogger(NetworkTopologyDiscoveryImpl.class.getName());
+
+    private final Method        _isUp;
+
+    private final Method        _supportsMulticast;
+
+    /**
+     *
+     */
+    public NetworkTopologyDiscoveryImpl() {
+        super();
+        Method isUp;
+        try {
+            isUp = NetworkInterface.class.getMethod("isUp", (Class<?>[]) null);
+        } catch (Exception exception) {
+            // We do not want to throw anything if the method does not exist.
+            isUp = null;
+        }
+        _isUp = isUp;
+        Method supportsMulticast;
+        try {
+            supportsMulticast = NetworkInterface.class.getMethod("supportsMulticast", (Class<?>[]) null);
+        } catch (Exception exception) {
+            // We do not want to throw anything if the method does not exist.
+            supportsMulticast = null;
+        }
+        _supportsMulticast = supportsMulticast;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS.NetworkTopologyDiscovery#getInetAddresses()
+     */
+    @Override
+    public InetAddress[] getInetAddresses() {
+        Set<InetAddress> result = new HashSet<InetAddress>();
+        try {
+
+            for (Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces(); nifs.hasMoreElements();) {
+                NetworkInterface nif = nifs.nextElement();
+                for (Enumeration<InetAddress> iaenum = nif.getInetAddresses(); iaenum.hasMoreElements();) {
+                    InetAddress interfaceAddress = iaenum.nextElement();
+                    if (logger.isLoggable(Level.FINEST)) {
+                        logger.finest("Found NetworkInterface/InetAddress: " + nif + " -- " + interfaceAddress);
+                    }
+                    if (this.useInetAddress(nif, interfaceAddress)) {
+                        result.add(interfaceAddress);
+                    }
+                }
+            }
+        } catch (SocketException se) {
+            logger.warning("Error while fetching network interfaces addresses: " + se);
+        }
+        return result.toArray(new InetAddress[result.size()]);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.JmmDNS.NetworkTopologyDiscovery#useInetAddress(java.net.NetworkInterface, java.net.InetAddress)
+     */
+    @Override
+    public boolean useInetAddress(NetworkInterface networkInterface, InetAddress interfaceAddress) {
+        try {
+            if (_isUp != null) {
+                try {
+                    if (!((Boolean) _isUp.invoke(networkInterface, (Object[]) null)).booleanValue()) {
+                        return false;
+                    }
+                } catch (Exception exception) {
+                    // We should hide that exception.
+                }
+            }
+            if (_supportsMulticast != null) {
+                try {
+                    if (!((Boolean) _supportsMulticast.invoke(networkInterface, (Object[]) null)).booleanValue()) {
+                        return false;
+                    }
+                } catch (Exception exception) {
+                    // We should hide that exception.
+                }
+            }
+            if (interfaceAddress.isLoopbackAddress()) {
+                return false;
+            }
+            return true;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.NetworkTopologyDiscovery#lockInetAddress(java.net.InetAddress)
+     */
+    @Override
+    public void lockInetAddress(InetAddress interfaceAddress) {
+        // Default implementation does nothing.
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.NetworkTopologyDiscovery#unlockInetAddress(java.net.InetAddress)
+     */
+    @Override
+    public void unlockInetAddress(InetAddress interfaceAddress) {
+        // Default implementation does nothing.
+    }
+
+}
diff --git a/src/javax/jmdns/impl/NetworkTopologyEventImpl.java b/src/javax/jmdns/impl/NetworkTopologyEventImpl.java
new file mode 100644
index 0000000..000df54
--- /dev/null
+++ b/src/javax/jmdns/impl/NetworkTopologyEventImpl.java
@@ -0,0 +1,82 @@
+/**
+ *
+ */
+package javax.jmdns.impl;
+
+import java.net.InetAddress;
+
+import javax.jmdns.JmDNS;
+import javax.jmdns.NetworkTopologyEvent;
+import javax.jmdns.NetworkTopologyListener;
+
+/**
+ * @author C&eacute;drik Lime, Pierre Frisch
+ */
+public class NetworkTopologyEventImpl extends NetworkTopologyEvent implements Cloneable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1445606146153550463L;
+
+    private final InetAddress _inetAddress;
+
+    /**
+     * Constructs a Network Topology Event.
+     * 
+     * @param jmDNS
+     * @param inetAddress
+     * @exception IllegalArgumentException
+     *                if source is null.
+     */
+    public NetworkTopologyEventImpl(JmDNS jmDNS, InetAddress inetAddress) {
+        super(jmDNS);
+        this._inetAddress = inetAddress;
+    }
+
+    NetworkTopologyEventImpl(NetworkTopologyListener jmmDNS, InetAddress inetAddress) {
+        super(jmmDNS);
+        this._inetAddress = inetAddress;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.NetworkTopologyEvent#getDNS()
+     */
+    @Override
+    public JmDNS getDNS() {
+        return (this.getSource() instanceof JmDNS ? (JmDNS) getSource() : null);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.NetworkTopologyEvent#getInetAddress()
+     */
+    @Override
+    public InetAddress getInetAddress() {
+        return _inetAddress;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("[" + this.getClass().getSimpleName() + "@" + System.identityHashCode(this) + " ");
+        buf.append("\n\tinetAddress: '");
+        buf.append(this.getInetAddress());
+        buf.append("']");
+        // buf.append("' source: ");
+        // buf.append("\n\t" + source + "");
+        // buf.append("\n]");
+        return buf.toString();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see java.lang.Object#clone()
+     */
+    @Override
+    public NetworkTopologyEventImpl clone() throws CloneNotSupportedException {
+        return new NetworkTopologyEventImpl(getDNS(), getInetAddress());
+    }
+
+}
diff --git a/src/javax/jmdns/impl/ServiceEventImpl.java b/src/javax/jmdns/impl/ServiceEventImpl.java
new file mode 100644
index 0000000..95120a8
--- /dev/null
+++ b/src/javax/jmdns/impl/ServiceEventImpl.java
@@ -0,0 +1,124 @@
+// /Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl;
+
+import javax.jmdns.JmDNS;
+import javax.jmdns.ServiceEvent;
+import javax.jmdns.ServiceInfo;
+
+/**
+ * ServiceEvent.
+ * 
+ * @author Werner Randelshofer, Rick Blair
+ */
+/**
+ *
+ */
+public class ServiceEventImpl extends ServiceEvent {
+    /**
+     *
+     */
+    private static final long serialVersionUID = 7107973622016897488L;
+    // private static Logger logger = Logger.getLogger(ServiceEvent.class.getName());
+    /**
+     * The type name of the service.
+     */
+    private final String      _type;
+    /**
+     * The instance name of the service. Or null, if the event was fired to a service type listener.
+     */
+    private final String      _name;
+    /**
+     * The service info record, or null if the service could be be resolved. This is also null, if the event was fired to a service type listener.
+     */
+    private final ServiceInfo _info;
+
+    /**
+     * Creates a new instance.
+     * 
+     * @param jmDNS
+     *            the JmDNS instance which originated the event.
+     * @param type
+     *            the type name of the service.
+     * @param name
+     *            the instance name of the service.
+     * @param info
+     *            the service info record, or null if the service could be be resolved.
+     */
+    public ServiceEventImpl(JmDNSImpl jmDNS, String type, String name, ServiceInfo info) {
+        super(jmDNS);
+        this._type = type;
+        this._name = name;
+        this._info = info;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.ServiceEvent#getDNS()
+     */
+    @Override
+    public JmDNS getDNS() {
+        return (JmDNS) getSource();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.ServiceEvent#getType()
+     */
+    @Override
+    public String getType() {
+        return _type;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.ServiceEvent#getName()
+     */
+    @Override
+    public String getName() {
+        return _name;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see java.util.EventObject#toString()
+     */
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("[" + this.getClass().getSimpleName() + "@" + System.identityHashCode(this) + " ");
+        buf.append("\n\tname: '");
+        buf.append(this.getName());
+        buf.append("' type: '");
+        buf.append(this.getType());
+        buf.append("' info: '");
+        buf.append(this.getInfo());
+        buf.append("']");
+        // buf.append("' source: ");
+        // buf.append("\n\t" + source + "");
+        // buf.append("\n]");
+        return buf.toString();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.ServiceEvent#getInfo()
+     */
+    @Override
+    public ServiceInfo getInfo() {
+        return _info;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.ServiceEvent#clone()
+     */
+    @Override
+    public ServiceEventImpl clone() {
+        ServiceInfoImpl newInfo = new ServiceInfoImpl(this.getInfo());
+        return new ServiceEventImpl((JmDNSImpl) this.getDNS(), this.getType(), this.getName(), newInfo);
+    }
+
+}
diff --git a/src/javax/jmdns/impl/ServiceInfoImpl.java b/src/javax/jmdns/impl/ServiceInfoImpl.java
new file mode 100644
index 0000000..d9c7a92
--- /dev/null
+++ b/src/javax/jmdns/impl/ServiceInfoImpl.java
@@ -0,0 +1,1324 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.jmdns.ServiceEvent;
+import javax.jmdns.ServiceInfo;
+import javax.jmdns.impl.DNSRecord.Pointer;
+import javax.jmdns.impl.DNSRecord.Service;
+import javax.jmdns.impl.DNSRecord.Text;
+import javax.jmdns.impl.constants.DNSRecordClass;
+import javax.jmdns.impl.constants.DNSRecordType;
+import javax.jmdns.impl.constants.DNSState;
+import javax.jmdns.impl.tasks.DNSTask;
+
+/**
+ * JmDNS service information.
+ *
+ * @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer
+ */
+public class ServiceInfoImpl extends ServiceInfo implements DNSListener, DNSStatefulObject {
+    private static Logger           logger = Logger.getLogger(ServiceInfoImpl.class.getName());
+
+    private String                  _domain;
+    private String                  _protocol;
+    private String                  _application;
+    private String                  _name;
+    private String                  _subtype;
+    private String                  _server;
+    private int                     _port;
+    private int                     _weight;
+    private int                     _priority;
+    private byte                    _text[];
+    private Map<String, byte[]>     _props;
+    private final Set<Inet4Address> _ipv4Addresses;
+    private final Set<Inet6Address> _ipv6Addresses;
+
+    private transient String        _key;
+
+    private boolean                 _persistent;
+    private boolean                 _needTextAnnouncing;
+
+    private final ServiceInfoState  _state;
+
+    private Delegate                _delegate;
+
+    public static interface Delegate {
+
+        public void textValueUpdated(ServiceInfo target, byte[] value);
+
+    }
+
+    private final static class ServiceInfoState extends DNSStatefulObject.DefaultImplementation {
+
+        private static final long     serialVersionUID = 1104131034952196820L;
+
+        private final ServiceInfoImpl _info;
+
+        /**
+         * @param info
+         */
+        public ServiceInfoState(ServiceInfoImpl info) {
+            super();
+            _info = info;
+        }
+
+        @Override
+        protected void setTask(DNSTask task) {
+            super.setTask(task);
+            if ((this._task == null) && _info.needTextAnnouncing()) {
+                this.lock();
+                try {
+                    if ((this._task == null) && _info.needTextAnnouncing()) {
+                        if (this._state.isAnnounced()) {
+                            this.setState(DNSState.ANNOUNCING_1);
+                            if (this.getDns() != null) {
+                                this.getDns().startAnnouncer();
+                            }
+                        }
+                        _info.setNeedTextAnnouncing(false);
+                    }
+                } finally {
+                    this.unlock();
+                }
+            }
+        }
+
+        @Override
+        public void setDns(JmDNSImpl dns) {
+            super.setDns(dns);
+        }
+
+    }
+
+    /**
+     * @param type
+     * @param name
+     * @param subtype
+     * @param port
+     * @param weight
+     * @param priority
+     * @param persistent
+     * @param text
+     * @see javax.jmdns.ServiceInfo#create(String, String, int, int, int, String)
+     */
+    public ServiceInfoImpl(String type, String name, String subtype, int port, int weight, int priority, boolean persistent, String text) {
+        this(ServiceInfoImpl.decodeQualifiedNameMap(type, name, subtype), port, weight, priority, persistent, (byte[]) null);
+        _server = text;
+        try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream(text.length());
+            writeUTF(out, text);
+            this._text = out.toByteArray();
+        } catch (IOException e) {
+            throw new RuntimeException("unexpected exception: " + e);
+        }
+    }
+
+    /**
+     * @param type
+     * @param name
+     * @param subtype
+     * @param port
+     * @param weight
+     * @param priority
+     * @param persistent
+     * @param props
+     * @see javax.jmdns.ServiceInfo#create(String, String, int, int, int, Map)
+     */
+    public ServiceInfoImpl(String type, String name, String subtype, int port, int weight, int priority, boolean persistent, Map<String, ?> props) {
+        this(ServiceInfoImpl.decodeQualifiedNameMap(type, name, subtype), port, weight, priority, persistent, textFromProperties(props));
+    }
+
+    /**
+     * @param type
+     * @param name
+     * @param subtype
+     * @param port
+     * @param weight
+     * @param priority
+     * @param persistent
+     * @param text
+     * @see javax.jmdns.ServiceInfo#create(String, String, int, int, int, byte[])
+     */
+    public ServiceInfoImpl(String type, String name, String subtype, int port, int weight, int priority, boolean persistent, byte text[]) {
+        this(ServiceInfoImpl.decodeQualifiedNameMap(type, name, subtype), port, weight, priority, persistent, text);
+    }
+
+    public ServiceInfoImpl(Map<Fields, String> qualifiedNameMap, int port, int weight, int priority, boolean persistent, Map<String, ?> props) {
+        this(qualifiedNameMap, port, weight, priority, persistent, textFromProperties(props));
+    }
+
+    ServiceInfoImpl(Map<Fields, String> qualifiedNameMap, int port, int weight, int priority, boolean persistent, String text) {
+        this(qualifiedNameMap, port, weight, priority, persistent, (byte[]) null);
+        _server = text;
+        try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream(text.length());
+            writeUTF(out, text);
+            this._text = out.toByteArray();
+        } catch (IOException e) {
+            throw new RuntimeException("unexpected exception: " + e);
+        }
+    }
+
+    ServiceInfoImpl(Map<Fields, String> qualifiedNameMap, int port, int weight, int priority, boolean persistent, byte text[]) {
+        Map<Fields, String> map = ServiceInfoImpl.checkQualifiedNameMap(qualifiedNameMap);
+
+        this._domain = map.get(Fields.Domain);
+        this._protocol = map.get(Fields.Protocol);
+        this._application = map.get(Fields.Application);
+        this._name = map.get(Fields.Instance);
+        this._subtype = map.get(Fields.Subtype);
+
+        this._port = port;
+        this._weight = weight;
+        this._priority = priority;
+        this._text = text;
+        this.setNeedTextAnnouncing(false);
+        this._state = new ServiceInfoState(this);
+        this._persistent = persistent;
+        this._ipv4Addresses = Collections.synchronizedSet(new LinkedHashSet<Inet4Address>());
+        this._ipv6Addresses = Collections.synchronizedSet(new LinkedHashSet<Inet6Address>());
+    }
+
+    /**
+     * During recovery we need to duplicate service info to reregister them
+     *
+     * @param info
+     */
+    ServiceInfoImpl(ServiceInfo info) {
+        this._ipv4Addresses = Collections.synchronizedSet(new LinkedHashSet<Inet4Address>());
+        this._ipv6Addresses = Collections.synchronizedSet(new LinkedHashSet<Inet6Address>());
+        if (info != null) {
+            this._domain = info.getDomain();
+            this._protocol = info.getProtocol();
+            this._application = info.getApplication();
+            this._name = info.getName();
+            this._subtype = info.getSubtype();
+            this._port = info.getPort();
+            this._weight = info.getWeight();
+            this._priority = info.getPriority();
+            this._text = info.getTextBytes();
+            this._persistent = info.isPersistent();
+            Inet6Address[] ipv6Addresses = info.getInet6Addresses();
+            for (Inet6Address address : ipv6Addresses) {
+                this._ipv6Addresses.add(address);
+            }
+            Inet4Address[] ipv4Addresses = info.getInet4Addresses();
+            for (Inet4Address address : ipv4Addresses) {
+                this._ipv4Addresses.add(address);
+            }
+        }
+        this._state = new ServiceInfoState(this);
+    }
+
+    public static Map<Fields, String> decodeQualifiedNameMap(String type, String name, String subtype) {
+        Map<Fields, String> qualifiedNameMap = decodeQualifiedNameMapForType(type);
+
+        qualifiedNameMap.put(Fields.Instance, name);
+        qualifiedNameMap.put(Fields.Subtype, subtype);
+
+        return checkQualifiedNameMap(qualifiedNameMap);
+    }
+
+    public static Map<Fields, String> decodeQualifiedNameMapForType(String type) {
+        int index;
+
+        String casePreservedType = type;
+
+        String aType = type.toLowerCase();
+        String application = aType;
+        String protocol = "";
+        String subtype = "";
+        String name = "";
+        String domain = "";
+
+        if (aType.contains("in-addr.arpa") || aType.contains("ip6.arpa")) {
+            index = (aType.contains("in-addr.arpa") ? aType.indexOf("in-addr.arpa") : aType.indexOf("ip6.arpa"));
+            name = removeSeparators(casePreservedType.substring(0, index));
+            domain = casePreservedType.substring(index);
+            application = "";
+        } else if ((!aType.contains("_")) && aType.contains(".")) {
+            index = aType.indexOf('.');
+            name = removeSeparators(casePreservedType.substring(0, index));
+            domain = removeSeparators(casePreservedType.substring(index));
+            application = "";
+        } else {
+            // First remove the name if it there.
+            if (!aType.startsWith("_") || aType.startsWith("_services")) {
+                index = aType.indexOf('.');
+                if (index > 0) {
+                    // We need to preserve the case for the user readable name.
+                    name = casePreservedType.substring(0, index);
+                    if (index + 1 < aType.length()) {
+                        aType = aType.substring(index + 1);
+                        casePreservedType = casePreservedType.substring(index + 1);
+                    }
+                }
+            }
+
+            index = aType.lastIndexOf("._");
+            if (index > 0) {
+                int start = index + 2;
+                int end = aType.indexOf('.', start);
+                protocol = casePreservedType.substring(start, end);
+            }
+            if (protocol.length() > 0) {
+                index = aType.indexOf("_" + protocol.toLowerCase() + ".");
+                int start = index + protocol.length() + 2;
+                int end = aType.length() - (aType.endsWith(".") ? 1 : 0);
+                domain = casePreservedType.substring(start, end);
+                application = casePreservedType.substring(0, index - 1);
+            }
+            index = application.toLowerCase().indexOf("._sub");
+            if (index > 0) {
+                int start = index + 5;
+                subtype = removeSeparators(application.substring(0, index));
+                application = application.substring(start);
+            }
+        }
+
+        final Map<Fields, String> qualifiedNameMap = new HashMap<Fields, String>(5);
+        qualifiedNameMap.put(Fields.Domain, removeSeparators(domain));
+        qualifiedNameMap.put(Fields.Protocol, protocol);
+        qualifiedNameMap.put(Fields.Application, removeSeparators(application));
+        qualifiedNameMap.put(Fields.Instance, name);
+        qualifiedNameMap.put(Fields.Subtype, subtype);
+
+        return qualifiedNameMap;
+    }
+
+    protected static Map<Fields, String> checkQualifiedNameMap(Map<Fields, String> qualifiedNameMap) {
+        Map<Fields, String> checkedQualifiedNameMap = new HashMap<Fields, String>(5);
+
+        // Optional domain
+        String domain = (qualifiedNameMap.containsKey(Fields.Domain) ? qualifiedNameMap.get(Fields.Domain) : "local");
+        if ((domain == null) || (domain.length() == 0)) {
+            domain = "local";
+        }
+        domain = removeSeparators(domain);
+        checkedQualifiedNameMap.put(Fields.Domain, domain);
+        // Optional protocol
+        String protocol = (qualifiedNameMap.containsKey(Fields.Protocol) ? qualifiedNameMap.get(Fields.Protocol) : "tcp");
+        if ((protocol == null) || (protocol.length() == 0)) {
+            protocol = "tcp";
+        }
+        protocol = removeSeparators(protocol);
+        checkedQualifiedNameMap.put(Fields.Protocol, protocol);
+        // Application
+        String application = (qualifiedNameMap.containsKey(Fields.Application) ? qualifiedNameMap.get(Fields.Application) : "");
+        if ((application == null) || (application.length() == 0)) {
+            application = "";
+        }
+        application = removeSeparators(application);
+        checkedQualifiedNameMap.put(Fields.Application, application);
+        // Instance
+        String instance = (qualifiedNameMap.containsKey(Fields.Instance) ? qualifiedNameMap.get(Fields.Instance) : "");
+        if ((instance == null) || (instance.length() == 0)) {
+            instance = "";
+            // throw new IllegalArgumentException("The instance name component of a fully qualified service cannot be empty.");
+        }
+        instance = removeSeparators(instance);
+        checkedQualifiedNameMap.put(Fields.Instance, instance);
+        // Optional Subtype
+        String subtype = (qualifiedNameMap.containsKey(Fields.Subtype) ? qualifiedNameMap.get(Fields.Subtype) : "");
+        if ((subtype == null) || (subtype.length() == 0)) {
+            subtype = "";
+        }
+        subtype = removeSeparators(subtype);
+        checkedQualifiedNameMap.put(Fields.Subtype, subtype);
+
+        return checkedQualifiedNameMap;
+    }
+
+    private static String removeSeparators(String name) {
+        if (name == null) {
+            return "";
+        }
+        String newName = name.trim();
+        if (newName.startsWith(".")) {
+            newName = newName.substring(1);
+        }
+        if (newName.startsWith("_")) {
+            newName = newName.substring(1);
+        }
+        if (newName.endsWith(".")) {
+            newName = newName.substring(0, newName.length() - 1);
+        }
+        return newName;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getType() {
+        String domain = this.getDomain();
+        String protocol = this.getProtocol();
+        String application = this.getApplication();
+        return (application.length() > 0 ? "_" + application + "." : "") + (protocol.length() > 0 ? "_" + protocol + "." : "") + domain + ".";
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getTypeWithSubtype() {
+        String subtype = this.getSubtype();
+        return (subtype.length() > 0 ? "_" + subtype.toLowerCase() + "._sub." : "") + this.getType();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getName() {
+        return (_name != null ? _name : "");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getKey() {
+        if (this._key == null) {
+            this._key = this.getQualifiedName().toLowerCase();
+        }
+        return this._key;
+    }
+
+    /**
+     * Sets the service instance name.
+     *
+     * @param name
+     *            unqualified service instance name, such as <code>foobar</code>
+     */
+    void setName(String name) {
+        this._name = name;
+        this._key = null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getQualifiedName() {
+        String domain = this.getDomain();
+        String protocol = this.getProtocol();
+        String application = this.getApplication();
+        String instance = this.getName();
+        // String subtype = this.getSubtype();
+        // return (instance.length() > 0 ? instance + "." : "") + (application.length() > 0 ? "_" + application + "." : "") + (protocol.length() > 0 ? "_" + protocol + (subtype.length() > 0 ? ",_" + subtype.toLowerCase() + "." : ".") : "") + domain
+        // + ".";
+        return (instance.length() > 0 ? instance + "." : "") + (application.length() > 0 ? "_" + application + "." : "") + (protocol.length() > 0 ? "_" + protocol + "." : "") + domain + ".";
+    }
+
+    /**
+     * @see javax.jmdns.ServiceInfo#getServer()
+     */
+    @Override
+    public String getServer() {
+        return (_server != null ? _server : "");
+    }
+
+    /**
+     * @param server
+     *            the server to set
+     */
+    void setServer(String server) {
+        this._server = server;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Deprecated
+    @Override
+    public String getHostAddress() {
+        String[] names = this.getHostAddresses();
+        return (names.length > 0 ? names[0] : "");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String[] getHostAddresses() {
+        Inet4Address[] ip4Aaddresses = this.getInet4Addresses();
+        Inet6Address[] ip6Aaddresses = this.getInet6Addresses();
+        String[] names = new String[ip4Aaddresses.length + ip6Aaddresses.length];
+        for (int i = 0; i < ip4Aaddresses.length; i++) {
+            names[i] = ip4Aaddresses[i].getHostAddress();
+        }
+        for (int i = 0; i < ip6Aaddresses.length; i++) {
+            names[i + ip4Aaddresses.length] = "[" + ip6Aaddresses[i].getHostAddress() + "]";
+        }
+        return names;
+    }
+
+    /**
+     * @param addr
+     *            the addr to add
+     */
+    void addAddress(Inet4Address addr) {
+        _ipv4Addresses.add(addr);
+    }
+
+    /**
+     * @param addr
+     *            the addr to add
+     */
+    void addAddress(Inet6Address addr) {
+        _ipv6Addresses.add(addr);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Deprecated
+    @Override
+    public InetAddress getAddress() {
+        return this.getInetAddress();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Deprecated
+    @Override
+    public InetAddress getInetAddress() {
+        InetAddress[] addresses = this.getInetAddresses();
+        return (addresses.length > 0 ? addresses[0] : null);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Deprecated
+    @Override
+    public Inet4Address getInet4Address() {
+        Inet4Address[] addresses = this.getInet4Addresses();
+        return (addresses.length > 0 ? addresses[0] : null);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Deprecated
+    @Override
+    public Inet6Address getInet6Address() {
+        Inet6Address[] addresses = this.getInet6Addresses();
+        return (addresses.length > 0 ? addresses[0] : null);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.ServiceInfo#getInetAddresses()
+     */
+    @Override
+    public InetAddress[] getInetAddresses() {
+        List<InetAddress> aList = new ArrayList<InetAddress>(_ipv4Addresses.size() + _ipv6Addresses.size());
+        aList.addAll(_ipv4Addresses);
+        aList.addAll(_ipv6Addresses);
+        return aList.toArray(new InetAddress[aList.size()]);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.ServiceInfo#getInet4Addresses()
+     */
+    @Override
+    public Inet4Address[] getInet4Addresses() {
+        return _ipv4Addresses.toArray(new Inet4Address[_ipv4Addresses.size()]);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.ServiceInfo#getInet6Addresses()
+     */
+    @Override
+    public Inet6Address[] getInet6Addresses() {
+        return _ipv6Addresses.toArray(new Inet6Address[_ipv6Addresses.size()]);
+    }
+
+    /**
+     * @see javax.jmdns.ServiceInfo#getPort()
+     */
+    @Override
+    public int getPort() {
+        return _port;
+    }
+
+    /**
+     * @see javax.jmdns.ServiceInfo#getPriority()
+     */
+    @Override
+    public int getPriority() {
+        return _priority;
+    }
+
+    /**
+     * @see javax.jmdns.ServiceInfo#getWeight()
+     */
+    @Override
+    public int getWeight() {
+        return _weight;
+    }
+
+    /**
+     * @see javax.jmdns.ServiceInfo#getTextBytes()
+     */
+    @Override
+    public byte[] getTextBytes() {
+        return (this._text != null && this._text.length > 0 ? this._text : DNSRecord.EMPTY_TXT);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Deprecated
+    @Override
+    public String getTextString() {
+        Map<String, byte[]> properties = this.getProperties();
+        for (String key : properties.keySet()) {
+            byte[] value = properties.get(key);
+            if ((value != null) && (value.length > 0)) {
+                return key + "=" + new String(value);
+            }
+            return key;
+        }
+        return "";
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.ServiceInfo#getURL()
+     */
+    @Deprecated
+    @Override
+    public String getURL() {
+        return this.getURL("http");
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.ServiceInfo#getURLs()
+     */
+    @Override
+    public String[] getURLs() {
+        return this.getURLs("http");
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.ServiceInfo#getURL(java.lang.String)
+     */
+    @Deprecated
+    @Override
+    public String getURL(String protocol) {
+        String[] urls = this.getURLs(protocol);
+        return (urls.length > 0 ? urls[0] : protocol + "://null:" + getPort());
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.ServiceInfo#getURLs(java.lang.String)
+     */
+    @Override
+    public String[] getURLs(String protocol) {
+        InetAddress[] addresses = this.getInetAddresses();
+        String[] urls = new String[addresses.length];
+        for (int i = 0; i < addresses.length; i++) {
+            String url = protocol + "://" + addresses[i].getHostAddress() + ":" + getPort();
+            String path = getPropertyString("path");
+            if (path != null) {
+                if (path.indexOf("://") >= 0) {
+                    url = path;
+                } else {
+                    url += path.startsWith("/") ? path : "/" + path;
+                }
+            }
+            urls[i] = url;
+        }
+        return urls;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized byte[] getPropertyBytes(String name) {
+        return this.getProperties().get(name);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized String getPropertyString(String name) {
+        byte data[] = this.getProperties().get(name);
+        if (data == null) {
+            return null;
+        }
+        if (data == NO_VALUE) {
+            return "true";
+        }
+        return readUTF(data, 0, data.length);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Enumeration<String> getPropertyNames() {
+        Map<String, byte[]> properties = this.getProperties();
+        Collection<String> names = (properties != null ? properties.keySet() : Collections.<String> emptySet());
+        return new Vector<String>(names).elements();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getApplication() {
+        return (_application != null ? _application : "");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getDomain() {
+        return (_domain != null ? _domain : "local");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getProtocol() {
+        return (_protocol != null ? _protocol : "tcp");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getSubtype() {
+        return (_subtype != null ? _subtype : "");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Map<Fields, String> getQualifiedNameMap() {
+        Map<Fields, String> map = new HashMap<Fields, String>(5);
+
+        map.put(Fields.Domain, this.getDomain());
+        map.put(Fields.Protocol, this.getProtocol());
+        map.put(Fields.Application, this.getApplication());
+        map.put(Fields.Instance, this.getName());
+        map.put(Fields.Subtype, this.getSubtype());
+        return map;
+    }
+
+    /**
+     * Write a UTF string with a length to a stream.
+     */
+    static void writeUTF(OutputStream out, String str) throws IOException {
+        for (int i = 0, len = str.length(); i < len; i++) {
+            int c = str.charAt(i);
+            if ((c >= 0x0001) && (c <= 0x007F)) {
+                out.write(c);
+            } else {
+                if (c > 0x07FF) {
+                    out.write(0xE0 | ((c >> 12) & 0x0F));
+                    out.write(0x80 | ((c >> 6) & 0x3F));
+                    out.write(0x80 | ((c >> 0) & 0x3F));
+                } else {
+                    out.write(0xC0 | ((c >> 6) & 0x1F));
+                    out.write(0x80 | ((c >> 0) & 0x3F));
+                }
+            }
+        }
+    }
+
+    /**
+     * Read data bytes as a UTF stream.
+     */
+    String readUTF(byte data[], int off, int len) {
+        int offset = off;
+        StringBuffer buf = new StringBuffer();
+        for (int end = offset + len; offset < end;) {
+            int ch = data[offset++] & 0xFF;
+            switch (ch >> 4) {
+                case 0:
+                case 1:
+                case 2:
+                case 3:
+                case 4:
+                case 5:
+                case 6:
+                case 7:
+                    // 0xxxxxxx
+                    break;
+                case 12:
+                case 13:
+                    if (offset >= len) {
+                        return null;
+                    }
+                    // 110x xxxx 10xx xxxx
+                    ch = ((ch & 0x1F) << 6) | (data[offset++] & 0x3F);
+                    break;
+                case 14:
+                    if (offset + 2 >= len) {
+                        return null;
+                    }
+                    // 1110 xxxx 10xx xxxx 10xx xxxx
+                    ch = ((ch & 0x0f) << 12) | ((data[offset++] & 0x3F) << 6) | (data[offset++] & 0x3F);
+                    break;
+                default:
+                    if (offset + 1 >= len) {
+                        return null;
+                    }
+                    // 10xx xxxx, 1111 xxxx
+                    ch = ((ch & 0x3F) << 4) | (data[offset++] & 0x0f);
+                    break;
+            }
+            buf.append((char) ch);
+        }
+        return buf.toString();
+    }
+
+    synchronized Map<String, byte[]> getProperties() {
+        if ((_props == null) && (this.getTextBytes() != null)) {
+            Hashtable<String, byte[]> properties = new Hashtable<String, byte[]>();
+            try {
+                int off = 0;
+                while (off < getTextBytes().length) {
+                    // length of the next key value pair
+                    int len = getTextBytes()[off++] & 0xFF;
+                    if ((len == 0) || (off + len > getTextBytes().length)) {
+                        properties.clear();
+                        break;
+                    }
+                    // look for the '='
+                    int i = 0;
+                    for (; (i < len) && (getTextBytes()[off + i] != '='); i++) {
+                        /* Stub */
+                    }
+
+                    // get the property name
+                    String name = readUTF(getTextBytes(), off, i);
+                    if (name == null) {
+                        properties.clear();
+                        break;
+                    }
+                    if (i == len) {
+                        properties.put(name, NO_VALUE);
+                    } else {
+                        byte value[] = new byte[len - ++i];
+                        System.arraycopy(getTextBytes(), off + i, value, 0, len - i);
+                        properties.put(name, value);
+                        off += len;
+                    }
+                }
+            } catch (Exception exception) {
+                // We should get better logging.
+                logger.log(Level.WARNING, "Malformed TXT Field ", exception);
+            }
+            this._props = properties;
+        }
+        return (_props != null ? _props : Collections.<String, byte[]> emptyMap());
+    }
+
+    /**
+     * JmDNS callback to update a DNS record.
+     *
+     * @param dnsCache
+     * @param now
+     * @param rec
+     */
+    @Override
+    public void updateRecord(DNSCache dnsCache, long now, DNSEntry rec) {
+        if ((rec instanceof DNSRecord) && !rec.isExpired(now)) {
+            boolean serviceUpdated = false;
+            switch (rec.getRecordType()) {
+                case TYPE_A: // IPv4
+                    if (rec.getName().equalsIgnoreCase(this.getServer())) {
+                        _ipv4Addresses.add((Inet4Address) ((DNSRecord.Address) rec).getAddress());
+                        serviceUpdated = true;
+                    }
+                    break;
+                case TYPE_AAAA: // IPv6
+                    if (rec.getName().equalsIgnoreCase(this.getServer())) {
+                        _ipv6Addresses.add((Inet6Address) ((DNSRecord.Address) rec).getAddress());
+                        serviceUpdated = true;
+                    }
+                    break;
+                case TYPE_SRV:
+                    if (rec.getName().equalsIgnoreCase(this.getQualifiedName())) {
+                        DNSRecord.Service srv = (DNSRecord.Service) rec;
+                        boolean serverChanged = (_server == null) || !_server.equalsIgnoreCase(srv.getServer());
+                        _server = srv.getServer();
+                        _port = srv.getPort();
+                        _weight = srv.getWeight();
+                        _priority = srv.getPriority();
+                        if (serverChanged) {
+                            _ipv4Addresses.clear();
+                            _ipv6Addresses.clear();
+                            for (DNSEntry entry : dnsCache.getDNSEntryList(_server, DNSRecordType.TYPE_A, DNSRecordClass.CLASS_IN)) {
+                                this.updateRecord(dnsCache, now, entry);
+                            }
+                            for (DNSEntry entry : dnsCache.getDNSEntryList(_server, DNSRecordType.TYPE_AAAA, DNSRecordClass.CLASS_IN)) {
+                                this.updateRecord(dnsCache, now, entry);
+                            }
+                            // We do not want to trigger the listener in this case as it will be triggered if the address resolves.
+                        } else {
+                            serviceUpdated = true;
+                        }
+                    }
+                    break;
+                case TYPE_TXT:
+                    if (rec.getName().equalsIgnoreCase(this.getQualifiedName())) {
+                        DNSRecord.Text txt = (DNSRecord.Text) rec;
+                        _text = txt.getText();
+                        _props = null; // set it null for apply update text data
+                        serviceUpdated = true;
+                    }
+                    break;
+                case TYPE_PTR:
+                    if ((this.getSubtype().length() == 0) && (rec.getSubtype().length() != 0)) {
+                        _subtype = rec.getSubtype();
+                        serviceUpdated = true;
+                    }
+                    break;
+                default:
+                    break;
+            }
+            if (serviceUpdated && this.hasData()) {
+                JmDNSImpl dns = this.getDns();
+                if (dns != null) {
+                    ServiceEvent event = ((DNSRecord) rec).getServiceEvent(dns);
+                    event = new ServiceEventImpl(dns, event.getType(), event.getName(), this);
+                    dns.handleServiceResolved(event);
+                }
+            }
+            // This is done, to notify the wait loop in method JmDNS.waitForInfoData(ServiceInfo info, int timeout);
+            synchronized (this) {
+                this.notifyAll();
+            }
+        }
+    }
+
+    /**
+     * Returns true if the service info is filled with data.
+     *
+     * @return <code>true</code> if the service info has data, <code>false</code> otherwise.
+     */
+    @Override
+    public synchronized boolean hasData() {
+        return this.getServer() != null && this.hasInetAddress() && this.getTextBytes() != null && this.getTextBytes().length > 0;
+        // return this.getServer() != null && (this.getAddress() != null || (this.getTextBytes() != null && this.getTextBytes().length > 0));
+    }
+
+    private final boolean hasInetAddress() {
+        return _ipv4Addresses.size() > 0 || _ipv6Addresses.size() > 0;
+    }
+
+    // State machine
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean advanceState(DNSTask task) {
+        return _state.advanceState(task);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean revertState() {
+        return _state.revertState();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean cancelState() {
+        return _state.cancelState();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean closeState() {
+        return this._state.closeState();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean recoverState() {
+        return this._state.recoverState();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void removeAssociationWithTask(DNSTask task) {
+        _state.removeAssociationWithTask(task);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void associateWithTask(DNSTask task, DNSState state) {
+        _state.associateWithTask(task, state);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isAssociatedWithTask(DNSTask task, DNSState state) {
+        return _state.isAssociatedWithTask(task, state);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isProbing() {
+        return _state.isProbing();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isAnnouncing() {
+        return _state.isAnnouncing();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isAnnounced() {
+        return _state.isAnnounced();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isCanceling() {
+        return this._state.isCanceling();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isCanceled() {
+        return _state.isCanceled();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isClosing() {
+        return _state.isClosing();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isClosed() {
+        return _state.isClosed();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean waitForAnnounced(long timeout) {
+        return _state.waitForAnnounced(timeout);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean waitForCanceled(long timeout) {
+        return _state.waitForCanceled(timeout);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode() {
+        return getQualifiedName().hashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean equals(Object obj) {
+        return (obj instanceof ServiceInfoImpl) && getQualifiedName().equals(((ServiceInfoImpl) obj).getQualifiedName());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getNiceTextString() {
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0, len = this.getTextBytes().length; i < len; i++) {
+            if (i >= 200) {
+                buf.append("...");
+                break;
+            }
+            int ch = getTextBytes()[i] & 0xFF;
+            if ((ch < ' ') || (ch > 127)) {
+                buf.append("\\0");
+                buf.append(Integer.toString(ch, 8));
+            } else {
+                buf.append((char) ch);
+            }
+        }
+        return buf.toString();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.ServiceInfo#clone()
+     */
+    @Override
+    public ServiceInfoImpl clone() {
+        ServiceInfoImpl serviceInfo = new ServiceInfoImpl(this.getQualifiedNameMap(), _port, _weight, _priority, _persistent, _text);
+        Inet6Address[] ipv6Addresses = this.getInet6Addresses();
+        for (Inet6Address address : ipv6Addresses) {
+            serviceInfo._ipv6Addresses.add(address);
+        }
+        Inet4Address[] ipv4Addresses = this.getInet4Addresses();
+        for (Inet4Address address : ipv4Addresses) {
+            serviceInfo._ipv4Addresses.add(address);
+        }
+        return serviceInfo;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("[" + this.getClass().getSimpleName() + "@" + System.identityHashCode(this) + " ");
+        buf.append("name: '");
+        buf.append((this.getName().length() > 0 ? this.getName() + "." : "") + this.getTypeWithSubtype());
+        buf.append("' address: '");
+        InetAddress[] addresses = this.getInetAddresses();
+        if (addresses.length > 0) {
+            for (InetAddress address : addresses) {
+                buf.append(address);
+                buf.append(':');
+                buf.append(this.getPort());
+                buf.append(' ');
+            }
+        } else {
+            buf.append("(null):");
+            buf.append(this.getPort());
+        }
+        buf.append("' status: '");
+        buf.append(_state.toString());
+        buf.append(this.isPersistent() ? "' is persistent," : "',");
+        buf.append(" has ");
+        buf.append(this.hasData() ? "" : "NO ");
+        buf.append("data");
+        if (this.getTextBytes().length > 0) {
+            // buf.append("\n");
+            // buf.append(this.getNiceTextString());
+            Map<String, byte[]> properties = this.getProperties();
+            if (!properties.isEmpty()) {
+                buf.append("\n");
+                for (String key : properties.keySet()) {
+                    buf.append("\t" + key + ": " + new String(properties.get(key)) + "\n");
+                }
+            } else {
+                buf.append(" empty");
+            }
+        }
+        buf.append(']');
+        return buf.toString();
+    }
+
+    public Collection<DNSRecord> answers(boolean unique, int ttl, HostInfo localHost) {
+        List<DNSRecord> list = new ArrayList<DNSRecord>();
+        if (this.getSubtype().length() > 0) {
+            list.add(new Pointer(this.getTypeWithSubtype(), DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE, ttl, this.getQualifiedName()));
+        }
+        list.add(new Pointer(this.getType(), DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE, ttl, this.getQualifiedName()));
+        list.add(new Service(this.getQualifiedName(), DNSRecordClass.CLASS_IN, unique, ttl, _priority, _weight, _port, localHost.getName()));
+        list.add(new Text(this.getQualifiedName(), DNSRecordClass.CLASS_IN, unique, ttl, this.getTextBytes()));
+        return list;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setText(byte[] text) throws IllegalStateException {
+        synchronized (this) {
+            this._text = text;
+            this._props = null;
+            this.setNeedTextAnnouncing(true);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setText(Map<String, ?> props) throws IllegalStateException {
+        this.setText(textFromProperties(props));
+    }
+
+    /**
+     * This is used internally by the framework
+     *
+     * @param text
+     */
+    void _setText(byte[] text) {
+        this._text = text;
+        this._props = null;
+    }
+
+    private static byte[] textFromProperties(Map<String, ?> props) {
+        byte[] text = null;
+        if (props != null) {
+            try {
+                ByteArrayOutputStream out = new ByteArrayOutputStream(256);
+                for (String key : props.keySet()) {
+                    Object val = props.get(key);
+                    ByteArrayOutputStream out2 = new ByteArrayOutputStream(100);
+                    writeUTF(out2, key);
+                    if (val == null) {
+                        // Skip
+                    } else if (val instanceof String) {
+                        out2.write('=');
+                        writeUTF(out2, (String) val);
+                    } else if (val instanceof byte[]) {
+                        byte[] bval = (byte[]) val;
+                        if (bval.length > 0) {
+                            out2.write('=');
+                            out2.write(bval, 0, bval.length);
+                        } else {
+                            val = null;
+                        }
+                    } else {
+                        throw new IllegalArgumentException("invalid property value: " + val);
+                    }
+                    byte data[] = out2.toByteArray();
+                    if (data.length > 255) {
+                        throw new IOException("Cannot have individual values larger that 255 chars. Offending value: " + key + (val != null ? "" : "=" + val));
+                    }
+                    out.write((byte) data.length);
+                    out.write(data, 0, data.length);
+                }
+                text = out.toByteArray();
+            } catch (IOException e) {
+                throw new RuntimeException("unexpected exception: " + e);
+            }
+        }
+        return (text != null && text.length > 0 ? text : DNSRecord.EMPTY_TXT);
+    }
+
+    public void setDns(JmDNSImpl dns) {
+        this._state.setDns(dns);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public JmDNSImpl getDns() {
+        return this._state.getDns();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isPersistent() {
+        return _persistent;
+    }
+
+    /**
+     * @param needTextAnnouncing
+     *            the needTextAnnouncing to set
+     */
+    public void setNeedTextAnnouncing(boolean needTextAnnouncing) {
+        this._needTextAnnouncing = needTextAnnouncing;
+        if (this._needTextAnnouncing) {
+            _state.setTask(null);
+        }
+    }
+
+    /**
+     * @return the needTextAnnouncing
+     */
+    public boolean needTextAnnouncing() {
+        return _needTextAnnouncing;
+    }
+
+    /**
+     * @return the delegate
+     */
+    Delegate getDelegate() {
+        return this._delegate;
+    }
+
+    /**
+     * @param delegate
+     *            the delegate to set
+     */
+    void setDelegate(Delegate delegate) {
+        this._delegate = delegate;
+    }
+
+}
diff --git a/src/javax/jmdns/impl/SocketListener.java b/src/javax/jmdns/impl/SocketListener.java
new file mode 100644
index 0000000..f184e26
--- /dev/null
+++ b/src/javax/jmdns/impl/SocketListener.java
@@ -0,0 +1,81 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.jmdns.impl.constants.DNSConstants;
+
+/**
+ * Listen for multicast packets.
+ */
+class SocketListener extends Thread {
+    static Logger           logger = Logger.getLogger(SocketListener.class.getName());
+
+    /**
+     *
+     */
+    private final JmDNSImpl _jmDNSImpl;
+
+    /**
+     * @param jmDNSImpl
+     */
+    SocketListener(JmDNSImpl jmDNSImpl) {
+        super("SocketListener(" + (jmDNSImpl != null ? jmDNSImpl.getName() : "") + ")");
+        this.setDaemon(true);
+        this._jmDNSImpl = jmDNSImpl;
+    }
+
+    @Override
+    public void run() {
+        try {
+            byte buf[] = new byte[DNSConstants.MAX_MSG_ABSOLUTE];
+            DatagramPacket packet = new DatagramPacket(buf, buf.length);
+            while (!this._jmDNSImpl.isCanceling() && !this._jmDNSImpl.isCanceled()) {
+                packet.setLength(buf.length);
+                this._jmDNSImpl.getSocket().receive(packet);
+                if (this._jmDNSImpl.isCanceling() || this._jmDNSImpl.isCanceled() || this._jmDNSImpl.isClosing() || this._jmDNSImpl.isClosed()) {
+                    break;
+                }
+                try {
+                    if (this._jmDNSImpl.getLocalHost().shouldIgnorePacket(packet)) {
+                        continue;
+                    }
+
+                    DNSIncoming msg = new DNSIncoming(packet);
+                    if (logger.isLoggable(Level.FINEST)) {
+                        logger.finest(this.getName() + ".run() JmDNS in:" + msg.print(true));
+                    }
+                    if (msg.isQuery()) {
+                        if (packet.getPort() != DNSConstants.MDNS_PORT) {
+                            this._jmDNSImpl.handleQuery(msg, packet.getAddress(), packet.getPort());
+                        }
+                        this._jmDNSImpl.handleQuery(msg, this._jmDNSImpl.getGroup(), DNSConstants.MDNS_PORT);
+                    } else {
+                        this._jmDNSImpl.handleResponse(msg);
+                    }
+                } catch (IOException e) {
+                    logger.log(Level.WARNING, this.getName() + ".run() exception ", e);
+                }
+            }
+        } catch (IOException e) {
+            if (!this._jmDNSImpl.isCanceling() && !this._jmDNSImpl.isCanceled() && !this._jmDNSImpl.isClosing() && !this._jmDNSImpl.isClosed()) {
+                logger.log(Level.WARNING, this.getName() + ".run() exception ", e);
+                this._jmDNSImpl.recover();
+            }
+        }
+        if (logger.isLoggable(Level.FINEST)) {
+            logger.finest(this.getName() + ".run() exiting.");
+        }
+    }
+
+    public JmDNSImpl getDns() {
+        return _jmDNSImpl;
+    }
+
+}
diff --git a/src/javax/jmdns/impl/constants/DNSConstants.java b/src/javax/jmdns/impl/constants/DNSConstants.java
new file mode 100644
index 0000000..ce9f928
--- /dev/null
+++ b/src/javax/jmdns/impl/constants/DNSConstants.java
@@ -0,0 +1,61 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl.constants;
+
+/**
+ * DNS constants.
+ *
+ * @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Rick Blair
+ */
+public final class DNSConstants {
+    // http://www.iana.org/assignments/dns-parameters
+
+    // changed to final class - jeffs
+    public static final String MDNS_GROUP                     = "224.0.0.251";
+    public static final String MDNS_GROUP_IPV6                = "FF02::FB";
+    public static final int    MDNS_PORT                      = Integer.parseInt(System.getProperty("net.mdns.port", "5353"));
+    public static final int    DNS_PORT                       = 53;
+
+    // One hour expiration time 
+    public static final int    DNS_TTL                        = 25; //60 * 60;
+
+    public static final int    MAX_MSG_TYPICAL                = 1460;
+    public static final int    MAX_MSG_ABSOLUTE               = 8972;
+
+    public static final int    FLAGS_QR_MASK                  = 0x8000;                                                       // Query response mask
+    public static final int    FLAGS_QR_QUERY                 = 0x0000;                                                       // Query
+    public static final int    FLAGS_QR_RESPONSE              = 0x8000;                                                       // Response
+
+    public static final int    FLAGS_AA                       = 0x0400;                                                       // Authorative answer
+    public static final int    FLAGS_TC                       = 0x0200;                                                       // Truncated
+    public static final int    FLAGS_RD                       = 0x0100;                                                       // Recursion desired
+    public static final int    FLAGS_RA                       = 0x8000;                                                       // Recursion available
+
+    public static final int    FLAGS_Z                        = 0x0040;                                                       // Zero
+    public static final int    FLAGS_AD                       = 0x0020;                                                       // Authentic data
+    public static final int    FLAGS_CD                       = 0x0010;                                                       // Checking disabled
+
+    // Time Intervals for various functions
+
+    public static final int    SHARED_QUERY_TIME              = 20;                                                           // milliseconds before send shared query
+    public static final int    QUERY_WAIT_INTERVAL            = 225;                                                          // milliseconds between query loops.
+    public static final int    PROBE_WAIT_INTERVAL            = 250;                                                          // milliseconds between probe loops.
+    public static final int    RESPONSE_MIN_WAIT_INTERVAL     = 20;                                                           // minimal wait interval for response.
+    public static final int    RESPONSE_MAX_WAIT_INTERVAL     = 115;                                                          // maximal wait interval for response
+    public static final int    PROBE_CONFLICT_INTERVAL        = 1000;                                                         // milliseconds to wait after conflict.
+    public static final int    PROBE_THROTTLE_COUNT           = 10;                                                           // After x tries go 1 time a sec. on probes.
+    public static final int    PROBE_THROTTLE_COUNT_INTERVAL  = 5000;                                                         // We only increment the throttle count, if the previous increment is inside this interval.
+    public static final int    ANNOUNCE_WAIT_INTERVAL         = 1000;                                                         // milliseconds between Announce loops.
+    public static final int    RECORD_REAPER_INTERVAL         = 10000;                                                        // milliseconds between cache cleanups.
+    public static final int    RECORD_EXPIRY_DELAY            = 1;                                                            // This is 1s delay used in ttl and therefore in seconds
+    public static final int    KNOWN_ANSWER_TTL               = 120;
+    public static final int    ANNOUNCED_RENEWAL_TTL_INTERVAL = DNS_TTL * 500;                                                // 50% of the TTL in milliseconds
+
+    public static final long   CLOSE_TIMEOUT                  = ANNOUNCE_WAIT_INTERVAL * 5L;
+    public static final long   SERVICE_INFO_TIMEOUT           = ANNOUNCE_WAIT_INTERVAL * 6L;
+
+    public static final int    NETWORK_CHECK_INTERVAL         = 10 * 1000;                                                    // 10 secondes
+
+}
diff --git a/src/javax/jmdns/impl/constants/DNSLabel.java b/src/javax/jmdns/impl/constants/DNSLabel.java
new file mode 100644
index 0000000..4e27f84
--- /dev/null
+++ b/src/javax/jmdns/impl/constants/DNSLabel.java
@@ -0,0 +1,87 @@
+/**
+ *
+ */
+package javax.jmdns.impl.constants;
+
+/**
+ * DNS label.
+ * 
+ * @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Rick Blair
+ */
+public enum DNSLabel {
+    /**
+     * This is unallocated.
+     */
+    Unknown("", 0x80),
+    /**
+     * Standard label [RFC 1035]
+     */
+    Standard("standard label", 0x00),
+    /**
+     * Compressed label [RFC 1035]
+     */
+    Compressed("compressed label", 0xC0),
+    /**
+     * Extended label [RFC 2671]
+     */
+    Extended("extended label", 0x40);
+
+    /**
+     * DNS label types are encoded on the first 2 bits
+     */
+    static final int     LABEL_MASK     = 0xC0;
+    static final int     LABEL_NOT_MASK = 0x3F;
+
+    private final String _externalName;
+
+    private final int    _index;
+
+    DNSLabel(String name, int index) {
+        _externalName = name;
+        _index = index;
+    }
+
+    /**
+     * Return the string representation of this type
+     * 
+     * @return String
+     */
+    public String externalName() {
+        return _externalName;
+    }
+
+    /**
+     * Return the numeric value of this type
+     * 
+     * @return String
+     */
+    public int indexValue() {
+        return _index;
+    }
+
+    /**
+     * @param index
+     * @return label
+     */
+    public static DNSLabel labelForByte(int index) {
+        int maskedIndex = index & LABEL_MASK;
+        for (DNSLabel aLabel : DNSLabel.values()) {
+            if (aLabel._index == maskedIndex) return aLabel;
+        }
+        return Unknown;
+    }
+
+    /**
+     * @param index
+     * @return masked value
+     */
+    public static int labelValue(int index) {
+        return index & LABEL_NOT_MASK;
+    }
+
+    @Override
+    public String toString() {
+        return this.name() + " index " + this.indexValue();
+    }
+
+}
diff --git a/src/javax/jmdns/impl/constants/DNSOperationCode.java b/src/javax/jmdns/impl/constants/DNSOperationCode.java
new file mode 100644
index 0000000..86af38f
--- /dev/null
+++ b/src/javax/jmdns/impl/constants/DNSOperationCode.java
@@ -0,0 +1,86 @@
+/**
+ *
+ */
+package javax.jmdns.impl.constants;
+
+/**
+ * DNS operation code.
+ * 
+ * @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Rick Blair
+ */
+public enum DNSOperationCode {
+    /**
+     * Query [RFC1035]
+     */
+    Query("Query", 0),
+    /**
+     * IQuery (Inverse Query, Obsolete) [RFC3425]
+     */
+    IQuery("Inverse Query", 1),
+    /**
+     * Status [RFC1035]
+     */
+    Status("Status", 2),
+    /**
+     * Unassigned
+     */
+    Unassigned("Unassigned", 3),
+    /**
+     * Notify [RFC1996]
+     */
+    Notify("Notify", 4),
+    /**
+     * Update [RFC2136]
+     */
+    Update("Update", 5);
+
+    /**
+     * DNS RCode types are encoded on the last 4 bits
+     */
+    static final int     OpCode_MASK = 0x7800;
+
+    private final String _externalName;
+
+    private final int    _index;
+
+    DNSOperationCode(String name, int index) {
+        _externalName = name;
+        _index = index;
+    }
+
+    /**
+     * Return the string representation of this type
+     * 
+     * @return String
+     */
+    public String externalName() {
+        return _externalName;
+    }
+
+    /**
+     * Return the numeric value of this type
+     * 
+     * @return String
+     */
+    public int indexValue() {
+        return _index;
+    }
+
+    /**
+     * @param flags
+     * @return label
+     */
+    public static DNSOperationCode operationCodeForFlags(int flags) {
+        int maskedIndex = (flags & OpCode_MASK) >> 11;
+        for (DNSOperationCode aCode : DNSOperationCode.values()) {
+            if (aCode._index == maskedIndex) return aCode;
+        }
+        return Unassigned;
+    }
+
+    @Override
+    public String toString() {
+        return this.name() + " index " + this.indexValue();
+    }
+
+}
diff --git a/src/javax/jmdns/impl/constants/DNSOptionCode.java b/src/javax/jmdns/impl/constants/DNSOptionCode.java
new file mode 100644
index 0000000..d039fac
--- /dev/null
+++ b/src/javax/jmdns/impl/constants/DNSOptionCode.java
@@ -0,0 +1,78 @@
+/**
+ *
+ */
+package javax.jmdns.impl.constants;
+
+/**
+ * DNS option code.
+ * 
+ * @author Arthur van Hoff, Pierre Frisch, Rick Blair
+ */
+public enum DNSOptionCode {
+
+    /**
+     * Token
+     */
+    Unknown("Unknown", 65535),
+    /**
+     * Long-Lived Queries Option [http://files.dns-sd.org/draft-sekar-dns-llq.txt]
+     */
+    LLQ("LLQ", 1),
+    /**
+     * Update Leases Option [http://files.dns-sd.org/draft-sekar-dns-ul.txt]
+     */
+    UL("UL", 2),
+    /**
+     * Name Server Identifier Option [RFC5001]
+     */
+    NSID("NSID", 3),
+    /**
+     * Owner Option [draft-cheshire-edns0-owner-option]
+     */
+    Owner("Owner", 4);
+
+    private final String _externalName;
+
+    private final int    _index;
+
+    DNSOptionCode(String name, int index) {
+        _externalName = name;
+        _index = index;
+    }
+
+    /**
+     * Return the string representation of this type
+     * 
+     * @return String
+     */
+    public String externalName() {
+        return _externalName;
+    }
+
+    /**
+     * Return the numeric value of this type
+     * 
+     * @return String
+     */
+    public int indexValue() {
+        return _index;
+    }
+
+    /**
+     * @param optioncode
+     * @return label
+     */
+    public static DNSOptionCode resultCodeForFlags(int optioncode) {
+        int maskedIndex = optioncode;
+        for (DNSOptionCode aCode : DNSOptionCode.values()) {
+            if (aCode._index == maskedIndex) return aCode;
+        }
+        return Unknown;
+    }
+
+    @Override
+    public String toString() {
+        return this.name() + " index " + this.indexValue();
+    }
+
+}
diff --git a/src/javax/jmdns/impl/constants/DNSRecordClass.java b/src/javax/jmdns/impl/constants/DNSRecordClass.java
new file mode 100644
index 0000000..9fa3745
--- /dev/null
+++ b/src/javax/jmdns/impl/constants/DNSRecordClass.java
@@ -0,0 +1,138 @@
+/**
+ *
+ */
+package javax.jmdns.impl.constants;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * DNS Record Class
+ * 
+ * @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Rick Blair
+ */
+public enum DNSRecordClass {
+    /**
+     *
+     */
+    CLASS_UNKNOWN("?", 0),
+    /**
+     * static final Internet
+     */
+    CLASS_IN("in", 1),
+    /**
+     * CSNET
+     */
+    CLASS_CS("cs", 2),
+    /**
+     * CHAOS
+     */
+    CLASS_CH("ch", 3),
+    /**
+     * Hesiod
+     */
+    CLASS_HS("hs", 4),
+    /**
+     * Used in DNS UPDATE [RFC 2136]
+     */
+    CLASS_NONE("none", 254),
+    /**
+     * Not a DNS class, but a DNS query class, meaning "all classes"
+     */
+    CLASS_ANY("any", 255);
+
+    private static Logger       logger       = Logger.getLogger(DNSRecordClass.class.getName());
+
+    /**
+     * Multicast DNS uses the bottom 15 bits to identify the record class...<br/>
+     * Except for pseudo records like OPT.
+     */
+    public static final int     CLASS_MASK   = 0x7FFF;
+
+    /**
+     * For answers the top bit indicates that all other cached records are now invalid.<br/>
+     * For questions it indicates that we should send a unicast response.
+     */
+    public static final int     CLASS_UNIQUE = 0x8000;
+
+    /**
+     *
+     */
+    public static final boolean UNIQUE       = true;
+
+    /**
+     *
+     */
+    public static final boolean NOT_UNIQUE   = false;
+
+    private final String        _externalName;
+
+    private final int           _index;
+
+    DNSRecordClass(String name, int index) {
+        _externalName = name;
+        _index = index;
+    }
+
+    /**
+     * Return the string representation of this type
+     * 
+     * @return String
+     */
+    public String externalName() {
+        return _externalName;
+    }
+
+    /**
+     * Return the numeric value of this type
+     * 
+     * @return String
+     */
+    public int indexValue() {
+        return _index;
+    }
+
+    /**
+     * Checks if the class is unique
+     * 
+     * @param index
+     * @return <code>true</code> is the class is unique, <code>false</code> otherwise.
+     */
+    public boolean isUnique(int index) {
+        return (this != CLASS_UNKNOWN) && ((index & CLASS_UNIQUE) != 0);
+    }
+
+    /**
+     * @param name
+     * @return class for name
+     */
+    public static DNSRecordClass classForName(String name) {
+        if (name != null) {
+            String aName = name.toLowerCase();
+            for (DNSRecordClass aClass : DNSRecordClass.values()) {
+                if (aClass._externalName.equals(aName)) return aClass;
+            }
+        }
+        logger.log(Level.WARNING, "Could not find record class for name: " + name);
+        return CLASS_UNKNOWN;
+    }
+
+    /**
+     * @param index
+     * @return class for name
+     */
+    public static DNSRecordClass classForIndex(int index) {
+        int maskedIndex = index & CLASS_MASK;
+        for (DNSRecordClass aClass : DNSRecordClass.values()) {
+            if (aClass._index == maskedIndex) return aClass;
+        }
+        logger.log(Level.WARNING, "Could not find record class for index: " + index);
+        return CLASS_UNKNOWN;
+    }
+
+    @Override
+    public String toString() {
+        return this.name() + " index " + this.indexValue();
+    }
+
+}
diff --git a/src/javax/jmdns/impl/constants/DNSRecordType.java b/src/javax/jmdns/impl/constants/DNSRecordType.java
new file mode 100644
index 0000000..e12698c
--- /dev/null
+++ b/src/javax/jmdns/impl/constants/DNSRecordType.java
@@ -0,0 +1,312 @@
+/**
+ *
+ */
+package javax.jmdns.impl.constants;
+
+import java.util.logging.Logger;
+
+/**
+ * DNS Record Type
+ * 
+ * @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Rick Blair
+ */
+public enum DNSRecordType {
+    /**
+     * Address
+     */
+    TYPE_IGNORE("ignore", 0),
+    /**
+     * Address
+     */
+    TYPE_A("a", 1),
+    /**
+     * Name Server
+     */
+    TYPE_NS("ns", 2),
+    /**
+     * Mail Destination
+     */
+    TYPE_MD("md", 3),
+    /**
+     * Mail Forwarder
+     */
+    TYPE_MF("mf", 4),
+    /**
+     * Canonical Name
+     */
+    TYPE_CNAME("cname", 5),
+    /**
+     * Start of Authority
+     */
+    TYPE_SOA("soa", 6),
+    /**
+     * Mailbox
+     */
+    TYPE_MB("mb", 7),
+    /**
+     * Mail Group
+     */
+    TYPE_MG("mg", 8),
+    /**
+     * Mail Rename
+     */
+    TYPE_MR("mr", 9),
+    /**
+     * NULL RR
+     */
+    TYPE_NULL("null", 10),
+    /**
+     * Well-known-service
+     */
+    TYPE_WKS("wks", 11),
+    /**
+     * Domain Name pointer
+     */
+    TYPE_PTR("ptr", 12),
+    /**
+     * Host information
+     */
+    TYPE_HINFO("hinfo", 13),
+    /**
+     * Mailbox information
+     */
+    TYPE_MINFO("minfo", 14),
+    /**
+     * Mail exchanger
+     */
+    TYPE_MX("mx", 15),
+    /**
+     * Arbitrary text string
+     */
+    TYPE_TXT("txt", 16),
+    /**
+     * for Responsible Person [RFC1183]
+     */
+    TYPE_RP("rp", 17),
+    /**
+     * for AFS Data Base location [RFC1183]
+     */
+    TYPE_AFSDB("afsdb", 18),
+    /**
+     * for X.25 PSDN address [RFC1183]
+     */
+    TYPE_X25("x25", 19),
+    /**
+     * for ISDN address [RFC1183]
+     */
+    TYPE_ISDN("isdn", 20),
+    /**
+     * for Route Through [RFC1183]
+     */
+    TYPE_RT("rt", 21),
+    /**
+     * for NSAP address, NSAP style A record [RFC1706]
+     */
+    TYPE_NSAP("nsap", 22),
+    /**
+     *
+     */
+    TYPE_NSAP_PTR("nsap-otr", 23),
+    /**
+     * for security signature [RFC2931]
+     */
+    TYPE_SIG("sig", 24),
+    /**
+     * for security key [RFC2535]
+     */
+    TYPE_KEY("key", 25),
+    /**
+     * X.400 mail mapping information [RFC2163]
+     */
+    TYPE_PX("px", 26),
+    /**
+     * Geographical Position [RFC1712]
+     */
+    TYPE_GPOS("gpos", 27),
+    /**
+     * IP6 Address [Thomson]
+     */
+    TYPE_AAAA("aaaa", 28),
+    /**
+     * Location Information [Vixie]
+     */
+    TYPE_LOC("loc", 29),
+    /**
+     * Next Domain - OBSOLETE [RFC2535, RFC3755]
+     */
+    TYPE_NXT("nxt", 30),
+    /**
+     * Endpoint Identifier [Patton]
+     */
+    TYPE_EID("eid", 31),
+    /**
+     * Nimrod Locator [Patton]
+     */
+    TYPE_NIMLOC("nimloc", 32),
+    /**
+     * Server Selection [RFC2782]
+     */
+    TYPE_SRV("srv", 33),
+    /**
+     * ATM Address [Dobrowski]
+     */
+    TYPE_ATMA("atma", 34),
+    /**
+     * Naming Authority Pointer [RFC2168, RFC2915]
+     */
+    TYPE_NAPTR("naptr", 35),
+    /**
+     * Key Exchanger [RFC2230]
+     */
+    TYPE_KX("kx", 36),
+    /**
+     * CERT [RFC2538]
+     */
+    TYPE_CERT("cert", 37),
+    /**
+     * A6 [RFC2874]
+     */
+    TYPE_A6("a6", 38),
+    /**
+     * DNAME [RFC2672]
+     */
+    TYPE_DNAME("dname", 39),
+    /**
+     * SINK [Eastlake]
+     */
+    TYPE_SINK("sink", 40),
+    /**
+     * OPT [RFC2671]
+     */
+    TYPE_OPT("opt", 41),
+    /**
+     * APL [RFC3123]
+     */
+    TYPE_APL("apl", 42),
+    /**
+     * Delegation Signer [RFC3658]
+     */
+    TYPE_DS("ds", 43),
+    /**
+     * SSH Key Fingerprint [RFC-ietf-secsh-dns-05.txt]
+     */
+    TYPE_SSHFP("sshfp", 44),
+    /**
+     * RRSIG [RFC3755]
+     */
+    TYPE_RRSIG("rrsig", 46),
+    /**
+     * NSEC [RFC3755]
+     */
+    TYPE_NSEC("nsec", 47),
+    /**
+     * DNSKEY [RFC3755]
+     */
+    TYPE_DNSKEY("dnskey", 48),
+    /**
+     * [IANA-Reserved]
+     */
+    TYPE_UINFO("uinfo", 100),
+    /**
+     * [IANA-Reserved]
+     */
+    TYPE_UID("uid", 101),
+    /**
+     * [IANA-Reserved]
+     */
+    TYPE_GID("gid", 102),
+    /**
+     * [IANA-Reserved]
+     */
+    TYPE_UNSPEC("unspec", 103),
+    /**
+     * Transaction Key [RFC2930]
+     */
+    TYPE_TKEY("tkey", 249),
+    /**
+     * Transaction Signature [RFC2845]
+     */
+    TYPE_TSIG("tsig", 250),
+    /**
+     * Incremental transfer [RFC1995]
+     */
+    TYPE_IXFR("ixfr", 251),
+    /**
+     * Transfer of an entire zone [RFC1035]
+     */
+    TYPE_AXFR("axfr", 252),
+    /**
+     * Mailbox-related records (MB, MG or MR) [RFC1035]
+     */
+    TYPE_MAILA("mails", 253),
+    /**
+     * Mail agent RRs (Obsolete - see MX) [RFC1035]
+     */
+    TYPE_MAILB("mailb", 254),
+    /**
+     * Request for all records [RFC1035]
+     */
+    TYPE_ANY("any", 255);
+
+    private static Logger logger = Logger.getLogger(DNSRecordType.class.getName());
+
+    private final String  _externalName;
+
+    private final int     _index;
+
+    DNSRecordType(String name, int index) {
+        _externalName = name;
+        _index = index;
+    }
+
+    /**
+     * Return the string representation of this type
+     * 
+     * @return String
+     */
+    public String externalName() {
+        return _externalName;
+    }
+
+    /**
+     * Return the numeric value of this type
+     * 
+     * @return String
+     */
+    public int indexValue() {
+        return _index;
+    }
+
+    /**
+     * @param name
+     * @return type for name
+     */
+    public static DNSRecordType typeForName(String name) {
+        if (name != null) {
+            String aName = name.toLowerCase();
+            for (DNSRecordType aType : DNSRecordType.values()) {
+                if (aType._externalName.equals(aName)) return aType;
+            }
+        }
+        logger.severe("Could not find record type for name: " + name);
+        return TYPE_IGNORE;
+    }
+
+    /**
+     * @param index
+     * @return type for name
+     */
+    public static DNSRecordType typeForIndex(int index) {
+        for (DNSRecordType aType : DNSRecordType.values()) {
+            if (aType._index == index) return aType;
+        }
+        logger.severe("Could not find record type for index: " + index);
+        return TYPE_IGNORE;
+    }
+
+    @Override
+    public String toString() {
+        return this.name() + " index " + this.indexValue();
+    }
+
+}
diff --git a/src/javax/jmdns/impl/constants/DNSResultCode.java b/src/javax/jmdns/impl/constants/DNSResultCode.java
new file mode 100644
index 0000000..aa089f4
--- /dev/null
+++ b/src/javax/jmdns/impl/constants/DNSResultCode.java
@@ -0,0 +1,149 @@
+/**
+ *
+ */
+package javax.jmdns.impl.constants;
+
+/**
+ * DNS result code.
+ * 
+ * @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Rick Blair
+ */
+public enum DNSResultCode {
+    /**
+     * Token
+     */
+    Unknown("Unknown", 65535),
+    /**
+     * No Error [RFC1035]
+     */
+    NoError("No Error", 0),
+    /**
+     * Format Error [RFC1035]
+     */
+    FormErr("Format Error", 1),
+    /**
+     * Server Failure [RFC1035]
+     */
+    ServFail("Server Failure", 2),
+    /**
+     * Non-Existent Domain [RFC1035]
+     */
+    NXDomain("Non-Existent Domain", 3),
+    /**
+     * Not Implemented [RFC1035]
+     */
+    NotImp("Not Implemented", 4),
+    /**
+     * Query Refused [RFC1035]
+     */
+    Refused("Query Refused", 5),
+    /**
+     * Name Exists when it should not [RFC2136]
+     */
+    YXDomain("Name Exists when it should not", 6),
+    /**
+     * RR Set Exists when it should not [RFC2136]
+     */
+    YXRRSet("RR Set Exists when it should not", 7),
+    /**
+     * RR Set that should exist does not [RFC2136]
+     */
+    NXRRSet("RR Set that should exist does not", 8),
+    /**
+     * Server Not Authoritative for zone [RFC2136]]
+     */
+    NotAuth("Server Not Authoritative for zone", 9),
+    /**
+     * Name not contained in zone [RFC2136]
+     */
+    NotZone("NotZone Name not contained in zone", 10),
+
+    ;
+
+    // 0 NoError No Error [RFC1035]
+    // 1 FormErr Format Error [RFC1035]
+    // 2 ServFail Server Failure [RFC1035]
+    // 3 NXDomain Non-Existent Domain [RFC1035]
+    // 4 NotImp Not Implemented [RFC1035]
+    // 5 Refused Query Refused [RFC1035]
+    // 6 YXDomain Name Exists when it should not [RFC2136]
+    // 7 YXRRSet RR Set Exists when it should not [RFC2136]
+    // 8 NXRRSet RR Set that should exist does not [RFC2136]
+    // 9 NotAuth Server Not Authoritative for zone [RFC2136]
+    // 10 NotZone Name not contained in zone [RFC2136]
+    // 11-15 Unassigned
+    // 16 BADVERS Bad OPT Version [RFC2671]
+    // 16 BADSIG TSIG Signature Failure [RFC2845]
+    // 17 BADKEY Key not recognized [RFC2845]
+    // 18 BADTIME Signature out of time window [RFC2845]
+    // 19 BADMODE Bad TKEY Mode [RFC2930]
+    // 20 BADNAME Duplicate key name [RFC2930]
+    // 21 BADALG Algorithm not supported [RFC2930]
+    // 22 BADTRUNC Bad Truncation [RFC4635]
+    // 23-3840 Unassigned
+    // 3841-4095 Reserved for Private Use [RFC5395]
+    // 4096-65534 Unassigned
+    // 65535 Reserved, can be allocated by Standards Action [RFC5395]
+
+    /**
+     * DNS Result Code types are encoded on the last 4 bits
+     */
+    final static int     RCode_MASK         = 0x0F;
+    /**
+     * DNS Extended Result Code types are encoded on the first 8 bits
+     */
+    final static int     ExtendedRCode_MASK = 0xFF;
+
+    private final String _externalName;
+
+    private final int    _index;
+
+    DNSResultCode(String name, int index) {
+        _externalName = name;
+        _index = index;
+    }
+
+    /**
+     * Return the string representation of this type
+     * 
+     * @return String
+     */
+    public String externalName() {
+        return _externalName;
+    }
+
+    /**
+     * Return the numeric value of this type
+     * 
+     * @return String
+     */
+    public int indexValue() {
+        return _index;
+    }
+
+    /**
+     * @param flags
+     * @return label
+     */
+    public static DNSResultCode resultCodeForFlags(int flags) {
+        int maskedIndex = flags & RCode_MASK;
+        for (DNSResultCode aCode : DNSResultCode.values()) {
+            if (aCode._index == maskedIndex) return aCode;
+        }
+        return Unknown;
+    }
+
+    public static DNSResultCode resultCodeForFlags(int flags, int extendedRCode) {
+        int maskedIndex = ((extendedRCode >> 28) & ExtendedRCode_MASK) | (flags & RCode_MASK);
+        for (DNSResultCode aCode : DNSResultCode.values()) {
+            if (aCode._index == maskedIndex) return aCode;
+        }
+        return Unknown;
+    }
+
+    @Override
+    public String toString() {
+        return this.name() + " index " + this.indexValue();
+    }
+
+}
diff --git a/src/javax/jmdns/impl/constants/DNSState.java b/src/javax/jmdns/impl/constants/DNSState.java
new file mode 100644
index 0000000..8c652f5
--- /dev/null
+++ b/src/javax/jmdns/impl/constants/DNSState.java
@@ -0,0 +1,215 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl.constants;
+
+/**
+ * DNSState defines the possible states for services registered with JmDNS.
+ *
+ * @author Werner Randelshofer, Rick Blair, Pierre Frisch
+ */
+public enum DNSState {
+
+    /**
+     *
+     */
+    PROBING_1("probing 1", StateClass.probing),
+    /**
+    *
+    */
+    PROBING_2("probing 2", StateClass.probing),
+    /**
+    *
+    */
+    PROBING_3("probing 3", StateClass.probing),
+    /**
+    *
+    */
+    ANNOUNCING_1("announcing 1", StateClass.announcing),
+    /**
+    *
+    */
+    ANNOUNCING_2("announcing 2", StateClass.announcing),
+    /**
+    *
+    */
+    ANNOUNCED("announced", StateClass.announced),
+    /**
+    *
+    */
+    CANCELING_1("canceling 1", StateClass.canceling),
+    /**
+    *
+    */
+    CANCELING_2("canceling 2", StateClass.canceling),
+    /**
+    *
+    */
+    CANCELING_3("canceling 3", StateClass.canceling),
+    /**
+    *
+    */
+    CANCELED("canceled", StateClass.canceled),
+    /**
+     *
+     */
+    CLOSING("closing", StateClass.closing),
+    /**
+     *
+     */
+    CLOSED("closed", StateClass.closed);
+
+    private enum StateClass {
+        probing, announcing, announced, canceling, canceled, closing, closed
+    }
+
+    // private static Logger logger = Logger.getLogger(DNSState.class.getName());
+
+    private final String     _name;
+
+    private final StateClass _state;
+
+    private DNSState(String name, StateClass state) {
+        _name = name;
+        _state = state;
+    }
+
+    @Override
+    public final String toString() {
+        return _name;
+    }
+
+    /**
+     * Returns the next advanced state.<br/>
+     * In general, this advances one step in the following sequence: PROBING_1, PROBING_2, PROBING_3, ANNOUNCING_1, ANNOUNCING_2, ANNOUNCED.<br/>
+     * or CANCELING_1, CANCELING_2, CANCELING_3, CANCELED Does not advance for ANNOUNCED and CANCELED state.
+     *
+     * @return next state
+     */
+    public final DNSState advance() {
+        switch (this) {
+            case PROBING_1:
+                return PROBING_2;
+            case PROBING_2:
+                return PROBING_3;
+            case PROBING_3:
+                return ANNOUNCING_1;
+            case ANNOUNCING_1:
+                return ANNOUNCING_2;
+            case ANNOUNCING_2:
+                return ANNOUNCED;
+            case ANNOUNCED:
+                return ANNOUNCED;
+            case CANCELING_1:
+                return CANCELING_2;
+            case CANCELING_2:
+                return CANCELING_3;
+            case CANCELING_3:
+                return CANCELED;
+            case CANCELED:
+                return CANCELED;
+            case CLOSING:
+                return CLOSED;
+            case CLOSED:
+                return CLOSED;
+            default:
+                // This is just to keep the compiler happy as we have covered all cases before.
+                return this;
+        }
+    }
+
+    /**
+     * Returns to the next reverted state. All states except CANCELED revert to PROBING_1. Status CANCELED does not revert.
+     *
+     * @return reverted state
+     */
+    public final DNSState revert() {
+        switch (this) {
+            case PROBING_1:
+            case PROBING_2:
+            case PROBING_3:
+            case ANNOUNCING_1:
+            case ANNOUNCING_2:
+            case ANNOUNCED:
+                return PROBING_1;
+            case CANCELING_1:
+            case CANCELING_2:
+            case CANCELING_3:
+                return CANCELING_1;
+            case CANCELED:
+                return CANCELED;
+            case CLOSING:
+                return CLOSING;
+            case CLOSED:
+                return CLOSED;
+            default:
+                // This is just to keep the compiler happy as we have covered all cases before.
+                return this;
+        }
+    }
+
+    /**
+     * Returns true, if this is a probing state.
+     *
+     * @return <code>true</code> if probing state, <code>false</code> otherwise
+     */
+    public final boolean isProbing() {
+        return _state == StateClass.probing;
+    }
+
+    /**
+     * Returns true, if this is an announcing state.
+     *
+     * @return <code>true</code> if announcing state, <code>false</code> otherwise
+     */
+    public final boolean isAnnouncing() {
+        return _state == StateClass.announcing;
+    }
+
+    /**
+     * Returns true, if this is an announced state.
+     *
+     * @return <code>true</code> if announced state, <code>false</code> otherwise
+     */
+    public final boolean isAnnounced() {
+        return _state == StateClass.announced;
+    }
+
+    /**
+     * Returns true, if this is a canceling state.
+     *
+     * @return <code>true</code> if canceling state, <code>false</code> otherwise
+     */
+    public final boolean isCanceling() {
+        return _state == StateClass.canceling;
+    }
+
+    /**
+     * Returns true, if this is a canceled state.
+     *
+     * @return <code>true</code> if canceled state, <code>false</code> otherwise
+     */
+    public final boolean isCanceled() {
+        return _state == StateClass.canceled;
+    }
+
+    /**
+     * Returns true, if this is a closing state.
+     *
+     * @return <code>true</code> if closing state, <code>false</code> otherwise
+     */
+    public final boolean isClosing() {
+        return _state == StateClass.closing;
+    }
+
+    /**
+     * Returns true, if this is a closing state.
+     *
+     * @return <code>true</code> if closed state, <code>false</code> otherwise
+     */
+    public final boolean isClosed() {
+        return _state == StateClass.closed;
+    }
+
+}
diff --git a/src/javax/jmdns/impl/constants/package-info.java b/src/javax/jmdns/impl/constants/package-info.java
new file mode 100644
index 0000000..240b927
--- /dev/null
+++ b/src/javax/jmdns/impl/constants/package-info.java
@@ -0,0 +1,2 @@
+package javax.jmdns.impl.constants;
+
diff --git a/src/javax/jmdns/impl/package-info.java b/src/javax/jmdns/impl/package-info.java
new file mode 100644
index 0000000..f8b18f4
--- /dev/null
+++ b/src/javax/jmdns/impl/package-info.java
@@ -0,0 +1,2 @@
+package javax.jmdns.impl;
+
diff --git a/src/javax/jmdns/impl/tasks/DNSTask.java b/src/javax/jmdns/impl/tasks/DNSTask.java
new file mode 100644
index 0000000..f7affd5
--- /dev/null
+++ b/src/javax/jmdns/impl/tasks/DNSTask.java
@@ -0,0 +1,223 @@
+// Licensed under Apache License version 2.0
+package javax.jmdns.impl.tasks;
+
+import java.io.IOException;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import javax.jmdns.impl.DNSIncoming;
+import javax.jmdns.impl.DNSOutgoing;
+import javax.jmdns.impl.DNSQuestion;
+import javax.jmdns.impl.DNSRecord;
+import javax.jmdns.impl.JmDNSImpl;
+import javax.jmdns.impl.constants.DNSConstants;
+
+/**
+ * This is the root class for all task scheduled by the timer in JmDNS.
+ * 
+ * @author Pierre Frisch
+ */
+public abstract class DNSTask extends TimerTask {
+
+    /**
+     *
+     */
+    private final JmDNSImpl _jmDNSImpl;
+
+    /**
+     * @param jmDNSImpl
+     */
+    protected DNSTask(JmDNSImpl jmDNSImpl) {
+        super();
+        this._jmDNSImpl = jmDNSImpl;
+    }
+
+    /**
+     * Return the DNS associated with this task.
+     * 
+     * @return associated DNS
+     */
+    public JmDNSImpl getDns() {
+        return _jmDNSImpl;
+    }
+
+    /**
+     * Start this task.
+     * 
+     * @param timer
+     *            task timer.
+     */
+    public abstract void start(Timer timer);
+
+    /**
+     * Return this task name.
+     * 
+     * @return task name
+     */
+    public abstract String getName();
+
+    /*
+     * (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return this.getName();
+    }
+
+    /**
+     * Add a question to the message.
+     * 
+     * @param out
+     *            outgoing message
+     * @param rec
+     *            DNS question
+     * @return outgoing message for the next question
+     * @exception IOException
+     */
+    public DNSOutgoing addQuestion(DNSOutgoing out, DNSQuestion rec) throws IOException {
+        DNSOutgoing newOut = out;
+        try {
+            newOut.addQuestion(rec);
+        } catch (final IOException e) {
+            int flags = newOut.getFlags();
+            boolean multicast = newOut.isMulticast();
+            int maxUDPPayload = newOut.getMaxUDPPayload();
+            int id = newOut.getId();
+
+            newOut.setFlags(flags | DNSConstants.FLAGS_TC);
+            newOut.setId(id);
+            this._jmDNSImpl.send(newOut);
+
+            newOut = new DNSOutgoing(flags, multicast, maxUDPPayload);
+            newOut.addQuestion(rec);
+        }
+        return newOut;
+    }
+
+    /**
+     * Add an answer if it is not suppressed.
+     * 
+     * @param out
+     *            outgoing message
+     * @param in
+     *            incoming request
+     * @param rec
+     *            DNS record answer
+     * @return outgoing message for the next answer
+     * @exception IOException
+     */
+    public DNSOutgoing addAnswer(DNSOutgoing out, DNSIncoming in, DNSRecord rec) throws IOException {
+        DNSOutgoing newOut = out;
+        try {
+            newOut.addAnswer(in, rec);
+        } catch (final IOException e) {
+            int flags = newOut.getFlags();
+            boolean multicast = newOut.isMulticast();
+            int maxUDPPayload = newOut.getMaxUDPPayload();
+            int id = newOut.getId();
+
+            newOut.setFlags(flags | DNSConstants.FLAGS_TC);
+            newOut.setId(id);
+            this._jmDNSImpl.send(newOut);
+
+            newOut = new DNSOutgoing(flags, multicast, maxUDPPayload);
+            newOut.addAnswer(in, rec);
+        }
+        return newOut;
+    }
+
+    /**
+     * Add an answer to the message.
+     * 
+     * @param out
+     *            outgoing message
+     * @param rec
+     *            DNS record answer
+     * @param now
+     * @return outgoing message for the next answer
+     * @exception IOException
+     */
+    public DNSOutgoing addAnswer(DNSOutgoing out, DNSRecord rec, long now) throws IOException {
+        DNSOutgoing newOut = out;
+        try {
+            newOut.addAnswer(rec, now);
+        } catch (final IOException e) {
+            int flags = newOut.getFlags();
+            boolean multicast = newOut.isMulticast();
+            int maxUDPPayload = newOut.getMaxUDPPayload();
+            int id = newOut.getId();
+
+            newOut.setFlags(flags | DNSConstants.FLAGS_TC);
+            newOut.setId(id);
+            this._jmDNSImpl.send(newOut);
+
+            newOut = new DNSOutgoing(flags, multicast, maxUDPPayload);
+            newOut.addAnswer(rec, now);
+        }
+        return newOut;
+    }
+
+    /**
+     * Add an authoritative answer to the message.
+     * 
+     * @param out
+     *            outgoing message
+     * @param rec
+     *            DNS record answer
+     * @return outgoing message for the next answer
+     * @exception IOException
+     */
+    public DNSOutgoing addAuthoritativeAnswer(DNSOutgoing out, DNSRecord rec) throws IOException {
+        DNSOutgoing newOut = out;
+        try {
+            newOut.addAuthorativeAnswer(rec);
+        } catch (final IOException e) {
+            int flags = newOut.getFlags();
+            boolean multicast = newOut.isMulticast();
+            int maxUDPPayload = newOut.getMaxUDPPayload();
+            int id = newOut.getId();
+
+            newOut.setFlags(flags | DNSConstants.FLAGS_TC);
+            newOut.setId(id);
+            this._jmDNSImpl.send(newOut);
+
+            newOut = new DNSOutgoing(flags, multicast, maxUDPPayload);
+            newOut.addAuthorativeAnswer(rec);
+        }
+        return newOut;
+    }
+
+    /**
+     * Add an additional answer to the record. Omit if there is no room.
+     * 
+     * @param out
+     *            outgoing message
+     * @param in
+     *            incoming request
+     * @param rec
+     *            DNS record answer
+     * @return outgoing message for the next answer
+     * @exception IOException
+     */
+    public DNSOutgoing addAdditionalAnswer(DNSOutgoing out, DNSIncoming in, DNSRecord rec) throws IOException {
+        DNSOutgoing newOut = out;
+        try {
+            newOut.addAdditionalAnswer(in, rec);
+        } catch (final IOException e) {
+            int flags = newOut.getFlags();
+            boolean multicast = newOut.isMulticast();
+            int maxUDPPayload = newOut.getMaxUDPPayload();
+            int id = newOut.getId();
+
+            newOut.setFlags(flags | DNSConstants.FLAGS_TC);
+            newOut.setId(id);
+            this._jmDNSImpl.send(newOut);
+
+            newOut = new DNSOutgoing(flags, multicast, maxUDPPayload);
+            newOut.addAdditionalAnswer(in, rec);
+        }
+        return newOut;
+    }
+
+}
diff --git a/src/javax/jmdns/impl/tasks/RecordReaper.java b/src/javax/jmdns/impl/tasks/RecordReaper.java
new file mode 100644
index 0000000..75dd0ef
--- /dev/null
+++ b/src/javax/jmdns/impl/tasks/RecordReaper.java
@@ -0,0 +1,61 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl.tasks;
+
+import java.util.Timer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.jmdns.impl.JmDNSImpl;
+import javax.jmdns.impl.constants.DNSConstants;
+
+/**
+ * Periodically removes expired entries from the cache.
+ */
+public class RecordReaper extends DNSTask {
+    static Logger logger = Logger.getLogger(RecordReaper.class.getName());
+
+    /**
+     * @param jmDNSImpl
+     */
+    public RecordReaper(JmDNSImpl jmDNSImpl) {
+        super(jmDNSImpl);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.DNSTask#getName()
+     */
+    @Override
+    public String getName() {
+        return "RecordReaper(" + (this.getDns() != null ? this.getDns().getName() : "") + ")";
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.DNSTask#start(java.util.Timer)
+     */
+    @Override
+    public void start(Timer timer) {
+        if (!this.getDns().isCanceling() && !this.getDns().isCanceled()) {
+            timer.schedule(this, DNSConstants.RECORD_REAPER_INTERVAL, DNSConstants.RECORD_REAPER_INTERVAL);
+        }
+    }
+
+    @Override
+    public void run() {
+        if (this.getDns().isCanceling() || this.getDns().isCanceled()) {
+            return;
+        }
+        if (logger.isLoggable(Level.FINEST)) {
+            logger.finest(this.getName() + ".run() JmDNS reaping cache");
+        }
+
+        // Remove expired answers from the cache
+        // -------------------------------------
+        this.getDns().cleanCache();
+    }
+
+}
\ No newline at end of file
diff --git a/src/javax/jmdns/impl/tasks/Responder.java b/src/javax/jmdns/impl/tasks/Responder.java
new file mode 100644
index 0000000..1fbbe75
--- /dev/null
+++ b/src/javax/jmdns/impl/tasks/Responder.java
@@ -0,0 +1,157 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl.tasks;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Timer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.jmdns.impl.DNSIncoming;
+import javax.jmdns.impl.DNSOutgoing;
+import javax.jmdns.impl.DNSQuestion;
+import javax.jmdns.impl.DNSRecord;
+import javax.jmdns.impl.JmDNSImpl;
+import javax.jmdns.impl.constants.DNSConstants;
+
+/**
+ * The Responder sends a single answer for the specified service infos and for the host name.
+ */
+public class Responder extends DNSTask {
+    static Logger             logger = Logger.getLogger(Responder.class.getName());
+
+    /**
+     *
+     */
+    private final DNSIncoming _in;
+
+    /**
+     *
+     */
+    private final boolean     _unicast;
+
+    public Responder(JmDNSImpl jmDNSImpl, DNSIncoming in, int port) {
+        super(jmDNSImpl);
+        this._in = in;
+        this._unicast = (port != DNSConstants.MDNS_PORT);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.DNSTask#getName()
+     */
+    @Override
+    public String getName() {
+        return "Responder(" + (this.getDns() != null ? this.getDns().getName() : "") + ")";
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return super.toString() + " incomming: " + _in;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.DNSTask#start(java.util.Timer)
+     */
+    @Override
+    public void start(Timer timer) {
+        // According to draft-cheshire-dnsext-multicastdns.txt chapter "7 Responding":
+        // We respond immediately if we know for sure, that we are the only one who can respond to the query.
+        // In all other cases, we respond within 20-120 ms.
+        //
+        // According to draft-cheshire-dnsext-multicastdns.txt chapter "6.2 Multi-Packet Known Answer Suppression":
+        // We respond after 20-120 ms if the query is truncated.
+
+        boolean iAmTheOnlyOne = true;
+        for (DNSQuestion question : _in.getQuestions()) {
+            if (logger.isLoggable(Level.FINEST)) {
+                logger.finest(this.getName() + "start() question=" + question);
+            }
+            iAmTheOnlyOne = question.iAmTheOnlyOne(this.getDns());
+            if (!iAmTheOnlyOne) {
+                break;
+            }
+        }
+        int delay = (iAmTheOnlyOne && !_in.isTruncated()) ? 0 : DNSConstants.RESPONSE_MIN_WAIT_INTERVAL + JmDNSImpl.getRandom().nextInt(DNSConstants.RESPONSE_MAX_WAIT_INTERVAL - DNSConstants.RESPONSE_MIN_WAIT_INTERVAL + 1) - _in.elapseSinceArrival();
+        if (delay < 0) {
+            delay = 0;
+        }
+        if (logger.isLoggable(Level.FINEST)) {
+            logger.finest(this.getName() + "start() Responder chosen delay=" + delay);
+        }
+        if (!this.getDns().isCanceling() && !this.getDns().isCanceled()) {
+            timer.schedule(this, delay);
+        }
+    }
+
+    @Override
+    public void run() {
+        this.getDns().respondToQuery(_in);
+
+        // We use these sets to prevent duplicate records
+        Set<DNSQuestion> questions = new HashSet<DNSQuestion>();
+        Set<DNSRecord> answers = new HashSet<DNSRecord>();
+
+        if (this.getDns().isAnnounced()) {
+            try {
+                // Answer questions
+                for (DNSQuestion question : _in.getQuestions()) {
+                    if (logger.isLoggable(Level.FINER)) {
+                        logger.finer(this.getName() + "run() JmDNS responding to: " + question);
+                    }
+                    // for unicast responses the question must be included
+                    if (_unicast) {
+                        // out.addQuestion(q);
+                        questions.add(question);
+                    }
+
+                    question.addAnswers(this.getDns(), answers);
+                }
+
+                // remove known answers, if the ttl is at least half of the correct value. (See Draft Cheshire chapter 7.1.).
+                long now = System.currentTimeMillis();
+                for (DNSRecord knownAnswer : _in.getAnswers()) {
+                    if (knownAnswer.isStale(now)) {
+                        answers.remove(knownAnswer);
+                        if (logger.isLoggable(Level.FINER)) {
+                            logger.finer(this.getName() + "JmDNS Responder Known Answer Removed");
+                        }
+                    }
+                }
+
+                // respond if we have answers
+                if (!answers.isEmpty()) {
+                    if (logger.isLoggable(Level.FINER)) {
+                        logger.finer(this.getName() + "run() JmDNS responding");
+                    }
+                    DNSOutgoing out = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA, !_unicast, _in.getSenderUDPPayload());
+                    out.setId(_in.getId());
+                    for (DNSQuestion question : questions) {
+                        if (question != null) {
+                            out = this.addQuestion(out, question);
+                        }
+                    }
+                    for (DNSRecord answer : answers) {
+                        if (answer != null) {
+                            out = this.addAnswer(out, _in, answer);
+
+                        }
+                    }
+                    if (!out.isEmpty()) this.getDns().send(out);
+                }
+                // this.cancel();
+            } catch (Throwable e) {
+                logger.log(Level.WARNING, this.getName() + "run() exception ", e);
+                this.getDns().close();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/javax/jmdns/impl/tasks/package-info.java b/src/javax/jmdns/impl/tasks/package-info.java
new file mode 100644
index 0000000..b8435ea
--- /dev/null
+++ b/src/javax/jmdns/impl/tasks/package-info.java
@@ -0,0 +1,2 @@
+package javax.jmdns.impl.tasks;
+
diff --git a/src/javax/jmdns/impl/tasks/resolver/DNSResolverTask.java b/src/javax/jmdns/impl/tasks/resolver/DNSResolverTask.java
new file mode 100644
index 0000000..7fa7abb
--- /dev/null
+++ b/src/javax/jmdns/impl/tasks/resolver/DNSResolverTask.java
@@ -0,0 +1,116 @@
+// Licensed under Apache License version 2.0
+package javax.jmdns.impl.tasks.resolver;
+
+import java.io.IOException;
+import java.util.Timer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.jmdns.impl.DNSOutgoing;
+import javax.jmdns.impl.JmDNSImpl;
+import javax.jmdns.impl.constants.DNSConstants;
+import javax.jmdns.impl.tasks.DNSTask;
+
+/**
+ * This is the root class for all resolver tasks.
+ * 
+ * @author Pierre Frisch
+ */
+public abstract class DNSResolverTask extends DNSTask {
+    private static Logger logger = Logger.getLogger(DNSResolverTask.class.getName());
+
+    /**
+     * Counts the number of queries being sent.
+     */
+    protected int         _count = 0;
+
+    /**
+     * @param jmDNSImpl
+     */
+    public DNSResolverTask(JmDNSImpl jmDNSImpl) {
+        super(jmDNSImpl);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return super.toString() + " count: " + _count;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.DNSTask#start(java.util.Timer)
+     */
+    @Override
+    public void start(Timer timer) {
+        if (!this.getDns().isCanceling() && !this.getDns().isCanceled()) {
+            timer.schedule(this, DNSConstants.QUERY_WAIT_INTERVAL, DNSConstants.QUERY_WAIT_INTERVAL);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see java.util.TimerTask#run()
+     */
+    @Override
+    public void run() {
+        try {
+            if (this.getDns().isCanceling() || this.getDns().isCanceled()) {
+                this.cancel();
+            } else {
+                if (_count++ < 3) {
+                    if (logger.isLoggable(Level.FINER)) {
+                        logger.finer(this.getName() + ".run() JmDNS " + this.description());
+                    }
+                    DNSOutgoing out = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY);
+                    out = this.addQuestions(out);
+                    if (this.getDns().isAnnounced()) {
+                        out = this.addAnswers(out);
+                    }
+                    if (!out.isEmpty()) {
+                        this.getDns().send(out);
+                    }
+                } else {
+                    // After three queries, we can quit.
+                    this.cancel();
+                }
+            }
+        } catch (Throwable e) {
+            logger.log(Level.WARNING, this.getName() + ".run() exception ", e);
+            this.getDns().recover();
+        }
+    }
+
+    /**
+     * Overridden by subclasses to add questions to the message.<br/>
+     * <b>Note:</b> Because of message size limitation the returned message may be different than the message parameter.
+     * 
+     * @param out
+     *            outgoing message
+     * @return the outgoing message.
+     * @exception IOException
+     */
+    protected abstract DNSOutgoing addQuestions(DNSOutgoing out) throws IOException;
+
+    /**
+     * Overridden by subclasses to add questions to the message.<br/>
+     * <b>Note:</b> Because of message size limitation the returned message may be different than the message parameter.
+     * 
+     * @param out
+     *            outgoing message
+     * @return the outgoing message.
+     * @exception IOException
+     */
+    protected abstract DNSOutgoing addAnswers(DNSOutgoing out) throws IOException;
+
+    /**
+     * Returns a description of the resolver for debugging
+     * 
+     * @return resolver description
+     */
+    protected abstract String description();
+
+}
diff --git a/src/javax/jmdns/impl/tasks/resolver/ServiceInfoResolver.java b/src/javax/jmdns/impl/tasks/resolver/ServiceInfoResolver.java
new file mode 100644
index 0000000..3147efd
--- /dev/null
+++ b/src/javax/jmdns/impl/tasks/resolver/ServiceInfoResolver.java
@@ -0,0 +1,102 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl.tasks.resolver;
+
+import java.io.IOException;
+
+import javax.jmdns.impl.DNSOutgoing;
+import javax.jmdns.impl.DNSQuestion;
+import javax.jmdns.impl.DNSRecord;
+import javax.jmdns.impl.JmDNSImpl;
+import javax.jmdns.impl.ServiceInfoImpl;
+import javax.jmdns.impl.constants.DNSRecordClass;
+import javax.jmdns.impl.constants.DNSRecordType;
+
+/**
+ * The ServiceInfoResolver queries up to three times consecutively for a service info, and then removes itself from the timer.
+ * <p/>
+ * The ServiceInfoResolver will run only if JmDNS is in state ANNOUNCED. REMIND: Prevent having multiple service resolvers for the same info in the timer queue.
+ */
+public class ServiceInfoResolver extends DNSResolverTask {
+
+    private final ServiceInfoImpl _info;
+
+    public ServiceInfoResolver(JmDNSImpl jmDNSImpl, ServiceInfoImpl info) {
+        super(jmDNSImpl);
+        this._info = info;
+        info.setDns(this.getDns());
+        this.getDns().addListener(info, DNSQuestion.newQuestion(info.getQualifiedName(), DNSRecordType.TYPE_ANY, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.DNSTask#getName()
+     */
+    @Override
+    public String getName() {
+        return "ServiceInfoResolver(" + (this.getDns() != null ? this.getDns().getName() : "") + ")";
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see java.util.TimerTask#cancel()
+     */
+    @Override
+    public boolean cancel() {
+        // We should not forget to remove the listener
+        boolean result = super.cancel();
+        if (!_info.isPersistent()) {
+            this.getDns().removeListener(_info);
+        }
+        return result;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.Resolver#addAnswers(javax.jmdns.impl.DNSOutgoing)
+     */
+    @Override
+    protected DNSOutgoing addAnswers(DNSOutgoing out) throws IOException {
+        DNSOutgoing newOut = out;
+        if (!_info.hasData()) {
+            long now = System.currentTimeMillis();
+            newOut = this.addAnswer(newOut, (DNSRecord) this.getDns().getCache().getDNSEntry(_info.getQualifiedName(), DNSRecordType.TYPE_SRV, DNSRecordClass.CLASS_IN), now);
+            newOut = this.addAnswer(newOut, (DNSRecord) this.getDns().getCache().getDNSEntry(_info.getQualifiedName(), DNSRecordType.TYPE_TXT, DNSRecordClass.CLASS_IN), now);
+            if (_info.getServer().length() > 0) {
+                newOut = this.addAnswer(newOut, (DNSRecord) this.getDns().getCache().getDNSEntry(_info.getServer(), DNSRecordType.TYPE_A, DNSRecordClass.CLASS_IN), now);
+                newOut = this.addAnswer(newOut, (DNSRecord) this.getDns().getCache().getDNSEntry(_info.getServer(), DNSRecordType.TYPE_AAAA, DNSRecordClass.CLASS_IN), now);
+            }
+        }
+        return newOut;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.Resolver#addQuestions(javax.jmdns.impl.DNSOutgoing)
+     */
+    @Override
+    protected DNSOutgoing addQuestions(DNSOutgoing out) throws IOException {
+        DNSOutgoing newOut = out;
+        if (!_info.hasData()) {
+            newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_info.getQualifiedName(), DNSRecordType.TYPE_SRV, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
+            newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_info.getQualifiedName(), DNSRecordType.TYPE_TXT, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
+            if (_info.getServer().length() > 0) {
+                newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_info.getServer(), DNSRecordType.TYPE_A, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
+                newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_info.getServer(), DNSRecordType.TYPE_AAAA, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
+            }
+        }
+        return newOut;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.Resolver#description()
+     */
+    @Override
+    protected String description() {
+        return "querying service info: " + (_info != null ? _info.getQualifiedName() : "null");
+    }
+
+}
\ No newline at end of file
diff --git a/src/javax/jmdns/impl/tasks/resolver/ServiceResolver.java b/src/javax/jmdns/impl/tasks/resolver/ServiceResolver.java
new file mode 100644
index 0000000..ae7dee5
--- /dev/null
+++ b/src/javax/jmdns/impl/tasks/resolver/ServiceResolver.java
@@ -0,0 +1,77 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl.tasks.resolver;
+
+import java.io.IOException;
+
+import javax.jmdns.ServiceInfo;
+import javax.jmdns.impl.DNSOutgoing;
+import javax.jmdns.impl.DNSQuestion;
+import javax.jmdns.impl.DNSRecord;
+import javax.jmdns.impl.JmDNSImpl;
+import javax.jmdns.impl.constants.DNSConstants;
+import javax.jmdns.impl.constants.DNSRecordClass;
+import javax.jmdns.impl.constants.DNSRecordType;
+
+/**
+ * The ServiceResolver queries three times consecutively for services of a given type, and then removes itself from the timer.
+ * <p/>
+ * The ServiceResolver will run only if JmDNS is in state ANNOUNCED. REMIND: Prevent having multiple service resolvers for the same type in the timer queue.
+ */
+public class ServiceResolver extends DNSResolverTask {
+
+    private final String _type;
+
+    public ServiceResolver(JmDNSImpl jmDNSImpl, String type) {
+        super(jmDNSImpl);
+        this._type = type;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.DNSTask#getName()
+     */
+    @Override
+    public String getName() {
+        return "ServiceResolver(" + (this.getDns() != null ? this.getDns().getName() : "") + ")";
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.Resolver#addAnswers(javax.jmdns.impl.DNSOutgoing)
+     */
+    @Override
+    protected DNSOutgoing addAnswers(DNSOutgoing out) throws IOException {
+        DNSOutgoing newOut = out;
+        long now = System.currentTimeMillis();
+        for (ServiceInfo info : this.getDns().getServices().values()) {
+            newOut = this.addAnswer(newOut, new DNSRecord.Pointer(info.getType(), DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE, DNSConstants.DNS_TTL, info.getQualifiedName()), now);
+            // newOut = this.addAnswer(newOut, new DNSRecord.Service(info.getQualifiedName(), DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE, DNSConstants.DNS_TTL, info.getPriority(), info.getWeight(), info.getPort(),
+            // this.getDns().getLocalHost().getName()), now);
+        }
+        return newOut;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.Resolver#addQuestions(javax.jmdns.impl.DNSOutgoing)
+     */
+    @Override
+    protected DNSOutgoing addQuestions(DNSOutgoing out) throws IOException {
+        DNSOutgoing newOut = out;
+        newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_type, DNSRecordType.TYPE_PTR, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
+        // newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_type, DNSRecordType.TYPE_SRV, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
+        return newOut;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.Resolver#description()
+     */
+    @Override
+    protected String description() {
+        return "querying service";
+    }
+}
\ No newline at end of file
diff --git a/src/javax/jmdns/impl/tasks/resolver/TypeResolver.java b/src/javax/jmdns/impl/tasks/resolver/TypeResolver.java
new file mode 100644
index 0000000..8382e54
--- /dev/null
+++ b/src/javax/jmdns/impl/tasks/resolver/TypeResolver.java
@@ -0,0 +1,75 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl.tasks.resolver;
+
+import java.io.IOException;
+
+import javax.jmdns.impl.DNSOutgoing;
+import javax.jmdns.impl.DNSQuestion;
+import javax.jmdns.impl.DNSRecord;
+import javax.jmdns.impl.JmDNSImpl;
+import javax.jmdns.impl.JmDNSImpl.ServiceTypeEntry;
+import javax.jmdns.impl.constants.DNSConstants;
+import javax.jmdns.impl.constants.DNSRecordClass;
+import javax.jmdns.impl.constants.DNSRecordType;
+
+/**
+ * Helper class to resolve service types.
+ * <p/>
+ * The TypeResolver queries three times consecutively for service types, and then removes itself from the timer.
+ * <p/>
+ * The TypeResolver will run only if JmDNS is in state ANNOUNCED.
+ */
+public class TypeResolver extends DNSResolverTask {
+
+    /**
+     * @param jmDNSImpl
+     */
+    public TypeResolver(JmDNSImpl jmDNSImpl) {
+        super(jmDNSImpl);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.DNSTask#getName()
+     */
+    @Override
+    public String getName() {
+        return "TypeResolver(" + (this.getDns() != null ? this.getDns().getName() : "") + ")";
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.Resolver#addAnswers(javax.jmdns.impl.DNSOutgoing)
+     */
+    @Override
+    protected DNSOutgoing addAnswers(DNSOutgoing out) throws IOException {
+        DNSOutgoing newOut = out;
+        long now = System.currentTimeMillis();
+        for (String type : this.getDns().getServiceTypes().keySet()) {
+            ServiceTypeEntry typeEntry = this.getDns().getServiceTypes().get(type);
+            newOut = this.addAnswer(newOut, new DNSRecord.Pointer("_services._dns-sd._udp.local.", DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE, DNSConstants.DNS_TTL, typeEntry.getType()), now);
+        }
+        return newOut;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.Resolver#addQuestions(javax.jmdns.impl.DNSOutgoing)
+     */
+    @Override
+    protected DNSOutgoing addQuestions(DNSOutgoing out) throws IOException {
+        return this.addQuestion(out, DNSQuestion.newQuestion("_services._dns-sd._udp.local.", DNSRecordType.TYPE_PTR, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.Resolver#description()
+     */
+    @Override
+    protected String description() {
+        return "querying type";
+    }
+}
\ No newline at end of file
diff --git a/src/javax/jmdns/impl/tasks/resolver/package-info.java b/src/javax/jmdns/impl/tasks/resolver/package-info.java
new file mode 100644
index 0000000..9fada6a
--- /dev/null
+++ b/src/javax/jmdns/impl/tasks/resolver/package-info.java
@@ -0,0 +1,2 @@
+package javax.jmdns.impl.tasks.resolver;
+
diff --git a/src/javax/jmdns/impl/tasks/state/Announcer.java b/src/javax/jmdns/impl/tasks/state/Announcer.java
new file mode 100644
index 0000000..aff60f7
--- /dev/null
+++ b/src/javax/jmdns/impl/tasks/state/Announcer.java
@@ -0,0 +1,146 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl.tasks.state;
+
+import java.io.IOException;
+import java.util.Timer;
+import java.util.logging.Logger;
+
+import javax.jmdns.impl.DNSOutgoing;
+import javax.jmdns.impl.DNSRecord;
+import javax.jmdns.impl.JmDNSImpl;
+import javax.jmdns.impl.ServiceInfoImpl;
+import javax.jmdns.impl.constants.DNSConstants;
+import javax.jmdns.impl.constants.DNSRecordClass;
+import javax.jmdns.impl.constants.DNSState;
+
+/**
+ * The Announcer sends an accumulated query of all announces, and advances the state of all serviceInfos, for which it has sent an announce. The Announcer also sends announcements and advances the state of JmDNS itself.
+ * <p/>
+ * When the announcer has run two times, it finishes.
+ */
+public class Announcer extends DNSStateTask {
+    static Logger logger = Logger.getLogger(Announcer.class.getName());
+
+    public Announcer(JmDNSImpl jmDNSImpl) {
+        super(jmDNSImpl, defaultTTL());
+
+        this.setTaskState(DNSState.ANNOUNCING_1);
+        this.associate(DNSState.ANNOUNCING_1);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.DNSTask#getName()
+     */
+    @Override
+    public String getName() {
+        return "Announcer(" + (this.getDns() != null ? this.getDns().getName() : "") + ")";
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return super.toString() + " state: " + this.getTaskState();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.DNSTask#start(java.util.Timer)
+     */
+    @Override
+    public void start(Timer timer) {
+        if (!this.getDns().isCanceling() && !this.getDns().isCanceled()) {
+            timer.schedule(this, DNSConstants.ANNOUNCE_WAIT_INTERVAL, DNSConstants.ANNOUNCE_WAIT_INTERVAL);
+        }
+    }
+
+    @Override
+    public boolean cancel() {
+        this.removeAssociation();
+
+        return super.cancel();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#getTaskDescription()
+     */
+    @Override
+    public String getTaskDescription() {
+        return "announcing";
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#checkRunCondition()
+     */
+    @Override
+    protected boolean checkRunCondition() {
+        return !this.getDns().isCanceling() && !this.getDns().isCanceled();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#createOugoing()
+     */
+    @Override
+    protected DNSOutgoing createOugoing() {
+        return new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#buildOutgoingForDNS(javax.jmdns.impl.DNSOutgoing)
+     */
+    @Override
+    protected DNSOutgoing buildOutgoingForDNS(DNSOutgoing out) throws IOException {
+        DNSOutgoing newOut = out;
+        for (DNSRecord answer : this.getDns().getLocalHost().answers(DNSRecordClass.UNIQUE, this.getTTL())) {
+            newOut = this.addAnswer(newOut, null, answer);
+        }
+        return newOut;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#buildOutgoingForInfo(javax.jmdns.impl.ServiceInfoImpl, javax.jmdns.impl.DNSOutgoing)
+     */
+    @Override
+    protected DNSOutgoing buildOutgoingForInfo(ServiceInfoImpl info, DNSOutgoing out) throws IOException {
+        DNSOutgoing newOut = out;
+        for (DNSRecord answer : info.answers(DNSRecordClass.UNIQUE, this.getTTL(), this.getDns().getLocalHost())) {
+            newOut = this.addAnswer(newOut, null, answer);
+        }
+        return newOut;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#recoverTask(java.lang.Throwable)
+     */
+    @Override
+    protected void recoverTask(Throwable e) {
+        this.getDns().recover();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#advanceTask()
+     */
+    @Override
+    protected void advanceTask() {
+        this.setTaskState(this.getTaskState().advance());
+        if (!this.getTaskState().isAnnouncing()) {
+            this.cancel();
+
+            this.getDns().startRenewer();
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/src/javax/jmdns/impl/tasks/state/Canceler.java b/src/javax/jmdns/impl/tasks/state/Canceler.java
new file mode 100644
index 0000000..50cf316
--- /dev/null
+++ b/src/javax/jmdns/impl/tasks/state/Canceler.java
@@ -0,0 +1,143 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl.tasks.state;
+
+import java.io.IOException;
+import java.util.Timer;
+import java.util.logging.Logger;
+
+import javax.jmdns.impl.DNSOutgoing;
+import javax.jmdns.impl.DNSRecord;
+import javax.jmdns.impl.JmDNSImpl;
+import javax.jmdns.impl.ServiceInfoImpl;
+import javax.jmdns.impl.constants.DNSConstants;
+import javax.jmdns.impl.constants.DNSRecordClass;
+import javax.jmdns.impl.constants.DNSState;
+
+/**
+ * The Canceler sends two announces with TTL=0 for the specified services.
+ */
+public class Canceler extends DNSStateTask {
+    static Logger logger = Logger.getLogger(Canceler.class.getName());
+
+    public Canceler(JmDNSImpl jmDNSImpl) {
+        super(jmDNSImpl, 0);
+
+        this.setTaskState(DNSState.CANCELING_1);
+        this.associate(DNSState.CANCELING_1);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.DNSTask#getName()
+     */
+    @Override
+    public String getName() {
+        return "Canceler(" + (this.getDns() != null ? this.getDns().getName() : "") + ")";
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return super.toString() + " state: " + this.getTaskState();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.DNSTask#start(java.util.Timer)
+     */
+    @Override
+    public void start(Timer timer) {
+        timer.schedule(this, 0, DNSConstants.ANNOUNCE_WAIT_INTERVAL);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see java.util.TimerTask#cancel()
+     */
+    @Override
+    public boolean cancel() {
+        this.removeAssociation();
+
+        return super.cancel();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#getTaskDescription()
+     */
+    @Override
+    public String getTaskDescription() {
+        return "canceling";
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#checkRunCondition()
+     */
+    @Override
+    protected boolean checkRunCondition() {
+        return true;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#createOugoing()
+     */
+    @Override
+    protected DNSOutgoing createOugoing() {
+        return new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#buildOutgoingForDNS(javax.jmdns.impl.DNSOutgoing)
+     */
+    @Override
+    protected DNSOutgoing buildOutgoingForDNS(DNSOutgoing out) throws IOException {
+        DNSOutgoing newOut = out;
+        for (DNSRecord answer : this.getDns().getLocalHost().answers(DNSRecordClass.UNIQUE, this.getTTL())) {
+            newOut = this.addAnswer(newOut, null, answer);
+        }
+        return newOut;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#buildOutgoingForInfo(javax.jmdns.impl.ServiceInfoImpl, javax.jmdns.impl.DNSOutgoing)
+     */
+    @Override
+    protected DNSOutgoing buildOutgoingForInfo(ServiceInfoImpl info, DNSOutgoing out) throws IOException {
+        DNSOutgoing newOut = out;
+        for (DNSRecord answer : info.answers(DNSRecordClass.UNIQUE, this.getTTL(), this.getDns().getLocalHost())) {
+            newOut = this.addAnswer(newOut, null, answer);
+        }
+        return newOut;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#recoverTask(java.lang.Throwable)
+     */
+    @Override
+    protected void recoverTask(Throwable e) {
+        this.getDns().recover();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#advanceTask()
+     */
+    @Override
+    protected void advanceTask() {
+        this.setTaskState(this.getTaskState().advance());
+        if (!this.getTaskState().isCanceling()) {
+            cancel();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/javax/jmdns/impl/tasks/state/DNSStateTask.java b/src/javax/jmdns/impl/tasks/state/DNSStateTask.java
new file mode 100644
index 0000000..a0896d9
--- /dev/null
+++ b/src/javax/jmdns/impl/tasks/state/DNSStateTask.java
@@ -0,0 +1,188 @@
+// Licensed under Apache License version 2.0
+package javax.jmdns.impl.tasks.state;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.jmdns.ServiceInfo;
+import javax.jmdns.impl.DNSOutgoing;
+import javax.jmdns.impl.DNSStatefulObject;
+import javax.jmdns.impl.JmDNSImpl;
+import javax.jmdns.impl.ServiceInfoImpl;
+import javax.jmdns.impl.constants.DNSConstants;
+import javax.jmdns.impl.constants.DNSState;
+import javax.jmdns.impl.tasks.DNSTask;
+
+/**
+ * This is the root class for all state tasks. These tasks work with objects that implements the {@link javax.jmdns.impl.DNSStatefulObject} interface and therefore participate in the state machine.
+ * 
+ * @author Pierre Frisch
+ */
+public abstract class DNSStateTask extends DNSTask {
+    static Logger      logger1     = Logger.getLogger(DNSStateTask.class.getName());
+
+    /**
+     * By setting a 0 ttl we effectively expire the record.
+     */
+    private final int  _ttl;
+
+    private static int _defaultTTL = DNSConstants.DNS_TTL;
+
+    /**
+     * The state of the task.
+     */
+    private DNSState   _taskState  = null;
+
+    public abstract String getTaskDescription();
+
+    public static int defaultTTL() {
+        return _defaultTTL;
+    }
+
+    /**
+     * For testing only do not use in production.
+     * 
+     * @param value
+     */
+    public static void setDefaultTTL(int value) {
+        _defaultTTL = value;
+    }
+
+    /**
+     * @param jmDNSImpl
+     * @param ttl
+     */
+    public DNSStateTask(JmDNSImpl jmDNSImpl, int ttl) {
+        super(jmDNSImpl);
+        _ttl = ttl;
+    }
+
+    /**
+     * @return the ttl
+     */
+    public int getTTL() {
+        return _ttl;
+    }
+
+    /**
+     * Associate the DNS host and the service infos with this task if not already associated and in the same state.
+     * 
+     * @param state
+     *            target state
+     */
+    protected void associate(DNSState state) {
+        synchronized (this.getDns()) {
+            this.getDns().associateWithTask(this, state);
+        }
+        for (ServiceInfo serviceInfo : this.getDns().getServices().values()) {
+            ((ServiceInfoImpl) serviceInfo).associateWithTask(this, state);
+        }
+    }
+
+    /**
+     * Remove the DNS host and service info association with this task.
+     */
+    protected void removeAssociation() {
+        // Remove association from host to this
+        synchronized (this.getDns()) {
+            this.getDns().removeAssociationWithTask(this);
+        }
+
+        // Remove associations from services to this
+        for (ServiceInfo serviceInfo : this.getDns().getServices().values()) {
+            ((ServiceInfoImpl) serviceInfo).removeAssociationWithTask(this);
+        }
+    }
+
+    @Override
+    public void run() {
+        DNSOutgoing out = this.createOugoing();
+        try {
+            if (!this.checkRunCondition()) {
+                this.cancel();
+                return;
+            }
+            List<DNSStatefulObject> stateObjects = new ArrayList<DNSStatefulObject>();
+            // send probes for JmDNS itself
+            synchronized (this.getDns()) {
+                if (this.getDns().isAssociatedWithTask(this, this.getTaskState())) {
+                    logger1.finer(this.getName() + ".run() JmDNS " + this.getTaskDescription() + " " + this.getDns().getName());
+                    stateObjects.add(this.getDns());
+                    out = this.buildOutgoingForDNS(out);
+                }
+            }
+            // send probes for services
+            for (ServiceInfo serviceInfo : this.getDns().getServices().values()) {
+                ServiceInfoImpl info = (ServiceInfoImpl) serviceInfo;
+
+                synchronized (info) {
+                    if (info.isAssociatedWithTask(this, this.getTaskState())) {
+                        logger1.fine(this.getName() + ".run() JmDNS " + this.getTaskDescription() + " " + info.getQualifiedName());
+                        stateObjects.add(info);
+                        out = this.buildOutgoingForInfo(info, out);
+                    }
+                }
+            }
+            if (!out.isEmpty()) {
+                logger1.finer(this.getName() + ".run() JmDNS " + this.getTaskDescription() + " #" + this.getTaskState());
+                this.getDns().send(out);
+
+                // Advance the state of objects.
+                this.advanceObjectsState(stateObjects);
+            } else {
+                // Advance the state of objects.
+                this.advanceObjectsState(stateObjects);
+
+                // If we have nothing to send, another timer taskState ahead of us has done the job for us. We can cancel.
+                cancel();
+                return;
+            }
+        } catch (Throwable e) {
+            logger1.log(Level.WARNING, this.getName() + ".run() exception ", e);
+            this.recoverTask(e);
+        }
+
+        this.advanceTask();
+    }
+
+    protected abstract boolean checkRunCondition();
+
+    protected abstract DNSOutgoing buildOutgoingForDNS(DNSOutgoing out) throws IOException;
+
+    protected abstract DNSOutgoing buildOutgoingForInfo(ServiceInfoImpl info, DNSOutgoing out) throws IOException;
+
+    protected abstract DNSOutgoing createOugoing();
+
+    protected void advanceObjectsState(List<DNSStatefulObject> list) {
+        if (list != null) {
+            for (DNSStatefulObject object : list) {
+                synchronized (object) {
+                    object.advanceState(this);
+                }
+            }
+        }
+    }
+
+    protected abstract void recoverTask(Throwable e);
+
+    protected abstract void advanceTask();
+
+    /**
+     * @return the taskState
+     */
+    protected DNSState getTaskState() {
+        return this._taskState;
+    }
+
+    /**
+     * @param taskState
+     *            the taskState to set
+     */
+    protected void setTaskState(DNSState taskState) {
+        this._taskState = taskState;
+    }
+
+}
diff --git a/src/javax/jmdns/impl/tasks/state/Prober.java b/src/javax/jmdns/impl/tasks/state/Prober.java
new file mode 100644
index 0000000..a793a27
--- /dev/null
+++ b/src/javax/jmdns/impl/tasks/state/Prober.java
@@ -0,0 +1,161 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl.tasks.state;
+
+import java.io.IOException;
+import java.util.Timer;
+import java.util.logging.Logger;
+
+import javax.jmdns.impl.DNSOutgoing;
+import javax.jmdns.impl.DNSQuestion;
+import javax.jmdns.impl.DNSRecord;
+import javax.jmdns.impl.JmDNSImpl;
+import javax.jmdns.impl.ServiceInfoImpl;
+import javax.jmdns.impl.constants.DNSConstants;
+import javax.jmdns.impl.constants.DNSRecordClass;
+import javax.jmdns.impl.constants.DNSRecordType;
+import javax.jmdns.impl.constants.DNSState;
+
+/**
+ * The Prober sends three consecutive probes for all service infos that needs probing as well as for the host name. The state of each service info of the host name is advanced, when a probe has been sent for it. When the prober has run three times,
+ * it launches an Announcer.
+ * <p/>
+ * If a conflict during probes occurs, the affected service infos (and affected host name) are taken away from the prober. This eventually causes the prober to cancel itself.
+ */
+public class Prober extends DNSStateTask {
+    static Logger logger = Logger.getLogger(Prober.class.getName());
+
+    public Prober(JmDNSImpl jmDNSImpl) {
+        super(jmDNSImpl, defaultTTL());
+
+        this.setTaskState(DNSState.PROBING_1);
+        this.associate(DNSState.PROBING_1);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.DNSTask#getName()
+     */
+    @Override
+    public String getName() {
+        return "Prober(" + (this.getDns() != null ? this.getDns().getName() : "") + ")";
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return super.toString() + " state: " + this.getTaskState();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.DNSTask#start(java.util.Timer)
+     */
+    @Override
+    public void start(Timer timer) {
+        long now = System.currentTimeMillis();
+        if (now - this.getDns().getLastThrottleIncrement() < DNSConstants.PROBE_THROTTLE_COUNT_INTERVAL) {
+            this.getDns().setThrottle(this.getDns().getThrottle() + 1);
+        } else {
+            this.getDns().setThrottle(1);
+        }
+        this.getDns().setLastThrottleIncrement(now);
+
+        if (this.getDns().isAnnounced() && this.getDns().getThrottle() < DNSConstants.PROBE_THROTTLE_COUNT) {
+            timer.schedule(this, JmDNSImpl.getRandom().nextInt(1 + DNSConstants.PROBE_WAIT_INTERVAL), DNSConstants.PROBE_WAIT_INTERVAL);
+        } else if (!this.getDns().isCanceling() && !this.getDns().isCanceled()) {
+            timer.schedule(this, DNSConstants.PROBE_CONFLICT_INTERVAL, DNSConstants.PROBE_CONFLICT_INTERVAL);
+        }
+    }
+
+    @Override
+    public boolean cancel() {
+        this.removeAssociation();
+
+        return super.cancel();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#getTaskDescription()
+     */
+    @Override
+    public String getTaskDescription() {
+        return "probing";
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#checkRunCondition()
+     */
+    @Override
+    protected boolean checkRunCondition() {
+        return !this.getDns().isCanceling() && !this.getDns().isCanceled();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#createOugoing()
+     */
+    @Override
+    protected DNSOutgoing createOugoing() {
+        return new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#buildOutgoingForDNS(javax.jmdns.impl.DNSOutgoing)
+     */
+    @Override
+    protected DNSOutgoing buildOutgoingForDNS(DNSOutgoing out) throws IOException {
+        DNSOutgoing newOut = out;
+        newOut.addQuestion(DNSQuestion.newQuestion(this.getDns().getLocalHost().getName(), DNSRecordType.TYPE_ANY, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
+        for (DNSRecord answer : this.getDns().getLocalHost().answers(DNSRecordClass.NOT_UNIQUE, this.getTTL())) {
+            newOut = this.addAuthoritativeAnswer(newOut, answer);
+        }
+        return newOut;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#buildOutgoingForInfo(javax.jmdns.impl.ServiceInfoImpl, javax.jmdns.impl.DNSOutgoing)
+     */
+    @Override
+    protected DNSOutgoing buildOutgoingForInfo(ServiceInfoImpl info, DNSOutgoing out) throws IOException {
+        DNSOutgoing newOut = out;
+        newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(info.getQualifiedName(), DNSRecordType.TYPE_ANY, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
+        // the "unique" flag should be not set here because these answers haven't been proven unique yet this means the record will not exactly match the announcement record
+        newOut = this.addAuthoritativeAnswer(newOut, new DNSRecord.Service(info.getQualifiedName(), DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE, this.getTTL(), info.getPriority(), info.getWeight(), info.getPort(), this.getDns().getLocalHost()
+                .getName()));
+        return newOut;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#recoverTask(java.lang.Throwable)
+     */
+    @Override
+    protected void recoverTask(Throwable e) {
+        this.getDns().recover();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#advanceTask()
+     */
+    @Override
+    protected void advanceTask() {
+        this.setTaskState(this.getTaskState().advance());
+        if (!this.getTaskState().isProbing()) {
+            cancel();
+
+            this.getDns().startAnnouncer();
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/src/javax/jmdns/impl/tasks/state/Renewer.java b/src/javax/jmdns/impl/tasks/state/Renewer.java
new file mode 100644
index 0000000..f79ee12
--- /dev/null
+++ b/src/javax/jmdns/impl/tasks/state/Renewer.java
@@ -0,0 +1,144 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl.tasks.state;
+
+import java.io.IOException;
+import java.util.Timer;
+import java.util.logging.Logger;
+
+import javax.jmdns.impl.DNSOutgoing;
+import javax.jmdns.impl.DNSRecord;
+import javax.jmdns.impl.JmDNSImpl;
+import javax.jmdns.impl.ServiceInfoImpl;
+import javax.jmdns.impl.constants.DNSConstants;
+import javax.jmdns.impl.constants.DNSRecordClass;
+import javax.jmdns.impl.constants.DNSState;
+
+/**
+ * The Renewer is there to send renewal announcement when the record expire for ours infos.
+ */
+public class Renewer extends DNSStateTask {
+    static Logger logger = Logger.getLogger(Renewer.class.getName());
+
+    public Renewer(JmDNSImpl jmDNSImpl) {
+        super(jmDNSImpl, defaultTTL());
+
+        this.setTaskState(DNSState.ANNOUNCED);
+        this.associate(DNSState.ANNOUNCED);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.DNSTask#getName()
+     */
+    @Override
+    public String getName() {
+        return "Renewer(" + (this.getDns() != null ? this.getDns().getName() : "") + ")";
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return super.toString() + " state: " + this.getTaskState();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.DNSTask#start(java.util.Timer)
+     */
+    @Override
+    public void start(Timer timer) {
+        if (!this.getDns().isCanceling() && !this.getDns().isCanceled()) {
+            // BEGIN android-changed
+            // Schedule the renewer based on this task's TTL, not the default TTL
+            timer.schedule(this, getTTL() * 500, getTTL() * 500);
+            // END android-changed
+        }
+    }
+
+    @Override
+    public boolean cancel() {
+        this.removeAssociation();
+
+        return super.cancel();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#getTaskDescription()
+     */
+    @Override
+    public String getTaskDescription() {
+        return "renewing";
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#checkRunCondition()
+     */
+    @Override
+    protected boolean checkRunCondition() {
+        return !this.getDns().isCanceling() && !this.getDns().isCanceled();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#createOugoing()
+     */
+    @Override
+    protected DNSOutgoing createOugoing() {
+        return new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#buildOutgoingForDNS(javax.jmdns.impl.DNSOutgoing)
+     */
+    @Override
+    protected DNSOutgoing buildOutgoingForDNS(DNSOutgoing out) throws IOException {
+        DNSOutgoing newOut = out;
+        for (DNSRecord answer : this.getDns().getLocalHost().answers(DNSRecordClass.UNIQUE, this.getTTL())) {
+            newOut = this.addAnswer(newOut, null, answer);
+        }
+        return newOut;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#buildOutgoingForInfo(javax.jmdns.impl.ServiceInfoImpl, javax.jmdns.impl.DNSOutgoing)
+     */
+    @Override
+    protected DNSOutgoing buildOutgoingForInfo(ServiceInfoImpl info, DNSOutgoing out) throws IOException {
+        DNSOutgoing newOut = out;
+        for (DNSRecord answer : info.answers(DNSRecordClass.UNIQUE, this.getTTL(), this.getDns().getLocalHost())) {
+            newOut = this.addAnswer(newOut, null, answer);
+        }
+        return newOut;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#recoverTask(java.lang.Throwable)
+     */
+    @Override
+    protected void recoverTask(Throwable e) {
+        this.getDns().recover();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.jmdns.impl.tasks.state.DNSStateTask#advanceTask()
+     */
+    @Override
+    protected void advanceTask() {
+        this.setTaskState(this.getTaskState().advance());
+        if (!this.getTaskState().isAnnounced()) {
+            cancel();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/javax/jmdns/impl/tasks/state/package-info.java b/src/javax/jmdns/impl/tasks/state/package-info.java
new file mode 100644
index 0000000..d9b986c
--- /dev/null
+++ b/src/javax/jmdns/impl/tasks/state/package-info.java
@@ -0,0 +1,2 @@
+package javax.jmdns.impl.tasks.state;
+
diff --git a/src/javax/jmdns/package-info.java b/src/javax/jmdns/package-info.java
new file mode 100644
index 0000000..4d4202f
--- /dev/null
+++ b/src/javax/jmdns/package-info.java
@@ -0,0 +1,9 @@
+package javax.jmdns;
+
+/**
+ * JmDNS is a Java implementation of multi-cast DNS and can be used for service registration and discovery in local area networks. JmDNS is fully compatible with Apple's Bonjour. The project was originally started in December 2002 by Arthur van Hoff
+ * at Strangeberry. In November 2003 the project was moved to SourceForge, and the name was changed from JRendezvous to JmDNS for legal reasons. Many thanks to Stuart Cheshire for help and moral support.
+ * <p>
+ * <a href="http://jmdns.sourceforge.net/">http://jmdns.sourceforge.net/<a>
+ * </p>
+ **/
