diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.ui/launch/ECF Discovery and Remote Service UI.launch b/framework/bundles/org.eclipse.ecf.remoteservice.ui/launch/ECF Discovery and Remote Service UI.launch
index c6f3897..7c7c705 100644
--- a/framework/bundles/org.eclipse.ecf.remoteservice.ui/launch/ECF Discovery and Remote Service UI.launch
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.ui/launch/ECF Discovery and Remote Service UI.launch
@@ -20,7 +20,7 @@
 <stringAttribute key="pde.version" value="3.3"/>
 <stringAttribute key="product" value="org.eclipse.platform.ide"/>
 <booleanAttribute key="restart" value="false"/>
-<stringAttribute key="selected_target_plugins" value="com.ibm.icu@default:default,org.apache.lucene.analysis@default:default,org.apache.lucene@default:default,org.eclipse.ant.core@default:default,org.eclipse.compare.core@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding.observable@default:default,org.eclipse.core.databinding.property@default:default,org.eclipse.core.databinding@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.net@default:default,org.eclipse.core.resources@default:default,org.eclipse.core.runtime.compatibility.registry@default:false,org.eclipse.core.runtime@default:true,org.eclipse.core.variables@default:default,org.eclipse.ecf.filetransfer@default:default,org.eclipse.ecf.ssl@default:false,org.eclipse.equinox.app@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.concurrent@default:default,org.eclipse.equinox.p2.artifact.repository@default:default,org.eclipse.equinox.p2.core@default:default,org.eclipse.equinox.p2.engine@default:default,org.eclipse.equinox.p2.jarprocessor@default:default,org.eclipse.equinox.p2.metadata.repository@default:default,org.eclipse.equinox.p2.metadata@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.security@default:default,org.eclipse.help.base@default:default,org.eclipse.help@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.jface.text@default:default,org.eclipse.jface@default:default,org.eclipse.osgi,org.eclipse.osgi.services@default:default,org.eclipse.platform@default:default,org.eclipse.swt@default:default,org.eclipse.text@default:default,org.eclipse.ui.browser@default:default,org.eclipse.ui.cheatsheets@default:default,org.eclipse.ui.forms@default:default,org.eclipse.ui.ide.application@default:default,org.eclipse.ui.ide@default:default,org.eclipse.ui.intro.universal@default:default,org.eclipse.ui.intro@default:default,org.eclipse.ui.navigator.resources@default:default,org.eclipse.ui.navigator@default:default,org.eclipse.ui.views.properties.tabbed@default:default,org.eclipse.ui.views@default:default,org.eclipse.ui.workbench.texteditor@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.ui@default:default,org.objectweb.asm@default:default"/>
+<stringAttribute key="selected_target_plugins" value="com.ibm.icu@default:default,org.apache.lucene.analysis@default:default,org.eclipse.ant.core@default:default,org.eclipse.compare.core@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding.observable@default:default,org.eclipse.core.databinding.property@default:default,org.eclipse.core.databinding@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.net@default:default,org.eclipse.core.resources@default:default,org.eclipse.core.runtime.compatibility.registry@default:false,org.eclipse.core.runtime@default:true,org.eclipse.core.variables@default:default,org.eclipse.ecf.filetransfer@default:default,org.eclipse.ecf.ssl@default:false,org.eclipse.equinox.app@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.concurrent@default:default,org.eclipse.equinox.p2.artifact.repository@default:default,org.eclipse.equinox.p2.core@default:default,org.eclipse.equinox.p2.engine@default:default,org.eclipse.equinox.p2.jarprocessor@default:default,org.eclipse.equinox.p2.metadata.repository@default:default,org.eclipse.equinox.p2.metadata@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.security@default:default,org.eclipse.help.base@default:default,org.eclipse.help@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.jface.text@default:default,org.eclipse.jface@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.eclipse.platform@default:default,org.eclipse.swt@default:default,org.eclipse.text@default:default,org.eclipse.ui.browser@default:default,org.eclipse.ui.cheatsheets@default:default,org.eclipse.ui.forms@default:default,org.eclipse.ui.ide.application@default:default,org.eclipse.ui.ide@default:default,org.eclipse.ui.intro.universal@default:default,org.eclipse.ui.intro@default:default,org.eclipse.ui.navigator.resources@default:default,org.eclipse.ui.navigator@default:default,org.eclipse.ui.views.properties.tabbed@default:default,org.eclipse.ui.views@default:default,org.eclipse.ui.workbench.texteditor@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.ui@default:default,org.objectweb.asm@default:default"/>
 <stringAttribute key="selected_workspace_plugins" value="ch.ethz.iks.r_osgi.remote@default:default,ch.ethz.iks.slp@default:default,org.eclipse.ecf.discovery.ui.browser@default:default,org.eclipse.ecf.discovery.ui.edit@default:default,org.eclipse.ecf.discovery.ui.model@default:default,org.eclipse.ecf.discovery.ui.properties.tabbed@default:false,org.eclipse.ecf.discovery.ui.properties@default:false,org.eclipse.ecf.discovery.ui@default:default,org.eclipse.ecf.discovery@default:default,org.eclipse.ecf.examples.remoteservices.client@default:false,org.eclipse.ecf.examples.remoteservices.common@default:default,org.eclipse.ecf.identity@default:default,org.eclipse.ecf.osgi.services.distribution@default:default,org.eclipse.ecf.provider.discovery@default:default,org.eclipse.ecf.provider.jmdns@default:default,org.eclipse.ecf.provider.jslp@default:default,org.eclipse.ecf.provider.r_osgi@default:default,org.eclipse.ecf.provider.remoteservice@default:default,org.eclipse.ecf.provider@default:default,org.eclipse.ecf.remoteservice.ui@default:default,org.eclipse.ecf.remoteservice@default:default,org.eclipse.ecf.server.generic@default:default,org.eclipse.ecf.sharedobject@default:default,org.eclipse.ecf@default:default,org.eclipse.emf.common.ui@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.emf.edit.ui@default:default,org.eclipse.emf.edit@default:default"/>
 <booleanAttribute key="show_selected_only" value="false"/>
 <stringAttribute key="templateConfig" value="${target_home}\configuration\config.ini"/>
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/AbstractConnectionListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/AbstractConnectionListener.java
index 69acf90..132da68 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/AbstractConnectionListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/AbstractConnectionListener.java
@@ -1,46 +1,46 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smack;
-
-/**
- * The AbstractConnectionListener class provides an empty implementation for all
- * methods defined by the {@link ConnectionListener} interface. This is a
- * convenience class which should be used in case you do not need to implement
- * all methods.
- * 
- * @author Henning Staib
- */
-public class AbstractConnectionListener implements ConnectionListener {
-
-    public void connectionClosed() {
-        // do nothing
-    }
-
-    public void connectionClosedOnError(Exception e) {
-        // do nothing
-    }
-
-    public void reconnectingIn(int seconds) {
-        // do nothing
-    }
-
-    public void reconnectionFailed(Exception e) {
-        // do nothing
-    }
-
-    public void reconnectionSuccessful() {
-        // do nothing
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smack;
+
+/**
+ * The AbstractConnectionListener class provides an empty implementation for all
+ * methods defined by the {@link ConnectionListener} interface. This is a
+ * convenience class which should be used in case you do not need to implement
+ * all methods.
+ * 
+ * @author Henning Staib
+ */
+public class AbstractConnectionListener implements ConnectionListener {
+
+    public void connectionClosed() {
+        // do nothing
+    }
+
+    public void connectionClosedOnError(Exception e) {
+        // do nothing
+    }
+
+    public void reconnectingIn(int seconds) {
+        // do nothing
+    }
+
+    public void reconnectionFailed(Exception e) {
+        // do nothing
+    }
+
+    public void reconnectionSuccessful() {
+        // do nothing
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/NonSASLAuthentication.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/NonSASLAuthentication.java
index d7a479d..93511b7 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/NonSASLAuthentication.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/NonSASLAuthentication.java
@@ -1,143 +1,143 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack;
-
-import org.jivesoftware.smack.filter.PacketIDFilter;
-import org.jivesoftware.smack.packet.Authentication;
-import org.jivesoftware.smack.packet.IQ;
-
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.Callback;
-
-/**
- * Implementation of JEP-0078: Non-SASL Authentication. Follow the following
- * <a href=http://www.jabber.org/jeps/jep-0078.html>link</a> to obtain more
- * information about the JEP.
- *
- * @author Gaston Dombiak
- */
-class NonSASLAuthentication implements UserAuthentication {
-
-    private Connection connection;
-
-    public NonSASLAuthentication(Connection connection) {
-        super();
-        this.connection = connection;
-    }
-
-    public String authenticate(String username, String resource, CallbackHandler cbh) throws XMPPException {
-        //Use the callback handler to determine the password, and continue on.
-        PasswordCallback pcb = new PasswordCallback("Password: ",false);
-        try {
-            cbh.handle(new Callback[]{pcb});
-            return authenticate(username, String.valueOf(pcb.getPassword()),resource);
-        } catch (Exception e) {
-            throw new XMPPException("Unable to determine password.",e);
-        }   
-    }
-
-    public String authenticate(String username, String password, String resource) throws
-            XMPPException {
-        // If we send an authentication packet in "get" mode with just the username,
-        // the server will return the list of authentication protocols it supports.
-        Authentication discoveryAuth = new Authentication();
-        discoveryAuth.setType(IQ.Type.GET);
-        discoveryAuth.setUsername(username);
-
-        PacketCollector collector =
-            connection.createPacketCollector(new PacketIDFilter(discoveryAuth.getPacketID()));
-        // Send the packet
-        connection.sendPacket(discoveryAuth);
-        // Wait up to a certain number of seconds for a response from the server.
-        IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-        if (response == null) {
-            throw new XMPPException("No response from the server.");
-        }
-        // If the server replied with an error, throw an exception.
-        else if (response.getType() == IQ.Type.ERROR) {
-            throw new XMPPException(response.getError());
-        }
-        // Otherwise, no error so continue processing.
-        Authentication authTypes = (Authentication) response;
-        collector.cancel();
-
-        // Now, create the authentication packet we'll send to the server.
-        Authentication auth = new Authentication();
-        auth.setUsername(username);
-
-        // Figure out if we should use digest or plain text authentication.
-        if (authTypes.getDigest() != null) {
-            auth.setDigest(connection.getConnectionID(), password);
-        }
-        else if (authTypes.getPassword() != null) {
-            auth.setPassword(password);
-        }
-        else {
-            throw new XMPPException("Server does not support compatible authentication mechanism.");
-        }
-
-        auth.setResource(resource);
-
-        collector = connection.createPacketCollector(new PacketIDFilter(auth.getPacketID()));
-        // Send the packet.
-        connection.sendPacket(auth);
-        // Wait up to a certain number of seconds for a response from the server.
-        response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-        if (response == null) {
-            throw new XMPPException("Authentication failed.");
-        }
-        else if (response.getType() == IQ.Type.ERROR) {
-            throw new XMPPException(response.getError());
-        }
-        // We're done with the collector, so explicitly cancel it.
-        collector.cancel();
-
-        return response.getTo();
-    }
-
-    public String authenticateAnonymously() throws XMPPException {
-        // Create the authentication packet we'll send to the server.
-        Authentication auth = new Authentication();
-
-        PacketCollector collector =
-            connection.createPacketCollector(new PacketIDFilter(auth.getPacketID()));
-        // Send the packet.
-        connection.sendPacket(auth);
-        // Wait up to a certain number of seconds for a response from the server.
-        IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-        if (response == null) {
-            throw new XMPPException("Anonymous login failed.");
-        }
-        else if (response.getType() == IQ.Type.ERROR) {
-            throw new XMPPException(response.getError());
-        }
-        // We're done with the collector, so explicitly cancel it.
-        collector.cancel();
-
-        if (response.getTo() != null) {
-            return response.getTo();
-        }
-        else {
-            return connection.getServiceName() + "/" + ((Authentication) response).getResource();
-        }
-    }
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack;
+
+import org.jivesoftware.smack.filter.PacketIDFilter;
+import org.jivesoftware.smack.packet.Authentication;
+import org.jivesoftware.smack.packet.IQ;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.Callback;
+
+/**
+ * Implementation of JEP-0078: Non-SASL Authentication. Follow the following
+ * <a href=http://www.jabber.org/jeps/jep-0078.html>link</a> to obtain more
+ * information about the JEP.
+ *
+ * @author Gaston Dombiak
+ */
+class NonSASLAuthentication implements UserAuthentication {
+
+    private Connection connection;
+
+    public NonSASLAuthentication(Connection connection) {
+        super();
+        this.connection = connection;
+    }
+
+    public String authenticate(String username, String resource, CallbackHandler cbh) throws XMPPException {
+        //Use the callback handler to determine the password, and continue on.
+        PasswordCallback pcb = new PasswordCallback("Password: ",false);
+        try {
+            cbh.handle(new Callback[]{pcb});
+            return authenticate(username, String.valueOf(pcb.getPassword()),resource);
+        } catch (Exception e) {
+            throw new XMPPException("Unable to determine password.",e);
+        }   
+    }
+
+    public String authenticate(String username, String password, String resource) throws
+            XMPPException {
+        // If we send an authentication packet in "get" mode with just the username,
+        // the server will return the list of authentication protocols it supports.
+        Authentication discoveryAuth = new Authentication();
+        discoveryAuth.setType(IQ.Type.GET);
+        discoveryAuth.setUsername(username);
+
+        PacketCollector collector =
+            connection.createPacketCollector(new PacketIDFilter(discoveryAuth.getPacketID()));
+        // Send the packet
+        connection.sendPacket(discoveryAuth);
+        // Wait up to a certain number of seconds for a response from the server.
+        IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+        if (response == null) {
+            throw new XMPPException("No response from the server.");
+        }
+        // If the server replied with an error, throw an exception.
+        else if (response.getType() == IQ.Type.ERROR) {
+            throw new XMPPException(response.getError());
+        }
+        // Otherwise, no error so continue processing.
+        Authentication authTypes = (Authentication) response;
+        collector.cancel();
+
+        // Now, create the authentication packet we'll send to the server.
+        Authentication auth = new Authentication();
+        auth.setUsername(username);
+
+        // Figure out if we should use digest or plain text authentication.
+        if (authTypes.getDigest() != null) {
+            auth.setDigest(connection.getConnectionID(), password);
+        }
+        else if (authTypes.getPassword() != null) {
+            auth.setPassword(password);
+        }
+        else {
+            throw new XMPPException("Server does not support compatible authentication mechanism.");
+        }
+
+        auth.setResource(resource);
+
+        collector = connection.createPacketCollector(new PacketIDFilter(auth.getPacketID()));
+        // Send the packet.
+        connection.sendPacket(auth);
+        // Wait up to a certain number of seconds for a response from the server.
+        response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+        if (response == null) {
+            throw new XMPPException("Authentication failed.");
+        }
+        else if (response.getType() == IQ.Type.ERROR) {
+            throw new XMPPException(response.getError());
+        }
+        // We're done with the collector, so explicitly cancel it.
+        collector.cancel();
+
+        return response.getTo();
+    }
+
+    public String authenticateAnonymously() throws XMPPException {
+        // Create the authentication packet we'll send to the server.
+        Authentication auth = new Authentication();
+
+        PacketCollector collector =
+            connection.createPacketCollector(new PacketIDFilter(auth.getPacketID()));
+        // Send the packet.
+        connection.sendPacket(auth);
+        // Wait up to a certain number of seconds for a response from the server.
+        IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+        if (response == null) {
+            throw new XMPPException("Anonymous login failed.");
+        }
+        else if (response.getType() == IQ.Type.ERROR) {
+            throw new XMPPException(response.getError());
+        }
+        // We're done with the collector, so explicitly cancel it.
+        collector.cancel();
+
+        if (response.getTo() != null) {
+            return response.getTo();
+        }
+        else {
+            return connection.getServiceName() + "/" + ((Authentication) response).getResource();
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/OpenTrustManager.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/OpenTrustManager.java
index 61ed8c6..2e47b1f 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/OpenTrustManager.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/OpenTrustManager.java
@@ -1,49 +1,49 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack;
-
-import javax.net.ssl.X509TrustManager;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-
-/**
- * Dummy trust manager that trust all certificates presented by the server. This class
- * is used during old SSL connections.
- *
- * @author Gaston Dombiak
- */
-class OpenTrustManager implements X509TrustManager {
-
-    public OpenTrustManager() {
-    }
-
-    public X509Certificate[] getAcceptedIssuers() {
-        return new X509Certificate[0];
-    }
-
-    public void checkClientTrusted(X509Certificate[] arg0, String arg1)
-            throws CertificateException {
-    }
-
-    public void checkServerTrusted(X509Certificate[] arg0, String arg1)
-            throws CertificateException {
-    }
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack;
+
+import javax.net.ssl.X509TrustManager;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+/**
+ * Dummy trust manager that trust all certificates presented by the server. This class
+ * is used during old SSL connections.
+ *
+ * @author Gaston Dombiak
+ */
+class OpenTrustManager implements X509TrustManager {
+
+    public OpenTrustManager() {
+    }
+
+    public X509Certificate[] getAcceptedIssuers() {
+        return new X509Certificate[0];
+    }
+
+    public void checkClientTrusted(X509Certificate[] arg0, String arg1)
+            throws CertificateException {
+    }
+
+    public void checkServerTrusted(X509Certificate[] arg0, String arg1)
+            throws CertificateException {
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PacketInterceptor.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PacketInterceptor.java
index bd89031..af56326 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PacketInterceptor.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PacketInterceptor.java
@@ -1,49 +1,49 @@
-/**
- * $Revision: 2408 $
- * $Date: 2004-11-02 20:53:30 -0300 (Tue, 02 Nov 2004) $
- *
- * Copyright 2003-2005 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack;
-
-import org.jivesoftware.smack.packet.Packet;
-
-/**
- * Provides a mechanism to intercept and modify packets that are going to be
- * sent to the server. PacketInterceptors are added to the {@link Connection}
- * together with a {@link org.jivesoftware.smack.filter.PacketFilter} so that only
- * certain packets are intercepted and processed by the interceptor.<p>
- *
- * This allows event-style programming -- every time a new packet is found,
- * the {@link #interceptPacket(Packet)} method will be called.
- *
- * @see Connection#addPacketInterceptor(PacketInterceptor, org.jivesoftware.smack.filter.PacketFilter)
- * @author Gaston Dombiak
- */
-public interface PacketInterceptor {
-
-    /**
-     * Process the packet that is about to be sent to the server. The intercepted
-     * packet can be modified by the interceptor.<p>
-     *
-     * Interceptors are invoked using the same thread that requested the packet
-     * to be sent, so it's very important that implementations of this method
-     * not block for any extended period of time.
-     *
-     * @param packet the packet to is going to be sent to the server.
-     */
-    public void interceptPacket(Packet packet);
-}
+/**
+ * $Revision: 2408 $
+ * $Date: 2004-11-02 20:53:30 -0300 (Tue, 02 Nov 2004) $
+ *
+ * Copyright 2003-2005 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack;
+
+import org.jivesoftware.smack.packet.Packet;
+
+/**
+ * Provides a mechanism to intercept and modify packets that are going to be
+ * sent to the server. PacketInterceptors are added to the {@link Connection}
+ * together with a {@link org.jivesoftware.smack.filter.PacketFilter} so that only
+ * certain packets are intercepted and processed by the interceptor.<p>
+ *
+ * This allows event-style programming -- every time a new packet is found,
+ * the {@link #interceptPacket(Packet)} method will be called.
+ *
+ * @see Connection#addPacketInterceptor(PacketInterceptor, org.jivesoftware.smack.filter.PacketFilter)
+ * @author Gaston Dombiak
+ */
+public interface PacketInterceptor {
+
+    /**
+     * Process the packet that is about to be sent to the server. The intercepted
+     * packet can be modified by the interceptor.<p>
+     *
+     * Interceptors are invoked using the same thread that requested the packet
+     * to be sent, so it's very important that implementations of this method
+     * not block for any extended period of time.
+     *
+     * @param packet the packet to is going to be sent to the server.
+     */
+    public void interceptPacket(Packet packet);
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PrivacyList.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PrivacyList.java
index 67d731d..e2d9f5e 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PrivacyList.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PrivacyList.java
@@ -15,60 +15,60 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jivesoftware.smack;
-
-import org.jivesoftware.smack.packet.PrivacyItem;
-
-import java.util.List;
-
-/**
- * A privacy list represents a list of contacts that is a read only class used to represent a set of allowed or blocked communications. 
- * Basically it can:<ul>
- *
- *      <li>Handle many {@link org.jivesoftware.smack.packet.PrivacyItem}.</li>
- *      <li>Answer if it is the default list.</li>
- *      <li>Answer if it is the active list.</li>
- * </ul>
- *
- * {@link PrivacyItem Privacy Items} can handle different kind of blocking communications based on JID, group,
- * subscription type or globally.
- * 
- * @author Francisco Vives
- */
-public class PrivacyList {
-
-    /** Holds if it is an active list or not **/
-    private boolean isActiveList;
-    /** Holds if it is an default list or not **/
-    private boolean isDefaultList;
-    /** Holds the list name used to print **/
-    private String listName;
-    /** Holds the list of {@see PrivacyItem} **/
-    private List<PrivacyItem> items;
-    
-    protected PrivacyList(boolean isActiveList, boolean isDefaultList,
-            String listName, List<PrivacyItem> privacyItems) {
-        super();
-        this.isActiveList = isActiveList;
-        this.isDefaultList = isDefaultList;
-        this.listName = listName;
-        this.items = privacyItems;
-    }
-
-    public boolean isActiveList() {
-        return isActiveList;
-    }
-
-    public boolean isDefaultList() {
-        return isDefaultList;
-    }
-
-    public List<PrivacyItem> getItems() {
-        return items;
-    }
-
-    public String toString() {
-        return listName;
-    }
-
-}
+package org.jivesoftware.smack;
+
+import org.jivesoftware.smack.packet.PrivacyItem;
+
+import java.util.List;
+
+/**
+ * A privacy list represents a list of contacts that is a read only class used to represent a set of allowed or blocked communications. 
+ * Basically it can:<ul>
+ *
+ *      <li>Handle many {@link org.jivesoftware.smack.packet.PrivacyItem}.</li>
+ *      <li>Answer if it is the default list.</li>
+ *      <li>Answer if it is the active list.</li>
+ * </ul>
+ *
+ * {@link PrivacyItem Privacy Items} can handle different kind of blocking communications based on JID, group,
+ * subscription type or globally.
+ * 
+ * @author Francisco Vives
+ */
+public class PrivacyList {
+
+    /** Holds if it is an active list or not **/
+    private boolean isActiveList;
+    /** Holds if it is an default list or not **/
+    private boolean isDefaultList;
+    /** Holds the list name used to print **/
+    private String listName;
+    /** Holds the list of {@see PrivacyItem} **/
+    private List<PrivacyItem> items;
+    
+    protected PrivacyList(boolean isActiveList, boolean isDefaultList,
+            String listName, List<PrivacyItem> privacyItems) {
+        super();
+        this.isActiveList = isActiveList;
+        this.isDefaultList = isDefaultList;
+        this.listName = listName;
+        this.items = privacyItems;
+    }
+
+    public boolean isActiveList() {
+        return isActiveList;
+    }
+
+    public boolean isDefaultList() {
+        return isDefaultList;
+    }
+
+    public List<PrivacyItem> getItems() {
+        return items;
+    }
+
+    public String toString() {
+        return listName;
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PrivacyListListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PrivacyListListener.java
index 5644ed7..20683f8 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PrivacyListListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PrivacyListListener.java
@@ -1,51 +1,51 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2006-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack;
-
-import org.jivesoftware.smack.packet.PrivacyItem;
-
-import java.util.List;
-
-/**
- * Interface to implement classes to listen for server events about privacy communication. 
- * Listeners are registered with the {@link PrivacyListManager}.
- *
- * @see PrivacyListManager#addListener
- * 
- * @author Francisco Vives
- */
-public interface PrivacyListListener {
-
-    /**
-     * Set or update a privacy list with PrivacyItem.
-     *
-     * @param listName the name of the new or updated privacy list.
-     * @param listItem the PrivacyItems that rules the list.
-     */
-    public void setPrivacyList(String listName, List<PrivacyItem> listItem);
-
-    /**
-     * A privacy list has been modified by another. It gets notified.
-     *
-     * @param listName the name of the updated privacy list.
-     */
-    public void updatedPrivacyList(String listName);
-
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2006-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack;
+
+import org.jivesoftware.smack.packet.PrivacyItem;
+
+import java.util.List;
+
+/**
+ * Interface to implement classes to listen for server events about privacy communication. 
+ * Listeners are registered with the {@link PrivacyListManager}.
+ *
+ * @see PrivacyListManager#addListener
+ * 
+ * @author Francisco Vives
+ */
+public interface PrivacyListListener {
+
+    /**
+     * Set or update a privacy list with PrivacyItem.
+     *
+     * @param listName the name of the new or updated privacy list.
+     * @param listItem the PrivacyItems that rules the list.
+     */
+    public void setPrivacyList(String listName, List<PrivacyItem> listItem);
+
+    /**
+     * A privacy list has been modified by another. It gets notified.
+     *
+     * @param listName the name of the updated privacy list.
+     */
+    public void updatedPrivacyList(String listName);
+
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PrivacyListManager.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PrivacyListManager.java
index eb1d231..77b066a 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PrivacyListManager.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PrivacyListManager.java
@@ -1,466 +1,466 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2006-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack;
-
-import org.jivesoftware.smack.filter.*;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smack.packet.Privacy;
-import org.jivesoftware.smack.packet.PrivacyItem;
-
-import java.util.*;
-
-/**
- * A PrivacyListManager is used by XMPP clients to block or allow communications from other
- * users. Use the manager to: <ul>
- *      <li>Retrieve privacy lists.
- *      <li>Add, remove, and edit privacy lists.
- *      <li>Set, change, or decline active lists.
- *      <li>Set, change, or decline the default list (i.e., the list that is active by default).
- * </ul>
- * Privacy Items can handle different kind of permission communications based on JID, group, 
- * subscription type or globally (@see PrivacyItem).
- * 
- * @author Francisco Vives
- */
-public class PrivacyListManager {
-
-    // Keep the list of instances of this class.
-	private static Map<Connection, PrivacyListManager> instances = new Hashtable<Connection, PrivacyListManager>();
-
-	private Connection connection;
-	private final List<PrivacyListListener> listeners = new ArrayList<PrivacyListListener>();
-	PacketFilter packetFilter = new AndFilter(new IQTypeFilter(IQ.Type.SET),
-    		new PacketExtensionFilter("query", "jabber:iq:privacy"));
-
-    static {
-        // Create a new PrivacyListManager on every established connection. In the init()
-        // method of PrivacyListManager, we'll add a listener that will delete the
-        // instance when the connection is closed.
-        Connection.addConnectionCreationListener(new ConnectionCreationListener() {
-            public void connectionCreated(Connection connection) {
-                new PrivacyListManager(connection);
-            }
-        });
-    }
-    /**
-     * Creates a new privacy manager to maintain the communication privacy. Note: no
-     * information is sent to or received from the server until you attempt to 
-     * get or set the privacy communication.<p>
-     *
-     * @param connection the XMPP connection.
-     */
-	private PrivacyListManager(Connection connection) {
-        this.connection = connection;
-        this.init();
-    }
-
-	/** Answer the connection userJID that owns the privacy.
-	 * @return the userJID that owns the privacy
-	 */
-	private String getUser() {
-		return connection.getUser();
-	}
-
-    /**
-     * Initializes the packet listeners of the connection that will notify for any set privacy 
-     * package. 
-     */
-    private void init() {
-        // Register the new instance and associate it with the connection 
-        instances.put(connection, this);
-        // Add a listener to the connection that removes the registered instance when
-        // the connection is closed
-        connection.addConnectionListener(new ConnectionListener() {
-            public void connectionClosed() {
-                // Unregister this instance since the connection has been closed
-                instances.remove(connection);
-            }
-
-            public void connectionClosedOnError(Exception e) {
-                // ignore
-            }
-
-            public void reconnectionFailed(Exception e) {
-                // ignore
-            }
-
-            public void reconnectingIn(int seconds) {
-                // ignore
-            }
-
-            public void reconnectionSuccessful() {
-                // ignore
-            }
-        });
-
-        connection.addPacketListener(new PacketListener() {
-            public void processPacket(Packet packet) {
-
-                if (packet == null || packet.getError() != null) {
-                    return;
-                }
-                // The packet is correct.
-                Privacy privacy = (Privacy) packet;
-                
-                // Notifies the event to the listeners.
-                synchronized (listeners) {
-                    for (PrivacyListListener listener : listeners) {
-                        // Notifies the created or updated privacy lists
-                        for (Map.Entry<String,List<PrivacyItem>> entry : privacy.getItemLists().entrySet()) {
-                            String listName = entry.getKey();
-                            List<PrivacyItem> items = entry.getValue();
-                            if (items.isEmpty()) {
-                                listener.updatedPrivacyList(listName);
-                            } else {
-                                listener.setPrivacyList(listName, items);
-                            }
-                        }
-                    }
-                }
-                
-                // Send a result package acknowledging the reception of a privacy package.
-                
-                // Prepare the IQ packet to send
-                IQ iq = new IQ() {
-                    public String getChildElementXML() {
-                        return "";
-                    }
-                };
-                iq.setType(IQ.Type.RESULT);
-                iq.setFrom(packet.getFrom());
-                iq.setPacketID(packet.getPacketID());
-
-                // Send create & join packet.
-                connection.sendPacket(iq);
-            }
-        }, packetFilter);
-    }
-
-    /**
-     * Returns the PrivacyListManager instance associated with a given Connection.
-     * 
-     * @param connection the connection used to look for the proper PrivacyListManager.
-     * @return the PrivacyListManager associated with a given Connection.
-     */
-    public static PrivacyListManager getInstanceFor(Connection connection) {
-        return instances.get(connection);
-    }
-    
-	/**
-	 * Send the {@link Privacy} packet to the server in order to know some privacy content and then 
-	 * waits for the answer.
-	 * 
-	 * @param requestPrivacy is the {@link Privacy} packet configured properly whose XML
-     *      will be sent to the server.
-	 * @return a new {@link Privacy} with the data received from the server.
-	 * @exception XMPPException if the request or the answer failed, it raises an exception.
-	 */ 
-	private Privacy getRequest(Privacy requestPrivacy) throws XMPPException {
-		// The request is a get iq type
-		requestPrivacy.setType(Privacy.Type.GET);
-		requestPrivacy.setFrom(this.getUser());
-		
-		// Filter packets looking for an answer from the server.
-		PacketFilter responseFilter = new PacketIDFilter(requestPrivacy.getPacketID());
-        PacketCollector response = connection.createPacketCollector(responseFilter);
-        
-        // Send create & join packet.
-        connection.sendPacket(requestPrivacy);
-        
-        // Wait up to a certain number of seconds for a reply.
-        Privacy privacyAnswer =
-            (Privacy) response.nextResult(SmackConfiguration.getPacketReplyTimeout());
-        
-        // Stop queuing results
-        response.cancel();
-
-        // Interprete the result and answer the privacy only if it is valid
-        if (privacyAnswer == null) {
-            throw new XMPPException("No response from server.");
-        }
-        else if (privacyAnswer.getError() != null) {
-            throw new XMPPException(privacyAnswer.getError());
-        }
-        return privacyAnswer;
-	}
-	
-	/**
-	 * Send the {@link Privacy} packet to the server in order to modify the server privacy and 
-	 * waits for the answer.
-	 * 
-	 * @param requestPrivacy is the {@link Privacy} packet configured properly whose xml will be sent
-	 * to the server.
-	 * @return a new {@link Privacy} with the data received from the server.
-	 * @exception XMPPException if the request or the answer failed, it raises an exception.
-	 */ 
-	private Packet setRequest(Privacy requestPrivacy) throws XMPPException {
-		
-		// The request is a get iq type
-		requestPrivacy.setType(Privacy.Type.SET);
-		requestPrivacy.setFrom(this.getUser());
-		
-		// Filter packets looking for an answer from the server.
-		PacketFilter responseFilter = new PacketIDFilter(requestPrivacy.getPacketID());
-        PacketCollector response = connection.createPacketCollector(responseFilter);
-        
-        // Send create & join packet.
-        connection.sendPacket(requestPrivacy);
-        
-        // Wait up to a certain number of seconds for a reply.
-        Packet privacyAnswer = response.nextResult(SmackConfiguration.getPacketReplyTimeout());
-        
-        // Stop queuing results
-        response.cancel();
-
-        // Interprete the result and answer the privacy only if it is valid
-        if (privacyAnswer == null) {
-            throw new XMPPException("No response from server.");
-        } else if (privacyAnswer.getError() != null) {
-            throw new XMPPException(privacyAnswer.getError());
-        }
-        return privacyAnswer;
-	}
-
-	/**
-	 * Answer a privacy containing the list structre without {@link PrivacyItem}.
-	 * 
-	 * @return a Privacy with the list names.
-     * @throws XMPPException if an error occurs.
-	 */ 
-	private Privacy getPrivacyWithListNames() throws XMPPException {
-		
-		// The request of the list is an empty privacy message
-		Privacy request = new Privacy();
-		
-		// Send the package to the server and get the answer
-		return getRequest(request);
-	}
-	
-    /**
-     * Answer the active privacy list.
-     * 
-     * @return the privacy list of the active list.
-     * @throws XMPPException if an error occurs.
-     */ 
-    public PrivacyList getActiveList() throws XMPPException {
-        Privacy privacyAnswer = this.getPrivacyWithListNames();
-        String listName = privacyAnswer.getActiveName();
-        boolean isDefaultAndActive = privacyAnswer.getActiveName() != null
-                && privacyAnswer.getDefaultName() != null
-                && privacyAnswer.getActiveName().equals(
-                privacyAnswer.getDefaultName());
-        return new PrivacyList(true, isDefaultAndActive, listName, getPrivacyListItems(listName));
-    }
-    
-    /**
-     * Answer the default privacy list.
-     * 
-     * @return the privacy list of the default list.
-     * @throws XMPPException if an error occurs.
-     */ 
-    public PrivacyList getDefaultList() throws XMPPException {
-        Privacy privacyAnswer = this.getPrivacyWithListNames();
-        String listName = privacyAnswer.getDefaultName();
-        boolean isDefaultAndActive = privacyAnswer.getActiveName() != null
-                && privacyAnswer.getDefaultName() != null
-                && privacyAnswer.getActiveName().equals(
-                privacyAnswer.getDefaultName());
-        return new PrivacyList(isDefaultAndActive, true, listName, getPrivacyListItems(listName));
-    }
-    
-    /**
-     * Answer the privacy list items under listName with the allowed and blocked permissions.
-     * 
-     * @param listName the name of the list to get the allowed and blocked permissions.
-     * @return a list of privacy items under the list listName.
-     * @throws XMPPException if an error occurs.
-     */ 
-    private List<PrivacyItem> getPrivacyListItems(String listName) throws XMPPException {
-        
-        // The request of the list is an privacy message with an empty list
-        Privacy request = new Privacy();
-        request.setPrivacyList(listName, new ArrayList<PrivacyItem>());
-        
-        // Send the package to the server and get the answer
-        Privacy privacyAnswer = getRequest(request);
-        
-        return privacyAnswer.getPrivacyList(listName);
-    }
-    
-	/**
-	 * Answer the privacy list items under listName with the allowed and blocked permissions.
-	 * 
-	 * @param listName the name of the list to get the allowed and blocked permissions.
-	 * @return a privacy list under the list listName.
-     * @throws XMPPException if an error occurs.
-	 */ 
-	public PrivacyList getPrivacyList(String listName) throws XMPPException {
-		
-        return new PrivacyList(false, false, listName, getPrivacyListItems(listName));
-	}
-	
-    /**
-     * Answer every privacy list with the allowed and blocked permissions.
-     * 
-     * @return an array of privacy lists.
-     * @throws XMPPException if an error occurs.
-     */ 
-    public PrivacyList[] getPrivacyLists() throws XMPPException {
-        Privacy privacyAnswer = this.getPrivacyWithListNames();
-        Set<String> names = privacyAnswer.getPrivacyListNames();
-        PrivacyList[] lists = new PrivacyList[names.size()];
-        boolean isActiveList;
-        boolean isDefaultList;
-        int index=0;
-        for (String listName : names) {
-            isActiveList = listName.equals(privacyAnswer.getActiveName());
-            isDefaultList = listName.equals(privacyAnswer.getDefaultName());
-            lists[index] = new PrivacyList(isActiveList, isDefaultList,
-                    listName, getPrivacyListItems(listName));
-            index = index + 1;
-        }
-        return lists;
-    }
-
-    
-	/**
-	 * Set or change the active list to listName.
-	 * 
-	 * @param listName the list name to set as the active one.
-	 * @exception XMPPException if the request or the answer failed, it raises an exception.
-	 */ 
-	public void setActiveListName(String listName) throws XMPPException {
-		
-		// The request of the list is an privacy message with an empty list
-		Privacy request = new Privacy();
-		request.setActiveName(listName);
-		
-		// Send the package to the server
-		setRequest(request);
-	}
-
-	/**
-	 * Client declines the use of active lists.
-     *
-     * @throws XMPPException if an error occurs.
-	 */ 
-	public void declineActiveList() throws XMPPException {
-		
-		// The request of the list is an privacy message with an empty list
-		Privacy request = new Privacy();
-		request.setDeclineActiveList(true);
-		
-		// Send the package to the server
-		setRequest(request);
-	}
-
-	/**
-	 * Set or change the default list to listName.
-	 * 
-	 * @param listName the list name to set as the default one.
-	 * @exception XMPPException if the request or the answer failed, it raises an exception.
-	 */ 
-	public void setDefaultListName(String listName) throws XMPPException {
-		
-		// The request of the list is an privacy message with an empty list
-		Privacy request = new Privacy();
-		request.setDefaultName(listName);
-		
-		// Send the package to the server
-		setRequest(request);
-	}
-	
-	/**
-	 * Client declines the use of default lists.
-     *
-     * @throws XMPPException if an error occurs.
-	 */ 
-	public void declineDefaultList() throws XMPPException {
-		
-		// The request of the list is an privacy message with an empty list
-		Privacy request = new Privacy();
-		request.setDeclineDefaultList(true);
-		
-		// Send the package to the server
-		setRequest(request);
-	}
-	
-	/**
-	 * The client has created a new list. It send the new one to the server.
-	 * 
-     * @param listName the list that has changed its content.
-     * @param privacyItems a List with every privacy item in the list.
-     * @throws XMPPException if an error occurs.
-	 */ 
-	public void createPrivacyList(String listName, List<PrivacyItem> privacyItems) throws XMPPException {
-
-		this.updatePrivacyList(listName, privacyItems);
-	}
-
-    /**
-     * The client has edited an existing list. It updates the server content with the resulting 
-     * list of privacy items. The {@link PrivacyItem} list MUST contain all elements in the 
-     * list (not the "delta").
-     * 
-     * @param listName the list that has changed its content.
-     * @param privacyItems a List with every privacy item in the list.
-     * @throws XMPPException if an error occurs.
-     */ 
-    public void updatePrivacyList(String listName, List<PrivacyItem> privacyItems) throws XMPPException {
-
-        // Build the privacy package to add or update the new list
-        Privacy request = new Privacy();
-        request.setPrivacyList(listName, privacyItems);
-
-        // Send the package to the server
-        setRequest(request);
-    }
-    
-	/**
-	 * Remove a privacy list.
-	 * 
-     * @param listName the list that has changed its content.
-     * @throws XMPPException if an error occurs.
-	 */ 
-	public void deletePrivacyList(String listName) throws XMPPException {
-		
-		// The request of the list is an privacy message with an empty list
-		Privacy request = new Privacy();
-		request.setPrivacyList(listName, new ArrayList<PrivacyItem>());
-
-		// Send the package to the server
-		setRequest(request);
-	}
-	
-    /**
-     * Adds a packet listener that will be notified of any new update in the user
-     * privacy communication.
-     *
-     * @param listener a packet listener.
-     */
-    public void addListener(PrivacyListListener listener) {
-        // Keep track of the listener so that we can manually deliver extra
-        // messages to it later if needed.
-        synchronized (listeners) {
-            listeners.add(listener);
-        }
-    }    
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2006-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack;
+
+import org.jivesoftware.smack.filter.*;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.packet.Privacy;
+import org.jivesoftware.smack.packet.PrivacyItem;
+
+import java.util.*;
+
+/**
+ * A PrivacyListManager is used by XMPP clients to block or allow communications from other
+ * users. Use the manager to: <ul>
+ *      <li>Retrieve privacy lists.
+ *      <li>Add, remove, and edit privacy lists.
+ *      <li>Set, change, or decline active lists.
+ *      <li>Set, change, or decline the default list (i.e., the list that is active by default).
+ * </ul>
+ * Privacy Items can handle different kind of permission communications based on JID, group, 
+ * subscription type or globally (@see PrivacyItem).
+ * 
+ * @author Francisco Vives
+ */
+public class PrivacyListManager {
+
+    // Keep the list of instances of this class.
+	private static Map<Connection, PrivacyListManager> instances = new Hashtable<Connection, PrivacyListManager>();
+
+	private Connection connection;
+	private final List<PrivacyListListener> listeners = new ArrayList<PrivacyListListener>();
+	PacketFilter packetFilter = new AndFilter(new IQTypeFilter(IQ.Type.SET),
+    		new PacketExtensionFilter("query", "jabber:iq:privacy"));
+
+    static {
+        // Create a new PrivacyListManager on every established connection. In the init()
+        // method of PrivacyListManager, we'll add a listener that will delete the
+        // instance when the connection is closed.
+        Connection.addConnectionCreationListener(new ConnectionCreationListener() {
+            public void connectionCreated(Connection connection) {
+                new PrivacyListManager(connection);
+            }
+        });
+    }
+    /**
+     * Creates a new privacy manager to maintain the communication privacy. Note: no
+     * information is sent to or received from the server until you attempt to 
+     * get or set the privacy communication.<p>
+     *
+     * @param connection the XMPP connection.
+     */
+	private PrivacyListManager(Connection connection) {
+        this.connection = connection;
+        this.init();
+    }
+
+	/** Answer the connection userJID that owns the privacy.
+	 * @return the userJID that owns the privacy
+	 */
+	private String getUser() {
+		return connection.getUser();
+	}
+
+    /**
+     * Initializes the packet listeners of the connection that will notify for any set privacy 
+     * package. 
+     */
+    private void init() {
+        // Register the new instance and associate it with the connection 
+        instances.put(connection, this);
+        // Add a listener to the connection that removes the registered instance when
+        // the connection is closed
+        connection.addConnectionListener(new ConnectionListener() {
+            public void connectionClosed() {
+                // Unregister this instance since the connection has been closed
+                instances.remove(connection);
+            }
+
+            public void connectionClosedOnError(Exception e) {
+                // ignore
+            }
+
+            public void reconnectionFailed(Exception e) {
+                // ignore
+            }
+
+            public void reconnectingIn(int seconds) {
+                // ignore
+            }
+
+            public void reconnectionSuccessful() {
+                // ignore
+            }
+        });
+
+        connection.addPacketListener(new PacketListener() {
+            public void processPacket(Packet packet) {
+
+                if (packet == null || packet.getError() != null) {
+                    return;
+                }
+                // The packet is correct.
+                Privacy privacy = (Privacy) packet;
+                
+                // Notifies the event to the listeners.
+                synchronized (listeners) {
+                    for (PrivacyListListener listener : listeners) {
+                        // Notifies the created or updated privacy lists
+                        for (Map.Entry<String,List<PrivacyItem>> entry : privacy.getItemLists().entrySet()) {
+                            String listName = entry.getKey();
+                            List<PrivacyItem> items = entry.getValue();
+                            if (items.isEmpty()) {
+                                listener.updatedPrivacyList(listName);
+                            } else {
+                                listener.setPrivacyList(listName, items);
+                            }
+                        }
+                    }
+                }
+                
+                // Send a result package acknowledging the reception of a privacy package.
+                
+                // Prepare the IQ packet to send
+                IQ iq = new IQ() {
+                    public String getChildElementXML() {
+                        return "";
+                    }
+                };
+                iq.setType(IQ.Type.RESULT);
+                iq.setFrom(packet.getFrom());
+                iq.setPacketID(packet.getPacketID());
+
+                // Send create & join packet.
+                connection.sendPacket(iq);
+            }
+        }, packetFilter);
+    }
+
+    /**
+     * Returns the PrivacyListManager instance associated with a given Connection.
+     * 
+     * @param connection the connection used to look for the proper PrivacyListManager.
+     * @return the PrivacyListManager associated with a given Connection.
+     */
+    public static PrivacyListManager getInstanceFor(Connection connection) {
+        return instances.get(connection);
+    }
+    
+	/**
+	 * Send the {@link Privacy} packet to the server in order to know some privacy content and then 
+	 * waits for the answer.
+	 * 
+	 * @param requestPrivacy is the {@link Privacy} packet configured properly whose XML
+     *      will be sent to the server.
+	 * @return a new {@link Privacy} with the data received from the server.
+	 * @exception XMPPException if the request or the answer failed, it raises an exception.
+	 */ 
+	private Privacy getRequest(Privacy requestPrivacy) throws XMPPException {
+		// The request is a get iq type
+		requestPrivacy.setType(Privacy.Type.GET);
+		requestPrivacy.setFrom(this.getUser());
+		
+		// Filter packets looking for an answer from the server.
+		PacketFilter responseFilter = new PacketIDFilter(requestPrivacy.getPacketID());
+        PacketCollector response = connection.createPacketCollector(responseFilter);
+        
+        // Send create & join packet.
+        connection.sendPacket(requestPrivacy);
+        
+        // Wait up to a certain number of seconds for a reply.
+        Privacy privacyAnswer =
+            (Privacy) response.nextResult(SmackConfiguration.getPacketReplyTimeout());
+        
+        // Stop queuing results
+        response.cancel();
+
+        // Interprete the result and answer the privacy only if it is valid
+        if (privacyAnswer == null) {
+            throw new XMPPException("No response from server.");
+        }
+        else if (privacyAnswer.getError() != null) {
+            throw new XMPPException(privacyAnswer.getError());
+        }
+        return privacyAnswer;
+	}
+	
+	/**
+	 * Send the {@link Privacy} packet to the server in order to modify the server privacy and 
+	 * waits for the answer.
+	 * 
+	 * @param requestPrivacy is the {@link Privacy} packet configured properly whose xml will be sent
+	 * to the server.
+	 * @return a new {@link Privacy} with the data received from the server.
+	 * @exception XMPPException if the request or the answer failed, it raises an exception.
+	 */ 
+	private Packet setRequest(Privacy requestPrivacy) throws XMPPException {
+		
+		// The request is a get iq type
+		requestPrivacy.setType(Privacy.Type.SET);
+		requestPrivacy.setFrom(this.getUser());
+		
+		// Filter packets looking for an answer from the server.
+		PacketFilter responseFilter = new PacketIDFilter(requestPrivacy.getPacketID());
+        PacketCollector response = connection.createPacketCollector(responseFilter);
+        
+        // Send create & join packet.
+        connection.sendPacket(requestPrivacy);
+        
+        // Wait up to a certain number of seconds for a reply.
+        Packet privacyAnswer = response.nextResult(SmackConfiguration.getPacketReplyTimeout());
+        
+        // Stop queuing results
+        response.cancel();
+
+        // Interprete the result and answer the privacy only if it is valid
+        if (privacyAnswer == null) {
+            throw new XMPPException("No response from server.");
+        } else if (privacyAnswer.getError() != null) {
+            throw new XMPPException(privacyAnswer.getError());
+        }
+        return privacyAnswer;
+	}
+
+	/**
+	 * Answer a privacy containing the list structre without {@link PrivacyItem}.
+	 * 
+	 * @return a Privacy with the list names.
+     * @throws XMPPException if an error occurs.
+	 */ 
+	private Privacy getPrivacyWithListNames() throws XMPPException {
+		
+		// The request of the list is an empty privacy message
+		Privacy request = new Privacy();
+		
+		// Send the package to the server and get the answer
+		return getRequest(request);
+	}
+	
+    /**
+     * Answer the active privacy list.
+     * 
+     * @return the privacy list of the active list.
+     * @throws XMPPException if an error occurs.
+     */ 
+    public PrivacyList getActiveList() throws XMPPException {
+        Privacy privacyAnswer = this.getPrivacyWithListNames();
+        String listName = privacyAnswer.getActiveName();
+        boolean isDefaultAndActive = privacyAnswer.getActiveName() != null
+                && privacyAnswer.getDefaultName() != null
+                && privacyAnswer.getActiveName().equals(
+                privacyAnswer.getDefaultName());
+        return new PrivacyList(true, isDefaultAndActive, listName, getPrivacyListItems(listName));
+    }
+    
+    /**
+     * Answer the default privacy list.
+     * 
+     * @return the privacy list of the default list.
+     * @throws XMPPException if an error occurs.
+     */ 
+    public PrivacyList getDefaultList() throws XMPPException {
+        Privacy privacyAnswer = this.getPrivacyWithListNames();
+        String listName = privacyAnswer.getDefaultName();
+        boolean isDefaultAndActive = privacyAnswer.getActiveName() != null
+                && privacyAnswer.getDefaultName() != null
+                && privacyAnswer.getActiveName().equals(
+                privacyAnswer.getDefaultName());
+        return new PrivacyList(isDefaultAndActive, true, listName, getPrivacyListItems(listName));
+    }
+    
+    /**
+     * Answer the privacy list items under listName with the allowed and blocked permissions.
+     * 
+     * @param listName the name of the list to get the allowed and blocked permissions.
+     * @return a list of privacy items under the list listName.
+     * @throws XMPPException if an error occurs.
+     */ 
+    private List<PrivacyItem> getPrivacyListItems(String listName) throws XMPPException {
+        
+        // The request of the list is an privacy message with an empty list
+        Privacy request = new Privacy();
+        request.setPrivacyList(listName, new ArrayList<PrivacyItem>());
+        
+        // Send the package to the server and get the answer
+        Privacy privacyAnswer = getRequest(request);
+        
+        return privacyAnswer.getPrivacyList(listName);
+    }
+    
+	/**
+	 * Answer the privacy list items under listName with the allowed and blocked permissions.
+	 * 
+	 * @param listName the name of the list to get the allowed and blocked permissions.
+	 * @return a privacy list under the list listName.
+     * @throws XMPPException if an error occurs.
+	 */ 
+	public PrivacyList getPrivacyList(String listName) throws XMPPException {
+		
+        return new PrivacyList(false, false, listName, getPrivacyListItems(listName));
+	}
+	
+    /**
+     * Answer every privacy list with the allowed and blocked permissions.
+     * 
+     * @return an array of privacy lists.
+     * @throws XMPPException if an error occurs.
+     */ 
+    public PrivacyList[] getPrivacyLists() throws XMPPException {
+        Privacy privacyAnswer = this.getPrivacyWithListNames();
+        Set<String> names = privacyAnswer.getPrivacyListNames();
+        PrivacyList[] lists = new PrivacyList[names.size()];
+        boolean isActiveList;
+        boolean isDefaultList;
+        int index=0;
+        for (String listName : names) {
+            isActiveList = listName.equals(privacyAnswer.getActiveName());
+            isDefaultList = listName.equals(privacyAnswer.getDefaultName());
+            lists[index] = new PrivacyList(isActiveList, isDefaultList,
+                    listName, getPrivacyListItems(listName));
+            index = index + 1;
+        }
+        return lists;
+    }
+
+    
+	/**
+	 * Set or change the active list to listName.
+	 * 
+	 * @param listName the list name to set as the active one.
+	 * @exception XMPPException if the request or the answer failed, it raises an exception.
+	 */ 
+	public void setActiveListName(String listName) throws XMPPException {
+		
+		// The request of the list is an privacy message with an empty list
+		Privacy request = new Privacy();
+		request.setActiveName(listName);
+		
+		// Send the package to the server
+		setRequest(request);
+	}
+
+	/**
+	 * Client declines the use of active lists.
+     *
+     * @throws XMPPException if an error occurs.
+	 */ 
+	public void declineActiveList() throws XMPPException {
+		
+		// The request of the list is an privacy message with an empty list
+		Privacy request = new Privacy();
+		request.setDeclineActiveList(true);
+		
+		// Send the package to the server
+		setRequest(request);
+	}
+
+	/**
+	 * Set or change the default list to listName.
+	 * 
+	 * @param listName the list name to set as the default one.
+	 * @exception XMPPException if the request or the answer failed, it raises an exception.
+	 */ 
+	public void setDefaultListName(String listName) throws XMPPException {
+		
+		// The request of the list is an privacy message with an empty list
+		Privacy request = new Privacy();
+		request.setDefaultName(listName);
+		
+		// Send the package to the server
+		setRequest(request);
+	}
+	
+	/**
+	 * Client declines the use of default lists.
+     *
+     * @throws XMPPException if an error occurs.
+	 */ 
+	public void declineDefaultList() throws XMPPException {
+		
+		// The request of the list is an privacy message with an empty list
+		Privacy request = new Privacy();
+		request.setDeclineDefaultList(true);
+		
+		// Send the package to the server
+		setRequest(request);
+	}
+	
+	/**
+	 * The client has created a new list. It send the new one to the server.
+	 * 
+     * @param listName the list that has changed its content.
+     * @param privacyItems a List with every privacy item in the list.
+     * @throws XMPPException if an error occurs.
+	 */ 
+	public void createPrivacyList(String listName, List<PrivacyItem> privacyItems) throws XMPPException {
+
+		this.updatePrivacyList(listName, privacyItems);
+	}
+
+    /**
+     * The client has edited an existing list. It updates the server content with the resulting 
+     * list of privacy items. The {@link PrivacyItem} list MUST contain all elements in the 
+     * list (not the "delta").
+     * 
+     * @param listName the list that has changed its content.
+     * @param privacyItems a List with every privacy item in the list.
+     * @throws XMPPException if an error occurs.
+     */ 
+    public void updatePrivacyList(String listName, List<PrivacyItem> privacyItems) throws XMPPException {
+
+        // Build the privacy package to add or update the new list
+        Privacy request = new Privacy();
+        request.setPrivacyList(listName, privacyItems);
+
+        // Send the package to the server
+        setRequest(request);
+    }
+    
+	/**
+	 * Remove a privacy list.
+	 * 
+     * @param listName the list that has changed its content.
+     * @throws XMPPException if an error occurs.
+	 */ 
+	public void deletePrivacyList(String listName) throws XMPPException {
+		
+		// The request of the list is an privacy message with an empty list
+		Privacy request = new Privacy();
+		request.setPrivacyList(listName, new ArrayList<PrivacyItem>());
+
+		// Send the package to the server
+		setRequest(request);
+	}
+	
+    /**
+     * Adds a packet listener that will be notified of any new update in the user
+     * privacy communication.
+     *
+     * @param listener a packet listener.
+     */
+    public void addListener(PrivacyListListener listener) {
+        // Keep track of the listener so that we can manually deliver extra
+        // messages to it later if needed.
+        synchronized (listeners) {
+            listeners.add(listener);
+        }
+    }    
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/ReconnectionManager.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/ReconnectionManager.java
index cc3e3af..7e3c1de 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/ReconnectionManager.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/ReconnectionManager.java
@@ -15,213 +15,213 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jivesoftware.smack;
-
-import org.jivesoftware.smack.packet.StreamError;
-import java.util.Random;
-/**
- * Handles the automatic reconnection process. Every time a connection is dropped without
- * the application explictly closing it, the manager automatically tries to reconnect to
- * the server.<p>
- *
- * The reconnection mechanism will try to reconnect periodically:
- * <ol>
- *  <li>For the first minute it will attempt to connect once every ten seconds.
- *  <li>For the next five minutes it will attempt to connect once a minute.
- *  <li>If that fails it will indefinitely try to connect once every five minutes.
- * </ol>
- *
- * @author Francisco Vives
- */
-public class ReconnectionManager implements ConnectionListener {
-
-    // Holds the connection to the server
-    private Connection connection;
-    private Thread reconnectionThread;
-    private int randomBase = new Random().nextInt(11) + 5; // between 5 and 15 seconds
-    
-    // Holds the state of the reconnection
-    boolean done = false;
-
-    static {
-        // Create a new PrivacyListManager on every established connection. In the init()
-        // method of PrivacyListManager, we'll add a listener that will delete the
-        // instance when the connection is closed.
-        Connection.addConnectionCreationListener(new ConnectionCreationListener() {
-            public void connectionCreated(Connection connection) {
-                connection.addConnectionListener(new ReconnectionManager(connection));
-            }
-        });
-    }
-
-    private ReconnectionManager(Connection connection) {
-        this.connection = connection;
-    }
-
-
-    /**
-     * Returns true if the reconnection mechanism is enabled.
-     *
-     * @return true if automatic reconnections are allowed.
-     */
-    private boolean isReconnectionAllowed() {
+package org.jivesoftware.smack;
+
+import org.jivesoftware.smack.packet.StreamError;
+import java.util.Random;
+/**
+ * Handles the automatic reconnection process. Every time a connection is dropped without
+ * the application explictly closing it, the manager automatically tries to reconnect to
+ * the server.<p>
+ *
+ * The reconnection mechanism will try to reconnect periodically:
+ * <ol>
+ *  <li>For the first minute it will attempt to connect once every ten seconds.
+ *  <li>For the next five minutes it will attempt to connect once a minute.
+ *  <li>If that fails it will indefinitely try to connect once every five minutes.
+ * </ol>
+ *
+ * @author Francisco Vives
+ */
+public class ReconnectionManager implements ConnectionListener {
+
+    // Holds the connection to the server
+    private Connection connection;
+    private Thread reconnectionThread;
+    private int randomBase = new Random().nextInt(11) + 5; // between 5 and 15 seconds
+    
+    // Holds the state of the reconnection
+    boolean done = false;
+
+    static {
+        // Create a new PrivacyListManager on every established connection. In the init()
+        // method of PrivacyListManager, we'll add a listener that will delete the
+        // instance when the connection is closed.
+        Connection.addConnectionCreationListener(new ConnectionCreationListener() {
+            public void connectionCreated(Connection connection) {
+                connection.addConnectionListener(new ReconnectionManager(connection));
+            }
+        });
+    }
+
+    private ReconnectionManager(Connection connection) {
+        this.connection = connection;
+    }
+
+
+    /**
+     * Returns true if the reconnection mechanism is enabled.
+     *
+     * @return true if automatic reconnections are allowed.
+     */
+    private boolean isReconnectionAllowed() {
         return !done && !connection.isConnected()
                 && connection.isReconnectionAllowed();
-    }
-
-    /**
-     * Starts a reconnection mechanism if it was configured to do that.
-     * The algorithm is been executed when the first connection error is detected.
-     * <p/>
-     * The reconnection mechanism will try to reconnect periodically in this way:
-     * <ol>
-     * <li>First it will try 6 times every 10 seconds.
-     * <li>Then it will try 10 times every 1 minute.
-     * <li>Finally it will try indefinitely every 5 minutes.
-     * </ol>
-     */
-    synchronized protected void reconnect() {
-        if (this.isReconnectionAllowed()) {
-            // Since there is no thread running, creates a new one to attempt
-            // the reconnection.
-            // avoid to run duplicated reconnectionThread -- fd: 16/09/2010
-            if (reconnectionThread!=null && reconnectionThread.isAlive()) return;
-            
-            reconnectionThread = new Thread() {
-             			
-                /**
-                 * Holds the current number of reconnection attempts
-                 */
-                private int attempts = 0;
-
-                /**
-                 * Returns the number of seconds until the next reconnection attempt.
-                 *
-                 * @return the number of seconds until the next reconnection attempt.
-                 */
-                private int timeDelay() {
-                    attempts++;
-                    if (attempts > 13) {
-                	return randomBase*6*5;      // between 2.5 and 7.5 minutes (~5 minutes)
-                    }
-                    if (attempts > 7) {
-                	return randomBase*6;       // between 30 and 90 seconds (~1 minutes)
-                    }
-                    return randomBase;       // 10 seconds
-                }
-
-                /**
-                 * The process will try the reconnection until the connection succeed or the user
-                 * cancell it
-                 */
-                public void run() {
-                    // The process will try to reconnect until the connection is established or
-                    // the user cancel the reconnection process {@link Connection#disconnect()}
-                    while (ReconnectionManager.this.isReconnectionAllowed()) {
-                        // Find how much time we should wait until the next reconnection
-                        int remainingSeconds = timeDelay();
-                        // Sleep until we're ready for the next reconnection attempt. Notify
-                        // listeners once per second about how much time remains before the next
-                        // reconnection attempt.
-                        while (ReconnectionManager.this.isReconnectionAllowed() &&
-                                remainingSeconds > 0)
-                        {
-                            try {
-                                Thread.sleep(1000);
-                                remainingSeconds--;
-                                ReconnectionManager.this
-                                        .notifyAttemptToReconnectIn(remainingSeconds);
-                            }
-                            catch (InterruptedException e1) {
-                                e1.printStackTrace();
-                                // Notify the reconnection has failed
-                                ReconnectionManager.this.notifyReconnectionFailed(e1);
-                            }
-                        }
-
-                        // Makes a reconnection attempt
-                        try {
-                            if (ReconnectionManager.this.isReconnectionAllowed()) {
-                                connection.connect();
-                            }
-                        }
-                        catch (XMPPException e) {
-                            // Fires the failed reconnection notification
-                            ReconnectionManager.this.notifyReconnectionFailed(e);
-                        }
-                    }
-                }
-            };
-            reconnectionThread.setName("Smack Reconnection Manager");
-            reconnectionThread.setDaemon(true);
-            reconnectionThread.start();
-        }
-    }
-
-    /**
-     * Fires listeners when a reconnection attempt has failed.
-     *
-     * @param exception the exception that occured.
-     */
-    protected void notifyReconnectionFailed(Exception exception) {
+    }
+
+    /**
+     * Starts a reconnection mechanism if it was configured to do that.
+     * The algorithm is been executed when the first connection error is detected.
+     * <p/>
+     * The reconnection mechanism will try to reconnect periodically in this way:
+     * <ol>
+     * <li>First it will try 6 times every 10 seconds.
+     * <li>Then it will try 10 times every 1 minute.
+     * <li>Finally it will try indefinitely every 5 minutes.
+     * </ol>
+     */
+    synchronized protected void reconnect() {
+        if (this.isReconnectionAllowed()) {
+            // Since there is no thread running, creates a new one to attempt
+            // the reconnection.
+            // avoid to run duplicated reconnectionThread -- fd: 16/09/2010
+            if (reconnectionThread!=null && reconnectionThread.isAlive()) return;
+            
+            reconnectionThread = new Thread() {
+             			
+                /**
+                 * Holds the current number of reconnection attempts
+                 */
+                private int attempts = 0;
+
+                /**
+                 * Returns the number of seconds until the next reconnection attempt.
+                 *
+                 * @return the number of seconds until the next reconnection attempt.
+                 */
+                private int timeDelay() {
+                    attempts++;
+                    if (attempts > 13) {
+                	return randomBase*6*5;      // between 2.5 and 7.5 minutes (~5 minutes)
+                    }
+                    if (attempts > 7) {
+                	return randomBase*6;       // between 30 and 90 seconds (~1 minutes)
+                    }
+                    return randomBase;       // 10 seconds
+                }
+
+                /**
+                 * The process will try the reconnection until the connection succeed or the user
+                 * cancell it
+                 */
+                public void run() {
+                    // The process will try to reconnect until the connection is established or
+                    // the user cancel the reconnection process {@link Connection#disconnect()}
+                    while (ReconnectionManager.this.isReconnectionAllowed()) {
+                        // Find how much time we should wait until the next reconnection
+                        int remainingSeconds = timeDelay();
+                        // Sleep until we're ready for the next reconnection attempt. Notify
+                        // listeners once per second about how much time remains before the next
+                        // reconnection attempt.
+                        while (ReconnectionManager.this.isReconnectionAllowed() &&
+                                remainingSeconds > 0)
+                        {
+                            try {
+                                Thread.sleep(1000);
+                                remainingSeconds--;
+                                ReconnectionManager.this
+                                        .notifyAttemptToReconnectIn(remainingSeconds);
+                            }
+                            catch (InterruptedException e1) {
+                                e1.printStackTrace();
+                                // Notify the reconnection has failed
+                                ReconnectionManager.this.notifyReconnectionFailed(e1);
+                            }
+                        }
+
+                        // Makes a reconnection attempt
+                        try {
+                            if (ReconnectionManager.this.isReconnectionAllowed()) {
+                                connection.connect();
+                            }
+                        }
+                        catch (XMPPException e) {
+                            // Fires the failed reconnection notification
+                            ReconnectionManager.this.notifyReconnectionFailed(e);
+                        }
+                    }
+                }
+            };
+            reconnectionThread.setName("Smack Reconnection Manager");
+            reconnectionThread.setDaemon(true);
+            reconnectionThread.start();
+        }
+    }
+
+    /**
+     * Fires listeners when a reconnection attempt has failed.
+     *
+     * @param exception the exception that occured.
+     */
+    protected void notifyReconnectionFailed(Exception exception) {
         if (isReconnectionAllowed()) {
             for (ConnectionListener listener : connection.connectionListeners) {
-                listener.reconnectionFailed(exception);
-            }
-        }
-    }
-
-    /**
-     * Fires listeners when The Connection will retry a reconnection. Expressed in seconds.
-     *
-     * @param seconds the number of seconds that a reconnection will be attempted in.
-     */
-    protected void notifyAttemptToReconnectIn(int seconds) {
+                listener.reconnectionFailed(exception);
+            }
+        }
+    }
+
+    /**
+     * Fires listeners when The Connection will retry a reconnection. Expressed in seconds.
+     *
+     * @param seconds the number of seconds that a reconnection will be attempted in.
+     */
+    protected void notifyAttemptToReconnectIn(int seconds) {
         if (isReconnectionAllowed()) {
             for (ConnectionListener listener : connection.connectionListeners) {
-                listener.reconnectingIn(seconds);
-            }
-        }
-    }
-
-    public void connectionClosed() {
-        done = true;
-    }
-
-    public void connectionClosedOnError(Exception e) {
-        done = false;
-        if (e instanceof XMPPException) {
-            XMPPException xmppEx = (XMPPException) e;
-            StreamError error = xmppEx.getStreamError();
-
-            // Make sure the error is not null
-            if (error != null) {
-                String reason = error.getCode();
-
-                if ("conflict".equals(reason)) {
-                    return;
-                }
-            }
-        }
-
-        if (this.isReconnectionAllowed()) {
-            this.reconnect();
-        }
-    }
-
-    public void reconnectingIn(int seconds) {
-        // ignore
-    }
-
-    public void reconnectionFailed(Exception e) {
-        // ignore
-    }
-
-    /**
-     * The connection has successfull gotten connected.
-     */
-    public void reconnectionSuccessful() {
-        // ignore
-    }
-
+                listener.reconnectingIn(seconds);
+            }
+        }
+    }
+
+    public void connectionClosed() {
+        done = true;
+    }
+
+    public void connectionClosedOnError(Exception e) {
+        done = false;
+        if (e instanceof XMPPException) {
+            XMPPException xmppEx = (XMPPException) e;
+            StreamError error = xmppEx.getStreamError();
+
+            // Make sure the error is not null
+            if (error != null) {
+                String reason = error.getCode();
+
+                if ("conflict".equals(reason)) {
+                    return;
+                }
+            }
+        }
+
+        if (this.isReconnectionAllowed()) {
+            this.reconnect();
+        }
+    }
+
+    public void reconnectingIn(int seconds) {
+        // ignore
+    }
+
+    public void reconnectionFailed(Exception e) {
+        // ignore
+    }
+
+    /**
+     * The connection has successfull gotten connected.
+     */
+    public void reconnectionSuccessful() {
+        // ignore
+    }
+
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/SASLAuthentication.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/SASLAuthentication.java
index 6f8b5bf..abf08c8 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/SASLAuthentication.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/SASLAuthentication.java
@@ -1,591 +1,591 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack;
-
-import org.jivesoftware.smack.filter.PacketIDFilter;
-import org.jivesoftware.smack.packet.Bind;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smack.packet.Session;
-import org.jivesoftware.smack.sasl.*;
-
-import javax.security.auth.callback.CallbackHandler;
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.util.*;
-
-/**
- * <p>This class is responsible authenticating the user using SASL, binding the resource
- * to the connection and establishing a session with the server.</p>
- *
- * <p>Once TLS has been negotiated (i.e. the connection has been secured) it is possible to
- * register with the server, authenticate using Non-SASL or authenticate using SASL. If the
- * server supports SASL then Smack will first try to authenticate using SASL. But if that
- * fails then Non-SASL will be tried.</p>
- *
- * <p>The server may support many SASL mechanisms to use for authenticating. Out of the box
- * Smack provides several SASL mechanisms, but it is possible to register new SASL Mechanisms. Use
- * {@link #registerSASLMechanism(String, Class)} to register a new mechanisms. A registered
- * mechanism wont be used until {@link #supportSASLMechanism(String, int)} is called. By default,
- * the list of supported SASL mechanisms is determined from the {@link SmackConfiguration}. </p>
- *
- * <p>Once the user has been authenticated with SASL, it is necessary to bind a resource for
- * the connection. If no resource is passed in {@link #authenticate(String, String, String)}
- * then the server will assign a resource for the connection. In case a resource is passed
- * then the server will receive the desired resource but may assign a modified resource for
- * the connection.</p>
- *
- * <p>Once a resource has been binded and if the server supports sessions then Smack will establish
- * a session so that instant messaging and presence functionalities may be used.</p>
- *
- * @see org.jivesoftware.smack.sasl.SASLMechanism
- *
- * @author Gaston Dombiak
- * @author Jay Kline
- */
-public class SASLAuthentication implements UserAuthentication {
-
-    private static Map<String, Class<? extends SASLMechanism>> implementedMechanisms = new HashMap<String, Class<? extends SASLMechanism>>();
-    private static List<String> mechanismsPreferences = new ArrayList<String>();
-
-    private Connection connection;
-    private Collection<String> serverMechanisms = new ArrayList<String>();
-    private SASLMechanism currentMechanism = null;
-    /**
-     * Boolean indicating if SASL negotiation has finished and was successful.
-     */
-    private boolean saslNegotiated;
-    /**
-     * Boolean indication if SASL authentication has failed. When failed the server may end
-     * the connection.
-     */
-    private boolean saslFailed;
-    private boolean resourceBinded;
-    private boolean sessionSupported;
-    /**
-     * The SASL related error condition if there was one provided by the server.
-     */
-    private String errorCondition;
-
-    static {
-
-        // Register SASL mechanisms supported by Smack
-        registerSASLMechanism("EXTERNAL", SASLExternalMechanism.class);
-        registerSASLMechanism("GSSAPI", SASLGSSAPIMechanism.class);
-        registerSASLMechanism("DIGEST-MD5", SASLDigestMD5Mechanism.class);
-        registerSASLMechanism("CRAM-MD5", SASLCramMD5Mechanism.class);
-        registerSASLMechanism("PLAIN", SASLPlainMechanism.class);
-        registerSASLMechanism("ANONYMOUS", SASLAnonymous.class);
-
-        supportSASLMechanism("GSSAPI",0);
-        supportSASLMechanism("DIGEST-MD5",1);
-        supportSASLMechanism("CRAM-MD5",2);
-        supportSASLMechanism("PLAIN",3);
-        supportSASLMechanism("ANONYMOUS",4);
-
-    }
-
-    /**
-     * Registers a new SASL mechanism
-     *
-     * @param name   common name of the SASL mechanism. E.g.: PLAIN, DIGEST-MD5 or KERBEROS_V4.
-     * @param mClass a SASLMechanism subclass.
-     */
-    public static void registerSASLMechanism(String name, Class<? extends SASLMechanism> mClass) {
-        implementedMechanisms.put(name, mClass);
-    }
-
-    /**
-     * Unregisters an existing SASL mechanism. Once the mechanism has been unregistered it won't
-     * be possible to authenticate users using the removed SASL mechanism. It also removes the
-     * mechanism from the supported list.
-     *
-     * @param name common name of the SASL mechanism. E.g.: PLAIN, DIGEST-MD5 or KERBEROS_V4.
-     */
-    public static void unregisterSASLMechanism(String name) {
-        implementedMechanisms.remove(name);
-        mechanismsPreferences.remove(name);
-    }
-
-
-    /**
-     * Registers a new SASL mechanism in the specified preference position. The client will try
-     * to authenticate using the most prefered SASL mechanism that is also supported by the server.
-     * The SASL mechanism must be registered via {@link #registerSASLMechanism(String, Class)}
-     *
-     * @param name common name of the SASL mechanism. E.g.: PLAIN, DIGEST-MD5 or KERBEROS_V4.
-     */
-    public static void supportSASLMechanism(String name) {
-        mechanismsPreferences.add(0, name);
-    }
-
-    /**
-     * Registers a new SASL mechanism in the specified preference position. The client will try
-     * to authenticate using the most prefered SASL mechanism that is also supported by the server.
-     * Use the <tt>index</tt> parameter to set the level of preference of the new SASL mechanism.
-     * A value of 0 means that the mechanism is the most prefered one. The SASL mechanism must be
-     * registered via {@link #registerSASLMechanism(String, Class)}
-     *
-     * @param name common name of the SASL mechanism. E.g.: PLAIN, DIGEST-MD5 or KERBEROS_V4.
-     * @param index preference position amongst all the implemented SASL mechanism. Starts with 0.
-     */
-    public static void supportSASLMechanism(String name, int index) {
-        mechanismsPreferences.add(index, name);
-    }
-
-    /**
-     * Un-supports an existing SASL mechanism. Once the mechanism has been unregistered it won't
-     * be possible to authenticate users using the removed SASL mechanism. Note that the mechanism
-     * is still registered, but will just not be used.
-     *
-     * @param name common name of the SASL mechanism. E.g.: PLAIN, DIGEST-MD5 or KERBEROS_V4.
-     */
-    public static void unsupportSASLMechanism(String name) {
-        mechanismsPreferences.remove(name);
-    }
-
-    /**
-     * Returns the registerd SASLMechanism classes sorted by the level of preference.
-     *
-     * @return the registerd SASLMechanism classes sorted by the level of preference.
-     */
-    public static List<Class<? extends SASLMechanism>> getRegisterSASLMechanisms() {
-        List<Class<? extends SASLMechanism>> answer = new ArrayList<Class<? extends SASLMechanism>>();
-        for (String mechanismsPreference : mechanismsPreferences) {
-            answer.add(implementedMechanisms.get(mechanismsPreference));
-        }
-        return answer;
-    }
-
-    SASLAuthentication(Connection connection) {
-        super();
-        this.connection = connection;
-        this.init();
-    }
-
-    /**
-     * Returns true if the server offered ANONYMOUS SASL as a way to authenticate users.
-     *
-     * @return true if the server offered ANONYMOUS SASL as a way to authenticate users.
-     */
-    public boolean hasAnonymousAuthentication() {
-        return serverMechanisms.contains("ANONYMOUS");
-    }
-
-    /**
-     * Returns true if the server offered SASL authentication besides ANONYMOUS SASL.
-     *
-     * @return true if the server offered SASL authentication besides ANONYMOUS SASL.
-     */
-    public boolean hasNonAnonymousAuthentication() {
-        return !serverMechanisms.isEmpty() && (serverMechanisms.size() != 1 || !hasAnonymousAuthentication());
-    }
-
-    /**
-     * Performs SASL authentication of the specified user. If SASL authentication was successful
-     * then resource binding and session establishment will be performed. This method will return
-     * the full JID provided by the server while binding a resource to the connection.<p>
-     *
-     * The server may assign a full JID with a username or resource different than the requested
-     * by this method.
-     *
-     * @param username the username that is authenticating with the server.
-     * @param resource the desired resource.
-     * @param cbh the CallbackHandler used to get information from the user
-     * @return the full JID provided by the server while binding a resource to the connection.
-     * @throws XMPPException if an error occures while authenticating.
-     */
-    public String authenticate(String username, String resource, CallbackHandler cbh) 
-            throws XMPPException {
-        // Locate the SASLMechanism to use
-        String selectedMechanism = null;
-        for (String mechanism : mechanismsPreferences) {
-            if (implementedMechanisms.containsKey(mechanism) &&
-                    serverMechanisms.contains(mechanism)) {
-                selectedMechanism = mechanism;
-                break;
-            }
-        }
-        if (selectedMechanism != null) {
-            // A SASL mechanism was found. Authenticate using the selected mechanism and then
-            // proceed to bind a resource
-            try {
-                Class<? extends SASLMechanism> mechanismClass = implementedMechanisms.get(selectedMechanism);
-                Constructor<? extends SASLMechanism> constructor = mechanismClass.getConstructor(SASLAuthentication.class);
-                currentMechanism = constructor.newInstance(this);
-                // Trigger SASL authentication with the selected mechanism. We use
-                // connection.getHost() since GSAPI requires the FQDN of the server, which
-                // may not match the XMPP domain.
-                currentMechanism.authenticate(username, connection.getHost(), cbh);
-
-                // Wait until SASL negotiation finishes
-                synchronized (this) {
-                    if (!saslNegotiated && !saslFailed) {
-                        try {
-                            wait(30000);
-                        }
-                        catch (InterruptedException e) {
-                            // Ignore
-                        }
-                    }
-                }
-
-                if (saslFailed) {
-                    // SASL authentication failed and the server may have closed the connection
-                    // so throw an exception
-                    if (errorCondition != null) {
-                        throw new XMPPException("SASL authentication " +
-                                selectedMechanism + " failed: " + errorCondition);
-                    }
-                    else {
-                        throw new XMPPException("SASL authentication failed using mechanism " +
-                                selectedMechanism);
-                    }
-                }
-
-                if (saslNegotiated) {
-                    // Bind a resource for this connection and
-                    return bindResourceAndEstablishSession(resource);
-                } else {
-                    // SASL authentication failed
-                }
-            }
-            catch (XMPPException e) {
-                throw e;
-            }
-            catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-        else {
-            throw new XMPPException("SASL Authentication failed. No known authentication mechanisims.");
-        }
-        throw new XMPPException("SASL authentication failed");
-    }
-
-    /**
-     * Performs SASL authentication of the specified user. If SASL authentication was successful
-     * then resource binding and session establishment will be performed. This method will return
-     * the full JID provided by the server while binding a resource to the connection.<p>
-     *
-     * The server may assign a full JID with a username or resource different than the requested
-     * by this method.
-     *
-     * @param username the username that is authenticating with the server.
-     * @param password the password to send to the server.
-     * @param resource the desired resource.
-     * @return the full JID provided by the server while binding a resource to the connection.
-     * @throws XMPPException if an error occures while authenticating.
-     */
-    public String authenticate(String username, String password, String resource)
-            throws XMPPException {
-        // Locate the SASLMechanism to use
-        String selectedMechanism = null;
-        for (String mechanism : mechanismsPreferences) {
-            if (implementedMechanisms.containsKey(mechanism) &&
-                    serverMechanisms.contains(mechanism)) {
-                selectedMechanism = mechanism;
-                break;
-            }
-        }
-        if (selectedMechanism != null) {
-            // A SASL mechanism was found. Authenticate using the selected mechanism and then
-            // proceed to bind a resource
-            try {
-                Class<? extends SASLMechanism> mechanismClass = implementedMechanisms.get(selectedMechanism);
-                Constructor<? extends SASLMechanism> constructor = mechanismClass.getConstructor(SASLAuthentication.class);
-                currentMechanism = constructor.newInstance(this);
-                // Trigger SASL authentication with the selected mechanism. We use
-                // connection.getHost() since GSAPI requires the FQDN of the server, which
-                // may not match the XMPP domain.    
-                
-                //The serviceName is basically the value that XMPP server sends to the client as being the location
-                //of the XMPP service we are trying to connect to. This should have the format: host [ "/" serv-name ]
-                //as per RFC-2831 guidelines
-                String serviceName = connection.getServiceName();               
-                currentMechanism.authenticate(username, connection.getHost(), serviceName, password);
-
-                // Wait until SASL negotiation finishes
-                synchronized (this) {
-                    if (!saslNegotiated && !saslFailed) {
-                        try {
-                            wait(30000);
-                        }
-                        catch (InterruptedException e) {
-                            // Ignore
-                        }
-                    }
-                }
-
-                if (saslFailed) {
-                    // SASL authentication failed and the server may have closed the connection
-                    // so throw an exception
-                    if (errorCondition != null) {
-                        throw new XMPPException("SASL authentication " +
-                                selectedMechanism + " failed: " + errorCondition);
-                    }
-                    else {
-                        throw new XMPPException("SASL authentication failed using mechanism " +
-                                selectedMechanism);
-                    }
-                }
-
-                if (saslNegotiated) {
-                    // Bind a resource for this connection and
-                    return bindResourceAndEstablishSession(resource);
-                }
-                else {
-                    // SASL authentication failed so try a Non-SASL authentication
-                    return new NonSASLAuthentication(connection)
-                            .authenticate(username, password, resource);
-                }
-            }
-            catch (XMPPException e) {
-                throw e;
-            }
-            catch (Exception e) {
-                e.printStackTrace();
-                // SASL authentication failed so try a Non-SASL authentication
-                return new NonSASLAuthentication(connection)
-                        .authenticate(username, password, resource);
-            }
-        }
-        else {
-            // No SASL method was found so try a Non-SASL authentication
-            return new NonSASLAuthentication(connection).authenticate(username, password, resource);
-        }
-    }
-
-    /**
-     * Performs ANONYMOUS SASL authentication. If SASL authentication was successful
-     * then resource binding and session establishment will be performed. This method will return
-     * the full JID provided by the server while binding a resource to the connection.<p>
-     *
-     * The server will assign a full JID with a randomly generated resource and possibly with
-     * no username.
-     *
-     * @return the full JID provided by the server while binding a resource to the connection.
-     * @throws XMPPException if an error occures while authenticating.
-     */
-    public String authenticateAnonymously() throws XMPPException {
-        try {
-            currentMechanism = new SASLAnonymous(this);
-            currentMechanism.authenticate(null,null,null,"");
-
-            // Wait until SASL negotiation finishes
-            synchronized (this) {
-                if (!saslNegotiated && !saslFailed) {
-                    try {
-                        wait(5000);
-                    }
-                    catch (InterruptedException e) {
-                        // Ignore
-                    }
-                }
-            }
-
-            if (saslFailed) {
-                // SASL authentication failed and the server may have closed the connection
-                // so throw an exception
-                if (errorCondition != null) {
-                    throw new XMPPException("SASL authentication failed: " + errorCondition);
-                }
-                else {
-                    throw new XMPPException("SASL authentication failed");
-                }
-            }
-
-            if (saslNegotiated) {
-                // Bind a resource for this connection and
-                return bindResourceAndEstablishSession(null);
-            }
-            else {
-                return new NonSASLAuthentication(connection).authenticateAnonymously();
-            }
-        } catch (IOException e) {
-            return new NonSASLAuthentication(connection).authenticateAnonymously();
-        }
-    }
-
-    private String bindResourceAndEstablishSession(String resource) throws XMPPException {
-        // Wait until server sends response containing the <bind> element
-        synchronized (this) {
-            if (!resourceBinded) {
-                try {
-                    wait(30000);
-                }
-                catch (InterruptedException e) {
-                    // Ignore
-                }
-            }
-        }
-
-        if (!resourceBinded) {
-            // Server never offered resource binding
-            throw new XMPPException("Resource binding not offered by server");
-        }
-
-        Bind bindResource = new Bind();
-        bindResource.setResource(resource);
-
-        PacketCollector collector = connection
-                .createPacketCollector(new PacketIDFilter(bindResource.getPacketID()));
-        // Send the packet
-        connection.sendPacket(bindResource);
-        // Wait up to a certain number of seconds for a response from the server.
-        Bind response = (Bind) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from the server.");
-        }
-        // If the server replied with an error, throw an exception.
-        else if (response.getType() == IQ.Type.ERROR) {
-            throw new XMPPException(response.getError());
-        }
-        String userJID = response.getJid();
-
-        if (sessionSupported) {
-            Session session = new Session();
-            collector = connection.createPacketCollector(new PacketIDFilter(session.getPacketID()));
-            // Send the packet
-            connection.sendPacket(session);
-            // Wait up to a certain number of seconds for a response from the server.
-            IQ ack = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-            collector.cancel();
-            if (ack == null) {
-                throw new XMPPException("No response from the server.");
-            }
-            // If the server replied with an error, throw an exception.
-            else if (ack.getType() == IQ.Type.ERROR) {
-                throw new XMPPException(ack.getError());
-            }
-        }
-        return userJID;
-    }
-
-    /**
-     * Sets the available SASL mechanism reported by the server. The server will report the
-     * available SASL mechanism once the TLS negotiation was successful. This information is
-     * stored and will be used when doing the authentication for logging in the user.
-     *
-     * @param mechanisms collection of strings with the available SASL mechanism reported
-     *                   by the server.
-     */
-    void setAvailableSASLMethods(Collection<String> mechanisms) {
-        this.serverMechanisms = mechanisms;
-    }
-
-    /**
-     * Returns true if the user was able to authenticate with the server usins SASL.
-     *
-     * @return true if the user was able to authenticate with the server usins SASL.
-     */
-    public boolean isAuthenticated() {
-        return saslNegotiated;
-    }
-
-    /**
-     * The server is challenging the SASL authentication we just sent. Forward the challenge
-     * to the current SASLMechanism we are using. The SASLMechanism will send a response to
-     * the server. The length of the challenge-response sequence varies according to the
-     * SASLMechanism in use.
-     *
-     * @param challenge a base64 encoded string representing the challenge.
-     * @throws IOException If a network error occures while authenticating.
-     */
-    void challengeReceived(String challenge) throws IOException {
-        currentMechanism.challengeReceived(challenge);
-    }
-
-    /**
-     * Notification message saying that SASL authentication was successful. The next step
-     * would be to bind the resource.
-     */
-    void authenticated() {
-        synchronized (this) {
-            saslNegotiated = true;
-            // Wake up the thread that is waiting in the #authenticate method
-            notify();
-        }
-    }
-
-    /**
-     * Notification message saying that SASL authentication has failed. The server may have
-     * closed the connection depending on the number of possible retries.
-     * 
-     * @deprecated replaced by {@see #authenticationFailed(String)}.
-     */
-    void authenticationFailed() {
-        authenticationFailed(null);
-    }
-
-    /**
-     * Notification message saying that SASL authentication has failed. The server may have
-     * closed the connection depending on the number of possible retries.
-     * 
-     * @param condition the error condition provided by the server.
-     */
-    void authenticationFailed(String condition) {
-        synchronized (this) {
-            saslFailed = true;
-            errorCondition = condition;
-            // Wake up the thread that is waiting in the #authenticate method
-            notify();
-        }
-    }
-
-    /**
-     * Notification message saying that the server requires the client to bind a
-     * resource to the stream.
-     */
-    void bindingRequired() {
-        synchronized (this) {
-            resourceBinded = true;
-            // Wake up the thread that is waiting in the #authenticate method
-            notify();
-        }
-    }
-
-    public void send(Packet stanza) {
-        connection.sendPacket(stanza);
-    }
-
-    /**
-     * Notification message saying that the server supports sessions. When a server supports
-     * sessions the client needs to send a Session packet after successfully binding a resource
-     * for the session.
-     */
-    void sessionsSupported() {
-        sessionSupported = true;
-    }
-    
-    /**
-     * Initializes the internal state in order to be able to be reused. The authentication
-     * is used by the connection at the first login and then reused after the connection
-     * is disconnected and then reconnected.
-     */
-    protected void init() {
-        saslNegotiated = false;
-        saslFailed = false;
-        resourceBinded = false;
-        sessionSupported = false;
-    }
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack;
+
+import org.jivesoftware.smack.filter.PacketIDFilter;
+import org.jivesoftware.smack.packet.Bind;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.packet.Session;
+import org.jivesoftware.smack.sasl.*;
+
+import javax.security.auth.callback.CallbackHandler;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.util.*;
+
+/**
+ * <p>This class is responsible authenticating the user using SASL, binding the resource
+ * to the connection and establishing a session with the server.</p>
+ *
+ * <p>Once TLS has been negotiated (i.e. the connection has been secured) it is possible to
+ * register with the server, authenticate using Non-SASL or authenticate using SASL. If the
+ * server supports SASL then Smack will first try to authenticate using SASL. But if that
+ * fails then Non-SASL will be tried.</p>
+ *
+ * <p>The server may support many SASL mechanisms to use for authenticating. Out of the box
+ * Smack provides several SASL mechanisms, but it is possible to register new SASL Mechanisms. Use
+ * {@link #registerSASLMechanism(String, Class)} to register a new mechanisms. A registered
+ * mechanism wont be used until {@link #supportSASLMechanism(String, int)} is called. By default,
+ * the list of supported SASL mechanisms is determined from the {@link SmackConfiguration}. </p>
+ *
+ * <p>Once the user has been authenticated with SASL, it is necessary to bind a resource for
+ * the connection. If no resource is passed in {@link #authenticate(String, String, String)}
+ * then the server will assign a resource for the connection. In case a resource is passed
+ * then the server will receive the desired resource but may assign a modified resource for
+ * the connection.</p>
+ *
+ * <p>Once a resource has been binded and if the server supports sessions then Smack will establish
+ * a session so that instant messaging and presence functionalities may be used.</p>
+ *
+ * @see org.jivesoftware.smack.sasl.SASLMechanism
+ *
+ * @author Gaston Dombiak
+ * @author Jay Kline
+ */
+public class SASLAuthentication implements UserAuthentication {
+
+    private static Map<String, Class<? extends SASLMechanism>> implementedMechanisms = new HashMap<String, Class<? extends SASLMechanism>>();
+    private static List<String> mechanismsPreferences = new ArrayList<String>();
+
+    private Connection connection;
+    private Collection<String> serverMechanisms = new ArrayList<String>();
+    private SASLMechanism currentMechanism = null;
+    /**
+     * Boolean indicating if SASL negotiation has finished and was successful.
+     */
+    private boolean saslNegotiated;
+    /**
+     * Boolean indication if SASL authentication has failed. When failed the server may end
+     * the connection.
+     */
+    private boolean saslFailed;
+    private boolean resourceBinded;
+    private boolean sessionSupported;
+    /**
+     * The SASL related error condition if there was one provided by the server.
+     */
+    private String errorCondition;
+
+    static {
+
+        // Register SASL mechanisms supported by Smack
+        registerSASLMechanism("EXTERNAL", SASLExternalMechanism.class);
+        registerSASLMechanism("GSSAPI", SASLGSSAPIMechanism.class);
+        registerSASLMechanism("DIGEST-MD5", SASLDigestMD5Mechanism.class);
+        registerSASLMechanism("CRAM-MD5", SASLCramMD5Mechanism.class);
+        registerSASLMechanism("PLAIN", SASLPlainMechanism.class);
+        registerSASLMechanism("ANONYMOUS", SASLAnonymous.class);
+
+        supportSASLMechanism("GSSAPI",0);
+        supportSASLMechanism("DIGEST-MD5",1);
+        supportSASLMechanism("CRAM-MD5",2);
+        supportSASLMechanism("PLAIN",3);
+        supportSASLMechanism("ANONYMOUS",4);
+
+    }
+
+    /**
+     * Registers a new SASL mechanism
+     *
+     * @param name   common name of the SASL mechanism. E.g.: PLAIN, DIGEST-MD5 or KERBEROS_V4.
+     * @param mClass a SASLMechanism subclass.
+     */
+    public static void registerSASLMechanism(String name, Class<? extends SASLMechanism> mClass) {
+        implementedMechanisms.put(name, mClass);
+    }
+
+    /**
+     * Unregisters an existing SASL mechanism. Once the mechanism has been unregistered it won't
+     * be possible to authenticate users using the removed SASL mechanism. It also removes the
+     * mechanism from the supported list.
+     *
+     * @param name common name of the SASL mechanism. E.g.: PLAIN, DIGEST-MD5 or KERBEROS_V4.
+     */
+    public static void unregisterSASLMechanism(String name) {
+        implementedMechanisms.remove(name);
+        mechanismsPreferences.remove(name);
+    }
+
+
+    /**
+     * Registers a new SASL mechanism in the specified preference position. The client will try
+     * to authenticate using the most prefered SASL mechanism that is also supported by the server.
+     * The SASL mechanism must be registered via {@link #registerSASLMechanism(String, Class)}
+     *
+     * @param name common name of the SASL mechanism. E.g.: PLAIN, DIGEST-MD5 or KERBEROS_V4.
+     */
+    public static void supportSASLMechanism(String name) {
+        mechanismsPreferences.add(0, name);
+    }
+
+    /**
+     * Registers a new SASL mechanism in the specified preference position. The client will try
+     * to authenticate using the most prefered SASL mechanism that is also supported by the server.
+     * Use the <tt>index</tt> parameter to set the level of preference of the new SASL mechanism.
+     * A value of 0 means that the mechanism is the most prefered one. The SASL mechanism must be
+     * registered via {@link #registerSASLMechanism(String, Class)}
+     *
+     * @param name common name of the SASL mechanism. E.g.: PLAIN, DIGEST-MD5 or KERBEROS_V4.
+     * @param index preference position amongst all the implemented SASL mechanism. Starts with 0.
+     */
+    public static void supportSASLMechanism(String name, int index) {
+        mechanismsPreferences.add(index, name);
+    }
+
+    /**
+     * Un-supports an existing SASL mechanism. Once the mechanism has been unregistered it won't
+     * be possible to authenticate users using the removed SASL mechanism. Note that the mechanism
+     * is still registered, but will just not be used.
+     *
+     * @param name common name of the SASL mechanism. E.g.: PLAIN, DIGEST-MD5 or KERBEROS_V4.
+     */
+    public static void unsupportSASLMechanism(String name) {
+        mechanismsPreferences.remove(name);
+    }
+
+    /**
+     * Returns the registerd SASLMechanism classes sorted by the level of preference.
+     *
+     * @return the registerd SASLMechanism classes sorted by the level of preference.
+     */
+    public static List<Class<? extends SASLMechanism>> getRegisterSASLMechanisms() {
+        List<Class<? extends SASLMechanism>> answer = new ArrayList<Class<? extends SASLMechanism>>();
+        for (String mechanismsPreference : mechanismsPreferences) {
+            answer.add(implementedMechanisms.get(mechanismsPreference));
+        }
+        return answer;
+    }
+
+    SASLAuthentication(Connection connection) {
+        super();
+        this.connection = connection;
+        this.init();
+    }
+
+    /**
+     * Returns true if the server offered ANONYMOUS SASL as a way to authenticate users.
+     *
+     * @return true if the server offered ANONYMOUS SASL as a way to authenticate users.
+     */
+    public boolean hasAnonymousAuthentication() {
+        return serverMechanisms.contains("ANONYMOUS");
+    }
+
+    /**
+     * Returns true if the server offered SASL authentication besides ANONYMOUS SASL.
+     *
+     * @return true if the server offered SASL authentication besides ANONYMOUS SASL.
+     */
+    public boolean hasNonAnonymousAuthentication() {
+        return !serverMechanisms.isEmpty() && (serverMechanisms.size() != 1 || !hasAnonymousAuthentication());
+    }
+
+    /**
+     * Performs SASL authentication of the specified user. If SASL authentication was successful
+     * then resource binding and session establishment will be performed. This method will return
+     * the full JID provided by the server while binding a resource to the connection.<p>
+     *
+     * The server may assign a full JID with a username or resource different than the requested
+     * by this method.
+     *
+     * @param username the username that is authenticating with the server.
+     * @param resource the desired resource.
+     * @param cbh the CallbackHandler used to get information from the user
+     * @return the full JID provided by the server while binding a resource to the connection.
+     * @throws XMPPException if an error occures while authenticating.
+     */
+    public String authenticate(String username, String resource, CallbackHandler cbh) 
+            throws XMPPException {
+        // Locate the SASLMechanism to use
+        String selectedMechanism = null;
+        for (String mechanism : mechanismsPreferences) {
+            if (implementedMechanisms.containsKey(mechanism) &&
+                    serverMechanisms.contains(mechanism)) {
+                selectedMechanism = mechanism;
+                break;
+            }
+        }
+        if (selectedMechanism != null) {
+            // A SASL mechanism was found. Authenticate using the selected mechanism and then
+            // proceed to bind a resource
+            try {
+                Class<? extends SASLMechanism> mechanismClass = implementedMechanisms.get(selectedMechanism);
+                Constructor<? extends SASLMechanism> constructor = mechanismClass.getConstructor(SASLAuthentication.class);
+                currentMechanism = constructor.newInstance(this);
+                // Trigger SASL authentication with the selected mechanism. We use
+                // connection.getHost() since GSAPI requires the FQDN of the server, which
+                // may not match the XMPP domain.
+                currentMechanism.authenticate(username, connection.getHost(), cbh);
+
+                // Wait until SASL negotiation finishes
+                synchronized (this) {
+                    if (!saslNegotiated && !saslFailed) {
+                        try {
+                            wait(30000);
+                        }
+                        catch (InterruptedException e) {
+                            // Ignore
+                        }
+                    }
+                }
+
+                if (saslFailed) {
+                    // SASL authentication failed and the server may have closed the connection
+                    // so throw an exception
+                    if (errorCondition != null) {
+                        throw new XMPPException("SASL authentication " +
+                                selectedMechanism + " failed: " + errorCondition);
+                    }
+                    else {
+                        throw new XMPPException("SASL authentication failed using mechanism " +
+                                selectedMechanism);
+                    }
+                }
+
+                if (saslNegotiated) {
+                    // Bind a resource for this connection and
+                    return bindResourceAndEstablishSession(resource);
+                } else {
+                    // SASL authentication failed
+                }
+            }
+            catch (XMPPException e) {
+                throw e;
+            }
+            catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        else {
+            throw new XMPPException("SASL Authentication failed. No known authentication mechanisims.");
+        }
+        throw new XMPPException("SASL authentication failed");
+    }
+
+    /**
+     * Performs SASL authentication of the specified user. If SASL authentication was successful
+     * then resource binding and session establishment will be performed. This method will return
+     * the full JID provided by the server while binding a resource to the connection.<p>
+     *
+     * The server may assign a full JID with a username or resource different than the requested
+     * by this method.
+     *
+     * @param username the username that is authenticating with the server.
+     * @param password the password to send to the server.
+     * @param resource the desired resource.
+     * @return the full JID provided by the server while binding a resource to the connection.
+     * @throws XMPPException if an error occures while authenticating.
+     */
+    public String authenticate(String username, String password, String resource)
+            throws XMPPException {
+        // Locate the SASLMechanism to use
+        String selectedMechanism = null;
+        for (String mechanism : mechanismsPreferences) {
+            if (implementedMechanisms.containsKey(mechanism) &&
+                    serverMechanisms.contains(mechanism)) {
+                selectedMechanism = mechanism;
+                break;
+            }
+        }
+        if (selectedMechanism != null) {
+            // A SASL mechanism was found. Authenticate using the selected mechanism and then
+            // proceed to bind a resource
+            try {
+                Class<? extends SASLMechanism> mechanismClass = implementedMechanisms.get(selectedMechanism);
+                Constructor<? extends SASLMechanism> constructor = mechanismClass.getConstructor(SASLAuthentication.class);
+                currentMechanism = constructor.newInstance(this);
+                // Trigger SASL authentication with the selected mechanism. We use
+                // connection.getHost() since GSAPI requires the FQDN of the server, which
+                // may not match the XMPP domain.    
+                
+                //The serviceName is basically the value that XMPP server sends to the client as being the location
+                //of the XMPP service we are trying to connect to. This should have the format: host [ "/" serv-name ]
+                //as per RFC-2831 guidelines
+                String serviceName = connection.getServiceName();               
+                currentMechanism.authenticate(username, connection.getHost(), serviceName, password);
+
+                // Wait until SASL negotiation finishes
+                synchronized (this) {
+                    if (!saslNegotiated && !saslFailed) {
+                        try {
+                            wait(30000);
+                        }
+                        catch (InterruptedException e) {
+                            // Ignore
+                        }
+                    }
+                }
+
+                if (saslFailed) {
+                    // SASL authentication failed and the server may have closed the connection
+                    // so throw an exception
+                    if (errorCondition != null) {
+                        throw new XMPPException("SASL authentication " +
+                                selectedMechanism + " failed: " + errorCondition);
+                    }
+                    else {
+                        throw new XMPPException("SASL authentication failed using mechanism " +
+                                selectedMechanism);
+                    }
+                }
+
+                if (saslNegotiated) {
+                    // Bind a resource for this connection and
+                    return bindResourceAndEstablishSession(resource);
+                }
+                else {
+                    // SASL authentication failed so try a Non-SASL authentication
+                    return new NonSASLAuthentication(connection)
+                            .authenticate(username, password, resource);
+                }
+            }
+            catch (XMPPException e) {
+                throw e;
+            }
+            catch (Exception e) {
+                e.printStackTrace();
+                // SASL authentication failed so try a Non-SASL authentication
+                return new NonSASLAuthentication(connection)
+                        .authenticate(username, password, resource);
+            }
+        }
+        else {
+            // No SASL method was found so try a Non-SASL authentication
+            return new NonSASLAuthentication(connection).authenticate(username, password, resource);
+        }
+    }
+
+    /**
+     * Performs ANONYMOUS SASL authentication. If SASL authentication was successful
+     * then resource binding and session establishment will be performed. This method will return
+     * the full JID provided by the server while binding a resource to the connection.<p>
+     *
+     * The server will assign a full JID with a randomly generated resource and possibly with
+     * no username.
+     *
+     * @return the full JID provided by the server while binding a resource to the connection.
+     * @throws XMPPException if an error occures while authenticating.
+     */
+    public String authenticateAnonymously() throws XMPPException {
+        try {
+            currentMechanism = new SASLAnonymous(this);
+            currentMechanism.authenticate(null,null,null,"");
+
+            // Wait until SASL negotiation finishes
+            synchronized (this) {
+                if (!saslNegotiated && !saslFailed) {
+                    try {
+                        wait(5000);
+                    }
+                    catch (InterruptedException e) {
+                        // Ignore
+                    }
+                }
+            }
+
+            if (saslFailed) {
+                // SASL authentication failed and the server may have closed the connection
+                // so throw an exception
+                if (errorCondition != null) {
+                    throw new XMPPException("SASL authentication failed: " + errorCondition);
+                }
+                else {
+                    throw new XMPPException("SASL authentication failed");
+                }
+            }
+
+            if (saslNegotiated) {
+                // Bind a resource for this connection and
+                return bindResourceAndEstablishSession(null);
+            }
+            else {
+                return new NonSASLAuthentication(connection).authenticateAnonymously();
+            }
+        } catch (IOException e) {
+            return new NonSASLAuthentication(connection).authenticateAnonymously();
+        }
+    }
+
+    private String bindResourceAndEstablishSession(String resource) throws XMPPException {
+        // Wait until server sends response containing the <bind> element
+        synchronized (this) {
+            if (!resourceBinded) {
+                try {
+                    wait(30000);
+                }
+                catch (InterruptedException e) {
+                    // Ignore
+                }
+            }
+        }
+
+        if (!resourceBinded) {
+            // Server never offered resource binding
+            throw new XMPPException("Resource binding not offered by server");
+        }
+
+        Bind bindResource = new Bind();
+        bindResource.setResource(resource);
+
+        PacketCollector collector = connection
+                .createPacketCollector(new PacketIDFilter(bindResource.getPacketID()));
+        // Send the packet
+        connection.sendPacket(bindResource);
+        // Wait up to a certain number of seconds for a response from the server.
+        Bind response = (Bind) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from the server.");
+        }
+        // If the server replied with an error, throw an exception.
+        else if (response.getType() == IQ.Type.ERROR) {
+            throw new XMPPException(response.getError());
+        }
+        String userJID = response.getJid();
+
+        if (sessionSupported) {
+            Session session = new Session();
+            collector = connection.createPacketCollector(new PacketIDFilter(session.getPacketID()));
+            // Send the packet
+            connection.sendPacket(session);
+            // Wait up to a certain number of seconds for a response from the server.
+            IQ ack = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+            collector.cancel();
+            if (ack == null) {
+                throw new XMPPException("No response from the server.");
+            }
+            // If the server replied with an error, throw an exception.
+            else if (ack.getType() == IQ.Type.ERROR) {
+                throw new XMPPException(ack.getError());
+            }
+        }
+        return userJID;
+    }
+
+    /**
+     * Sets the available SASL mechanism reported by the server. The server will report the
+     * available SASL mechanism once the TLS negotiation was successful. This information is
+     * stored and will be used when doing the authentication for logging in the user.
+     *
+     * @param mechanisms collection of strings with the available SASL mechanism reported
+     *                   by the server.
+     */
+    void setAvailableSASLMethods(Collection<String> mechanisms) {
+        this.serverMechanisms = mechanisms;
+    }
+
+    /**
+     * Returns true if the user was able to authenticate with the server usins SASL.
+     *
+     * @return true if the user was able to authenticate with the server usins SASL.
+     */
+    public boolean isAuthenticated() {
+        return saslNegotiated;
+    }
+
+    /**
+     * The server is challenging the SASL authentication we just sent. Forward the challenge
+     * to the current SASLMechanism we are using. The SASLMechanism will send a response to
+     * the server. The length of the challenge-response sequence varies according to the
+     * SASLMechanism in use.
+     *
+     * @param challenge a base64 encoded string representing the challenge.
+     * @throws IOException If a network error occures while authenticating.
+     */
+    void challengeReceived(String challenge) throws IOException {
+        currentMechanism.challengeReceived(challenge);
+    }
+
+    /**
+     * Notification message saying that SASL authentication was successful. The next step
+     * would be to bind the resource.
+     */
+    void authenticated() {
+        synchronized (this) {
+            saslNegotiated = true;
+            // Wake up the thread that is waiting in the #authenticate method
+            notify();
+        }
+    }
+
+    /**
+     * Notification message saying that SASL authentication has failed. The server may have
+     * closed the connection depending on the number of possible retries.
+     * 
+     * @deprecated replaced by {@see #authenticationFailed(String)}.
+     */
+    void authenticationFailed() {
+        authenticationFailed(null);
+    }
+
+    /**
+     * Notification message saying that SASL authentication has failed. The server may have
+     * closed the connection depending on the number of possible retries.
+     * 
+     * @param condition the error condition provided by the server.
+     */
+    void authenticationFailed(String condition) {
+        synchronized (this) {
+            saslFailed = true;
+            errorCondition = condition;
+            // Wake up the thread that is waiting in the #authenticate method
+            notify();
+        }
+    }
+
+    /**
+     * Notification message saying that the server requires the client to bind a
+     * resource to the stream.
+     */
+    void bindingRequired() {
+        synchronized (this) {
+            resourceBinded = true;
+            // Wake up the thread that is waiting in the #authenticate method
+            notify();
+        }
+    }
+
+    public void send(Packet stanza) {
+        connection.sendPacket(stanza);
+    }
+
+    /**
+     * Notification message saying that the server supports sessions. When a server supports
+     * sessions the client needs to send a Session packet after successfully binding a resource
+     * for the session.
+     */
+    void sessionsSupported() {
+        sessionSupported = true;
+    }
+    
+    /**
+     * Initializes the internal state in order to be able to be reused. The authentication
+     * is used by the connection at the first login and then reused after the connection
+     * is disconnected and then reconnected.
+     */
+    protected void init() {
+        saslNegotiated = false;
+        saslFailed = false;
+        resourceBinded = false;
+        sessionSupported = false;
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/SmackError.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/SmackError.java
index af22e7c..8527876 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/SmackError.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/SmackError.java
@@ -1,24 +1,24 @@
-package org.jivesoftware.smack;
-
-public enum SmackError {
-    NO_RESPONSE_FROM_SERVER("No response from server.");
-    
-    private String message;
-    
-    private SmackError(String errMessage) {
-        message = errMessage;
-    }
-    
-    public String getErrorMessage() {
-        return message;
-    }
-    
-    public static SmackError getErrorCode(String message) {
-        for (SmackError code : values()) {
-            if (code.message.equals(message)) {
-                return code;
-            }
-        }
-        return null;
-    }
-}
+package org.jivesoftware.smack;
+
+public enum SmackError {
+    NO_RESPONSE_FROM_SERVER("No response from server.");
+    
+    private String message;
+    
+    private SmackError(String errMessage) {
+        message = errMessage;
+    }
+    
+    public String getErrorMessage() {
+        return message;
+    }
+    
+    public static SmackError getErrorCode(String message) {
+        for (SmackError code : values()) {
+            if (code.message.equals(message)) {
+                return code;
+            }
+        }
+        return null;
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/UserAuthentication.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/UserAuthentication.java
index 8f0dd50..728428b 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/UserAuthentication.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/UserAuthentication.java
@@ -1,79 +1,79 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack;
-
-import javax.security.auth.callback.CallbackHandler;
-
-/**
- * There are two ways to authenticate a user with a server. Using SASL or Non-SASL
- * authentication. This interface makes {@link SASLAuthentication} and
- * {@link NonSASLAuthentication} polyphormic.
- *
- * @author Gaston Dombiak
- * @author Jay Kline
- */
-interface UserAuthentication {
-
-    /**
-     * Authenticates the user with the server.  This method will return the full JID provided by
-     * the server.  The server may assign a full JID with a username and resource different than
-     * requested by this method.
-     *
-     * Note that using callbacks is the prefered method of authenticating users since it allows
-     * more flexability in the mechanisms used.
-     *
-     * @param username the requested username (authorization ID) for authenticating to the server
-     * @param resource the requested resource.
-     * @param cbh the CallbackHandler used to obtain authentication ID, password, or other
-     * information
-     * @return the full JID provided by the server while binding a resource for the connection.
-     * @throws XMPPException if an error occurs while authenticating.
-     */
-    String authenticate(String username, String resource, CallbackHandler cbh) throws
-            XMPPException;
-
-    /**
-     * Authenticates the user with the server. This method will return the full JID provided by
-     * the server. The server may assign a full JID with a username and resource different than
-     * the requested by this method.
-     *
-     * It is recommended that @{link #authenticate(String, String, CallbackHandler)} be used instead
-     * since it provides greater flexability in authenticaiton and authorization.
-     *
-     * @param username the username that is authenticating with the server.
-     * @param password the password to send to the server.
-     * @param resource the desired resource.
-     * @return the full JID provided by the server while binding a resource for the connection.
-     * @throws XMPPException if an error occures while authenticating.
-     */
-    String authenticate(String username, String password, String resource) throws
-            XMPPException;
-
-    /**
-     * Performs an anonymous authentication with the server. The server will created a new full JID
-     * for this connection. An exception will be thrown if the server does not support anonymous
-     * authentication.
-     *
-     * @return the full JID provided by the server while binding a resource for the connection.
-     * @throws XMPPException if an error occures while authenticating.
-     */
-    String authenticateAnonymously() throws XMPPException;
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack;
+
+import javax.security.auth.callback.CallbackHandler;
+
+/**
+ * There are two ways to authenticate a user with a server. Using SASL or Non-SASL
+ * authentication. This interface makes {@link SASLAuthentication} and
+ * {@link NonSASLAuthentication} polyphormic.
+ *
+ * @author Gaston Dombiak
+ * @author Jay Kline
+ */
+interface UserAuthentication {
+
+    /**
+     * Authenticates the user with the server.  This method will return the full JID provided by
+     * the server.  The server may assign a full JID with a username and resource different than
+     * requested by this method.
+     *
+     * Note that using callbacks is the prefered method of authenticating users since it allows
+     * more flexability in the mechanisms used.
+     *
+     * @param username the requested username (authorization ID) for authenticating to the server
+     * @param resource the requested resource.
+     * @param cbh the CallbackHandler used to obtain authentication ID, password, or other
+     * information
+     * @return the full JID provided by the server while binding a resource for the connection.
+     * @throws XMPPException if an error occurs while authenticating.
+     */
+    String authenticate(String username, String resource, CallbackHandler cbh) throws
+            XMPPException;
+
+    /**
+     * Authenticates the user with the server. This method will return the full JID provided by
+     * the server. The server may assign a full JID with a username and resource different than
+     * the requested by this method.
+     *
+     * It is recommended that @{link #authenticate(String, String, CallbackHandler)} be used instead
+     * since it provides greater flexability in authenticaiton and authorization.
+     *
+     * @param username the username that is authenticating with the server.
+     * @param password the password to send to the server.
+     * @param resource the desired resource.
+     * @return the full JID provided by the server while binding a resource for the connection.
+     * @throws XMPPException if an error occures while authenticating.
+     */
+    String authenticate(String username, String password, String resource) throws
+            XMPPException;
+
+    /**
+     * Performs an anonymous authentication with the server. The server will created a new full JID
+     * for this connection. An exception will be thrown if the server does not support anonymous
+     * authentication.
+     *
+     * @return the full JID provided by the server while binding a resource for the connection.
+     * @throws XMPPException if an error occures while authenticating.
+     */
+    String authenticateAnonymously() throws XMPPException;
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/filter/IQTypeFilter.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/filter/IQTypeFilter.java
index dbab1c3..efe6003 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/filter/IQTypeFilter.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/filter/IQTypeFilter.java
@@ -1,48 +1,48 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2006 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smack.filter;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Packet;
-
-/**
- * A filter for IQ packet types. Returns true only if the packet is an IQ packet
- * and it matches the type provided in the constructor.
- * 
- * @author Alexander Wenckus
- * 
- */
-public class IQTypeFilter implements PacketFilter {
-
-	private IQ.Type type;
-
-	public IQTypeFilter(IQ.Type type) {
-		this.type = type;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.jivesoftware.smack.filter.PacketFilter#accept(org.jivesoftware.smack.packet.Packet)
-	 */
-	public boolean accept(Packet packet) {
-		return (packet instanceof IQ && ((IQ) packet).getType().equals(type));
-	}
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2006 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smack.filter;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Packet;
+
+/**
+ * A filter for IQ packet types. Returns true only if the packet is an IQ packet
+ * and it matches the type provided in the constructor.
+ * 
+ * @author Alexander Wenckus
+ * 
+ */
+public class IQTypeFilter implements PacketFilter {
+
+	private IQ.Type type;
+
+	public IQTypeFilter(IQ.Type type) {
+		this.type = type;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jivesoftware.smack.filter.PacketFilter#accept(org.jivesoftware.smack.packet.Packet)
+	 */
+	public boolean accept(Packet packet) {
+		return (packet instanceof IQ && ((IQ) packet).getType().equals(type));
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/Bind.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/Bind.java
index 07cd193..fa15014 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/Bind.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/Bind.java
@@ -1,71 +1,71 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack.packet;
-
-/**
- * IQ packet used by Smack to bind a resource and to obtain the jid assigned by the server.
- * There are two ways to bind a resource. One is simply sending an empty Bind packet where the
- * server will assign a new resource for this connection. The other option is to set a desired
- * resource but the server may return a modified version of the sent resource.<p>
- *
- * For more information refer to the following
- * <a href=http://www.xmpp.org/specs/rfc3920.html#bind>link</a>. 
- *
- * @author Gaston Dombiak
- */
-public class Bind extends IQ {
-
-    private String resource = null;
-    private String jid = null;
-
-    public Bind() {
-        setType(IQ.Type.SET);
-    }
-
-    public String getResource() {
-        return resource;
-    }
-
-    public void setResource(String resource) {
-        this.resource = resource;
-    }
-
-    public String getJid() {
-        return jid;
-    }
-
-    public void setJid(String jid) {
-        this.jid = jid;
-    }
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\">");
-        if (resource != null) {
-            buf.append("<resource>").append(resource).append("</resource>");
-        }
-        if (jid != null) {
-            buf.append("<jid>").append(jid).append("</jid>");
-        }
-        buf.append("</bind>");
-        return buf.toString();
-    }
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack.packet;
+
+/**
+ * IQ packet used by Smack to bind a resource and to obtain the jid assigned by the server.
+ * There are two ways to bind a resource. One is simply sending an empty Bind packet where the
+ * server will assign a new resource for this connection. The other option is to set a desired
+ * resource but the server may return a modified version of the sent resource.<p>
+ *
+ * For more information refer to the following
+ * <a href=http://www.xmpp.org/specs/rfc3920.html#bind>link</a>. 
+ *
+ * @author Gaston Dombiak
+ */
+public class Bind extends IQ {
+
+    private String resource = null;
+    private String jid = null;
+
+    public Bind() {
+        setType(IQ.Type.SET);
+    }
+
+    public String getResource() {
+        return resource;
+    }
+
+    public void setResource(String resource) {
+        this.resource = resource;
+    }
+
+    public String getJid() {
+        return jid;
+    }
+
+    public void setJid(String jid) {
+        this.jid = jid;
+    }
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\">");
+        if (resource != null) {
+            buf.append("<resource>").append(resource).append("</resource>");
+        }
+        if (jid != null) {
+            buf.append("<jid>").append(jid).append("</jid>");
+        }
+        buf.append("</bind>");
+        return buf.toString();
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/Privacy.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/Privacy.java
index a62d578..3af6c4b 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/Privacy.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/Privacy.java
@@ -1,323 +1,323 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2006-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack.packet;
-
-import java.util.*;
-
-/**
- * A Privacy IQ Packet, is used by the {@link org.jivesoftware.smack.PrivacyListManager}
- * and {@link org.jivesoftware.smack.provider.PrivacyProvider} to allow and block
- * communications from other users. It contains the appropriate structure to suit
- * user-defined privacy lists. Different configured Privacy packages are used in the
- * server & manager communication in order to:
- * <ul>
- * <li>Retrieving one's privacy lists. 
- * <li>Adding, removing, and editing one's privacy lists. 
- * <li>Setting, changing, or declining active lists. 
- * <li>Setting, changing, or declining the default list (i.e., the list that is active by default). 
- * </ul>
- * Privacy Items can handle different kind of blocking communications based on JID, group, 
- * subscription type or globally {@link PrivacyItem}
- * 
- * @author Francisco Vives
- */
-public class Privacy extends IQ {
-	/** declineActiveList is true when the user declines the use of the active list **/
-	private boolean declineActiveList=false;
-	/** activeName is the name associated with the active list set for the session **/
-	private String activeName;
-	/** declineDefaultList is true when the user declines the use of the default list **/
-	private boolean declineDefaultList=false;
-	/** defaultName is the name of the default list that applies to the user as a whole **/
-	private String defaultName;
-	/** itemLists holds the set of privacy items classified in lists. It is a map where the 
-	 * key is the name of the list and the value a collection with privacy items. **/
-	private Map<String, List<PrivacyItem>> itemLists = new HashMap<String, List<PrivacyItem>>();
-
-    /**
-     * Set or update a privacy list with privacy items.
-     *
-     * @param listName the name of the new privacy list.
-     * @param listItem the {@link PrivacyItem} that rules the list.
-     * @return the privacy List.
-     */
-    public List<PrivacyItem> setPrivacyList(String listName, List<PrivacyItem> listItem) {
-        // Add new list to the itemLists
-        this.getItemLists().put(listName, listItem);
-        return listItem;
-    }
-
-    /**
-     * Set the active list based on the default list.
-     *
-     * @return the active List.
-     */
-    public List<PrivacyItem> setActivePrivacyList() {
-        this.setActiveName(this.getDefaultName());
-        return this.getItemLists().get(this.getActiveName());
-    }
-
-    /**
-     * Deletes an existing privacy list. If the privacy list being deleted was the default list 
-     * then the user will end up with no default list. Therefore, the user will have to set a new 
-     * default list.
-     *
-     * @param listName the name of the list being deleted.
-     */
-    public void deletePrivacyList(String listName) {
-        // Remove the list from the cache
-    	this.getItemLists().remove(listName);
-
-        // Check if deleted list was the default list
-        if (this.getDefaultName() != null && listName.equals(this.getDefaultName())) {
-        	this.setDefaultName(null);
-        }
-    }
-
-    /**
-     * Returns the active privacy list or <tt>null</tt> if none was found.
-     *
-     * @return list with {@link PrivacyItem} or <tt>null</tt> if none was found.
-     */
-    public List<PrivacyItem> getActivePrivacyList() {
-        // Check if we have the default list
-        if (this.getActiveName() == null) {
-        	return null;
-        } else {
-        	return this.getItemLists().get(this.getActiveName());
-        }
-    }
-
-    /**
-     * Returns the default privacy list or <tt>null</tt> if none was found.
-     *
-     * @return list with {@link PrivacyItem} or <tt>null</tt> if none was found.
-     */
-    public List<PrivacyItem> getDefaultPrivacyList() {
-        // Check if we have the default list
-        if (this.getDefaultName() == null) {
-        	return null;
-        } else {
-        	return this.getItemLists().get(this.getDefaultName());
-        }
-    }
-
-    /**
-     * Returns a specific privacy list.
-     *
-     * @param listName the name of the list to get.
-     * @return a List with {@link PrivacyItem}
-     */
-    public List<PrivacyItem> getPrivacyList(String listName) {
-        return this.getItemLists().get(listName);
-    }
-
-    /**
-     * Returns the privacy item in the specified order.
-     *
-     * @param listName the name of the privacy list.
-     * @param order the order of the element.
-     * @return a List with {@link PrivacyItem}
-     */
-    public PrivacyItem getItem(String listName, int order) {
-    	Iterator<PrivacyItem> values = getPrivacyList(listName).iterator();
-    	PrivacyItem itemFound = null;
-    	while (itemFound == null && values.hasNext()) {
-    		PrivacyItem element = values.next();
-			if (element.getOrder() == order) {
-				itemFound = element;
-			}
-		}
-    	return itemFound;
-    }
-
-    /**
-     * Sets a given privacy list as the new user default list.
-     *
-     * @param newDefault the new default privacy list.
-     * @return if the default list was changed.
-     */
-    public boolean changeDefaultList(String newDefault) {
-        if (this.getItemLists().containsKey(newDefault)) {
-           this.setDefaultName(newDefault);
-           return true;
-        } else {
-        	return false; 
-        }
-    }
-
-    /**
-     * Remove the list.
-     *
-     * @param listName name of the list to remove.
-     */
-     public void deleteList(String listName) {
-    	 this.getItemLists().remove(listName);
-     }
-
-    /**
-     * Returns the name associated with the active list set for the session. Communications
-     * will be verified against the active list.
-     *
-     * @return the name of the active list.
-     */
-	public String getActiveName() {
-		return activeName;
-	}
-
-    /**
-     * Sets the name associated with the active list set for the session. Communications
-     * will be verified against the active list.
-     * 
-     * @param activeName is the name of the active list.
-     */
-	public void setActiveName(String activeName) {
-		this.activeName = activeName;
-	}
-
-    /**
-     * Returns the name of the default list that applies to the user as a whole. Default list is 
-     * processed if there is no active list set for the target session/resource to which a stanza 
-     * is addressed, or if there are no current sessions for the user.
-     * 
-     * @return the name of the default list.
-     */
-	public String getDefaultName() {
-		return defaultName;
-	}
-
-    /**
-     * Sets the name of the default list that applies to the user as a whole. Default list is 
-     * processed if there is no active list set for the target session/resource to which a stanza 
-     * is addressed, or if there are no current sessions for the user.
-     * 
-     * If there is no default list set, then all Privacy Items are processed.
-     * 
-     * @param defaultName is the name of the default list.
-     */
-	public void setDefaultName(String defaultName) {
-		this.defaultName = defaultName;
-	}
-
-    /**
-     * Returns the collection of privacy list that the user holds. A Privacy List contains a set of 
-     * rules that define if communication with the list owner is allowed or denied. 
-     * Users may have zero, one or more privacy items.
-     * 
-     * @return a map where the key is the name of the list and the value the 
-     * collection of privacy items.
-     */
-	public Map<String, List<PrivacyItem>> getItemLists() {
-		return itemLists;
-	}
-
-    /** 
-     * Returns whether the receiver allows or declines the use of an active list.
-     * 
-     * @return the decline status of the list.
-     */
-	public boolean isDeclineActiveList() {
-		return declineActiveList;
-	}
-
-    /** 
-     * Sets whether the receiver allows or declines the use of an active list.
-     * 
-     * @param declineActiveList indicates if the receiver declines the use of an active list.
-     */
-	public void setDeclineActiveList(boolean declineActiveList) {
-		this.declineActiveList = declineActiveList;
-	}
-
-    /** 
-     * Returns whether the receiver allows or declines the use of a default list.
-     * 
-     * @return the decline status of the list.
-     */
-	public boolean isDeclineDefaultList() {
-		return declineDefaultList;
-	}
-
-    /** 
-     * Sets whether the receiver allows or declines the use of a default list.
-     * 
-     * @param declineDefaultList indicates if the receiver declines the use of a default list.
-     */
-	public void setDeclineDefaultList(boolean declineDefaultList) {
-		this.declineDefaultList = declineDefaultList;
-	}
-
-	/** 
-     * Returns all the list names the user has defined to group restrictions.
-     * 
-     * @return a Set with Strings containing every list names.
-     */
-	public Set<String> getPrivacyListNames() {
-		return this.itemLists.keySet();
-	}
-	
-	public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<query xmlns=\"jabber:iq:privacy\">");
-        
-        // Add the active tag
-        if (this.isDeclineActiveList()) {
-        	buf.append("<active/>");
-        } else {
-        	if (this.getActiveName() != null) {
-            	buf.append("<active name=\"").append(this.getActiveName()).append("\"/>");
-            }
-        }
-        // Add the default tag
-        if (this.isDeclineDefaultList()) {
-        	buf.append("<default/>");
-        } else {
-	        if (this.getDefaultName() != null) {
-	        	buf.append("<default name=\"").append(this.getDefaultName()).append("\"/>");
-	        }
-        }
-        
-        // Add the list with their privacy items
-        for (Map.Entry<String, List<PrivacyItem>> entry : this.getItemLists().entrySet()) {
-          String listName = entry.getKey();
-          List<PrivacyItem> items = entry.getValue();
-			// Begin the list tag
-			if (items.isEmpty()) {
-				buf.append("<list name=\"").append(listName).append("\"/>");
-			} else {
-				buf.append("<list name=\"").append(listName).append("\">");
-			}
-	        for (PrivacyItem item : items) {
-	        	// Append the item xml representation
-	        	buf.append(item.toXML());
-	        }
-	        // Close the list tag
-	        if (!items.isEmpty()) {
-				buf.append("</list>");
-			}
-		}
-
-        // Add packet extensions, if any are defined.
-        buf.append(getExtensionsXML());
-        buf.append("</query>");
-        return buf.toString();
-    }
-    
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2006-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack.packet;
+
+import java.util.*;
+
+/**
+ * A Privacy IQ Packet, is used by the {@link org.jivesoftware.smack.PrivacyListManager}
+ * and {@link org.jivesoftware.smack.provider.PrivacyProvider} to allow and block
+ * communications from other users. It contains the appropriate structure to suit
+ * user-defined privacy lists. Different configured Privacy packages are used in the
+ * server & manager communication in order to:
+ * <ul>
+ * <li>Retrieving one's privacy lists. 
+ * <li>Adding, removing, and editing one's privacy lists. 
+ * <li>Setting, changing, or declining active lists. 
+ * <li>Setting, changing, or declining the default list (i.e., the list that is active by default). 
+ * </ul>
+ * Privacy Items can handle different kind of blocking communications based on JID, group, 
+ * subscription type or globally {@link PrivacyItem}
+ * 
+ * @author Francisco Vives
+ */
+public class Privacy extends IQ {
+	/** declineActiveList is true when the user declines the use of the active list **/
+	private boolean declineActiveList=false;
+	/** activeName is the name associated with the active list set for the session **/
+	private String activeName;
+	/** declineDefaultList is true when the user declines the use of the default list **/
+	private boolean declineDefaultList=false;
+	/** defaultName is the name of the default list that applies to the user as a whole **/
+	private String defaultName;
+	/** itemLists holds the set of privacy items classified in lists. It is a map where the 
+	 * key is the name of the list and the value a collection with privacy items. **/
+	private Map<String, List<PrivacyItem>> itemLists = new HashMap<String, List<PrivacyItem>>();
+
+    /**
+     * Set or update a privacy list with privacy items.
+     *
+     * @param listName the name of the new privacy list.
+     * @param listItem the {@link PrivacyItem} that rules the list.
+     * @return the privacy List.
+     */
+    public List<PrivacyItem> setPrivacyList(String listName, List<PrivacyItem> listItem) {
+        // Add new list to the itemLists
+        this.getItemLists().put(listName, listItem);
+        return listItem;
+    }
+
+    /**
+     * Set the active list based on the default list.
+     *
+     * @return the active List.
+     */
+    public List<PrivacyItem> setActivePrivacyList() {
+        this.setActiveName(this.getDefaultName());
+        return this.getItemLists().get(this.getActiveName());
+    }
+
+    /**
+     * Deletes an existing privacy list. If the privacy list being deleted was the default list 
+     * then the user will end up with no default list. Therefore, the user will have to set a new 
+     * default list.
+     *
+     * @param listName the name of the list being deleted.
+     */
+    public void deletePrivacyList(String listName) {
+        // Remove the list from the cache
+    	this.getItemLists().remove(listName);
+
+        // Check if deleted list was the default list
+        if (this.getDefaultName() != null && listName.equals(this.getDefaultName())) {
+        	this.setDefaultName(null);
+        }
+    }
+
+    /**
+     * Returns the active privacy list or <tt>null</tt> if none was found.
+     *
+     * @return list with {@link PrivacyItem} or <tt>null</tt> if none was found.
+     */
+    public List<PrivacyItem> getActivePrivacyList() {
+        // Check if we have the default list
+        if (this.getActiveName() == null) {
+        	return null;
+        } else {
+        	return this.getItemLists().get(this.getActiveName());
+        }
+    }
+
+    /**
+     * Returns the default privacy list or <tt>null</tt> if none was found.
+     *
+     * @return list with {@link PrivacyItem} or <tt>null</tt> if none was found.
+     */
+    public List<PrivacyItem> getDefaultPrivacyList() {
+        // Check if we have the default list
+        if (this.getDefaultName() == null) {
+        	return null;
+        } else {
+        	return this.getItemLists().get(this.getDefaultName());
+        }
+    }
+
+    /**
+     * Returns a specific privacy list.
+     *
+     * @param listName the name of the list to get.
+     * @return a List with {@link PrivacyItem}
+     */
+    public List<PrivacyItem> getPrivacyList(String listName) {
+        return this.getItemLists().get(listName);
+    }
+
+    /**
+     * Returns the privacy item in the specified order.
+     *
+     * @param listName the name of the privacy list.
+     * @param order the order of the element.
+     * @return a List with {@link PrivacyItem}
+     */
+    public PrivacyItem getItem(String listName, int order) {
+    	Iterator<PrivacyItem> values = getPrivacyList(listName).iterator();
+    	PrivacyItem itemFound = null;
+    	while (itemFound == null && values.hasNext()) {
+    		PrivacyItem element = values.next();
+			if (element.getOrder() == order) {
+				itemFound = element;
+			}
+		}
+    	return itemFound;
+    }
+
+    /**
+     * Sets a given privacy list as the new user default list.
+     *
+     * @param newDefault the new default privacy list.
+     * @return if the default list was changed.
+     */
+    public boolean changeDefaultList(String newDefault) {
+        if (this.getItemLists().containsKey(newDefault)) {
+           this.setDefaultName(newDefault);
+           return true;
+        } else {
+        	return false; 
+        }
+    }
+
+    /**
+     * Remove the list.
+     *
+     * @param listName name of the list to remove.
+     */
+     public void deleteList(String listName) {
+    	 this.getItemLists().remove(listName);
+     }
+
+    /**
+     * Returns the name associated with the active list set for the session. Communications
+     * will be verified against the active list.
+     *
+     * @return the name of the active list.
+     */
+	public String getActiveName() {
+		return activeName;
+	}
+
+    /**
+     * Sets the name associated with the active list set for the session. Communications
+     * will be verified against the active list.
+     * 
+     * @param activeName is the name of the active list.
+     */
+	public void setActiveName(String activeName) {
+		this.activeName = activeName;
+	}
+
+    /**
+     * Returns the name of the default list that applies to the user as a whole. Default list is 
+     * processed if there is no active list set for the target session/resource to which a stanza 
+     * is addressed, or if there are no current sessions for the user.
+     * 
+     * @return the name of the default list.
+     */
+	public String getDefaultName() {
+		return defaultName;
+	}
+
+    /**
+     * Sets the name of the default list that applies to the user as a whole. Default list is 
+     * processed if there is no active list set for the target session/resource to which a stanza 
+     * is addressed, or if there are no current sessions for the user.
+     * 
+     * If there is no default list set, then all Privacy Items are processed.
+     * 
+     * @param defaultName is the name of the default list.
+     */
+	public void setDefaultName(String defaultName) {
+		this.defaultName = defaultName;
+	}
+
+    /**
+     * Returns the collection of privacy list that the user holds. A Privacy List contains a set of 
+     * rules that define if communication with the list owner is allowed or denied. 
+     * Users may have zero, one or more privacy items.
+     * 
+     * @return a map where the key is the name of the list and the value the 
+     * collection of privacy items.
+     */
+	public Map<String, List<PrivacyItem>> getItemLists() {
+		return itemLists;
+	}
+
+    /** 
+     * Returns whether the receiver allows or declines the use of an active list.
+     * 
+     * @return the decline status of the list.
+     */
+	public boolean isDeclineActiveList() {
+		return declineActiveList;
+	}
+
+    /** 
+     * Sets whether the receiver allows or declines the use of an active list.
+     * 
+     * @param declineActiveList indicates if the receiver declines the use of an active list.
+     */
+	public void setDeclineActiveList(boolean declineActiveList) {
+		this.declineActiveList = declineActiveList;
+	}
+
+    /** 
+     * Returns whether the receiver allows or declines the use of a default list.
+     * 
+     * @return the decline status of the list.
+     */
+	public boolean isDeclineDefaultList() {
+		return declineDefaultList;
+	}
+
+    /** 
+     * Sets whether the receiver allows or declines the use of a default list.
+     * 
+     * @param declineDefaultList indicates if the receiver declines the use of a default list.
+     */
+	public void setDeclineDefaultList(boolean declineDefaultList) {
+		this.declineDefaultList = declineDefaultList;
+	}
+
+	/** 
+     * Returns all the list names the user has defined to group restrictions.
+     * 
+     * @return a Set with Strings containing every list names.
+     */
+	public Set<String> getPrivacyListNames() {
+		return this.itemLists.keySet();
+	}
+	
+	public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("<query xmlns=\"jabber:iq:privacy\">");
+        
+        // Add the active tag
+        if (this.isDeclineActiveList()) {
+        	buf.append("<active/>");
+        } else {
+        	if (this.getActiveName() != null) {
+            	buf.append("<active name=\"").append(this.getActiveName()).append("\"/>");
+            }
+        }
+        // Add the default tag
+        if (this.isDeclineDefaultList()) {
+        	buf.append("<default/>");
+        } else {
+	        if (this.getDefaultName() != null) {
+	        	buf.append("<default name=\"").append(this.getDefaultName()).append("\"/>");
+	        }
+        }
+        
+        // Add the list with their privacy items
+        for (Map.Entry<String, List<PrivacyItem>> entry : this.getItemLists().entrySet()) {
+          String listName = entry.getKey();
+          List<PrivacyItem> items = entry.getValue();
+			// Begin the list tag
+			if (items.isEmpty()) {
+				buf.append("<list name=\"").append(listName).append("\"/>");
+			} else {
+				buf.append("<list name=\"").append(listName).append("\">");
+			}
+	        for (PrivacyItem item : items) {
+	        	// Append the item xml representation
+	        	buf.append(item.toXML());
+	        }
+	        // Close the list tag
+	        if (!items.isEmpty()) {
+				buf.append("</list>");
+			}
+		}
+
+        // Add packet extensions, if any are defined.
+        buf.append(getExtensionsXML());
+        buf.append("</query>");
+        return buf.toString();
+    }
+    
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/PrivacyItem.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/PrivacyItem.java
index 2e144ee..e108f68 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/PrivacyItem.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/PrivacyItem.java
@@ -15,448 +15,448 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jivesoftware.smack.packet;
-
-/**
- * A privacy item acts a rule that when matched defines if a packet should be blocked or not.
- *
- * Privacy Items can handle different kind of blocking communications based on JID, group,
- * subscription type or globally by:<ul>
- * <li>Allowing or blocking messages.
- * <li>Allowing or blocking inbound presence notifications.
- * <li>Allowing or blocking outbound presence notifications.
- * <li>Allowing or blocking IQ stanzas.
- * <li>Allowing or blocking all communications.
- * </ul>
- * @author Francisco Vives
- */
-public class PrivacyItem {
-	/** allow is the action associated with the item, it can allow or deny the communication. */
-	private boolean allow;
-	/** order is a non-negative integer that is unique among all items in the list. */
-    private int order;
-    /** rule hold the kind of communication ([jid|group|subscription]) it will allow or block and
-     * identifier to apply the action.
-     * If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
-     * If the type is "group", then the 'value' attribute SHOULD contain the name of a group
-     * in the user's roster.
-     * If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
-     * "from", or "none". */
-    private PrivacyRule rule;
-
-    /** blocks incoming IQ stanzas. */
-    private boolean filterIQ = false;
-    /** filterMessage blocks incoming message stanzas. */
-    private boolean filterMessage = false;
-    /** blocks incoming presence notifications. */
-    private boolean filterPresence_in = false;
-    /** blocks outgoing presence notifications. */
-    private boolean filterPresence_out = false;
-
-    /**
-     * Creates a new privacy item.
-     *
-     * @param type the type.
-     */
-    public PrivacyItem(String type, boolean allow, int order) {
-        this.setRule(PrivacyRule.fromString(type));
-        this.setAllow(allow);
-        this.setOrder(order);
-    }
-
-    /**
-     * Returns the action associated with the item, it MUST be filled and will allow or deny
-     * the communication.
-     *
-     * @return the allow communication status.
-     */
-    public boolean isAllow() {
-		return allow;
-	}
-
-    /**
-     * Sets the action associated with the item, it can allow or deny the communication.
-     *
-     * @param allow indicates if the receiver allow or deny the communication.
-     */
-    private void setAllow(boolean allow) {
-		this.allow = allow;
-	}
-
-
-    /**
-     * Returns whether the receiver allow or deny incoming IQ stanzas or not.
-     *
-     * @return the iq filtering status.
-     */
-    public boolean isFilterIQ() {
-		return filterIQ;
-	}
-
-
-    /**
-     * Sets whether the receiver allows or denies incoming IQ stanzas or not.
-     *
-     * @param filterIQ indicates if the receiver allows or denies incoming IQ stanzas.
-     */
-    public void setFilterIQ(boolean filterIQ) {
-		this.filterIQ = filterIQ;
-	}
-
-
-    /**
-     * Returns whether the receiver allows or denies incoming messages or not.
-     *
-     * @return the message filtering status.
-     */
-    public boolean isFilterMessage() {
-		return filterMessage;
-	}
-
-
-    /**
-     * Sets wheather the receiver allows or denies incoming messages or not.
-     *
-     * @param filterMessage indicates if the receiver allows or denies incoming messages or not.
-     */
-    public void setFilterMessage(boolean filterMessage) {
-		this.filterMessage = filterMessage;
-	}
-
-
-    /**
-     * Returns whether the receiver allows or denies incoming presence or not.
-     *
-     * @return the iq filtering incoming presence status.
-     */
-    public boolean isFilterPresence_in() {
-		return filterPresence_in;
-	}
-
-
-    /**
-     * Sets whether the receiver allows or denies incoming presence or not.
-     *
-     * @param filterPresence_in indicates if the receiver allows or denies filtering incoming presence.
-     */
-    public void setFilterPresence_in(boolean filterPresence_in) {
-		this.filterPresence_in = filterPresence_in;
-	}
-
-
-    /**
-     * Returns whether the receiver allows or denies incoming presence or not.
-     *
-     * @return the iq filtering incoming presence status.
-     */
-    public boolean isFilterPresence_out() {
-		return filterPresence_out;
-	}
-
-
-    /**
-     * Sets whether the receiver allows or denies outgoing presence or not.
-     *
-     * @param filterPresence_out indicates if the receiver allows or denies filtering outgoing presence
-     */
-    public void setFilterPresence_out(boolean filterPresence_out) {
-		this.filterPresence_out = filterPresence_out;
-	}
-
-
-    /**
-     * Returns the order where the receiver is processed. List items are processed in
-     * ascending order.
-     *
-     * The order MUST be filled and its value MUST be a non-negative integer
-     * that is unique among all items in the list.
-     *
-     * @return the order number.
-     */
-    public int getOrder() {
-		return order;
-	}
-
-
-    /**
-     * Sets the order where the receiver is processed.
-     *
-     * The order MUST be filled and its value MUST be a non-negative integer
-     * that is unique among all items in the list.
-     *
-     * @param order indicates the order in the list.
-     */
-    public void setOrder(int order) {
-		this.order = order;
-	}
-
-    /**
-     * Sets the element identifier to apply the action.
-     *
-     * If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
-     * If the type is "group", then the 'value' attribute SHOULD contain the name of a group
-     * in the user's roster.
-     * If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
-     * "from", or "none".
-     *
-     * @param value is the identifier to apply the action.
-     */
-    public void setValue(String value) {
-    	if (!(this.getRule() == null && value == null)) {
-    		this.getRule().setValue(value);
-    	}
-	}
-
-    /**
-     * Returns the type hold the kind of communication it will allow or block.
-     * It MUST be filled with one of these values: jid, group or subscription.
-     *
-     * @return the type of communication it represent.
-     */
-    public Type getType() {
-    	if (this.getRule() == null) {
-    		return null;
-    	} else {
-		return this.getRule().getType();
-    	}
-	}
-
-    /**
-     * Returns the element identifier to apply the action.
-     *
-     * If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
-     * If the type is "group", then the 'value' attribute SHOULD contain the name of a group
-     * in the user's roster.
-     * If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
-     * "from", or "none".
-     *
-     * @return the identifier to apply the action.
-     */
-    public String getValue() {
-    	if (this.getRule() == null) {
-    		return null;
-    	} else {
-		return this.getRule().getValue();
-    	}
-	}
-
-
-    /**
-     * Returns whether the receiver allows or denies every kind of communication.
-     *
-     * When filterIQ, filterMessage, filterPresence_in and filterPresence_out are not set
-     * the receiver will block all communications.
-     *
-     * @return the all communications status.
-     */
-    public boolean isFilterEverything() {
-		return !(this.isFilterIQ() || this.isFilterMessage() || this.isFilterPresence_in()
-				|| this.isFilterPresence_out());
-	}
-
-
-	private PrivacyRule getRule() {
-		return rule;
-	}
-
-	private void setRule(PrivacyRule rule) {
-		this.rule = rule;
-	}
-	/**
-	 * Answer an xml representation of the receiver according to the RFC 3921.
-	 *
-	 * @return the text xml representation.
-     */
-    public String toXML() {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<item");
-        if (this.isAllow()) {
-        	buf.append(" action=\"allow\"");
-        } else {
-        	buf.append(" action=\"deny\"");
-        }
-        buf.append(" order=\"").append(getOrder()).append("\"");
-        if (getType() != null) {
-            buf.append(" type=\"").append(getType()).append("\"");
-        }
-        if (getValue() != null) {
-            buf.append(" value=\"").append(getValue()).append("\"");
-        }
-        if (isFilterEverything()) {
-        	buf.append("/>");
-        } else {
-        	buf.append(">");
-        	if (this.isFilterIQ()) {
-            	buf.append("<iq/>");
-            }
-        	if (this.isFilterMessage()) {
-            	buf.append("<message/>");
-            }
-        	if (this.isFilterPresence_in()) {
-            	buf.append("<presence-in/>");
-            }
-        	if (this.isFilterPresence_out()) {
-            	buf.append("<presence-out/>");
-            }
-        	buf.append("</item>");
-        }
-        return buf.toString();
-    }
-
-
-    /**
-     * Privacy Rule represents the kind of action to apply.
-     * It holds the kind of communication ([jid|group|subscription]) it will allow or block and
-     * identifier to apply the action.
-     */
-
-	public static class PrivacyRule {
-    	 /**
-    	  * Type defines if the rule is based on JIDs, roster groups or presence subscription types.
-    	  * Available values are: [jid|group|subscription]
-    	  */
-         private Type type;
-         /**
-          * The value hold the element identifier to apply the action.
-          * If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
-          * If the type is "group", then the 'value' attribute SHOULD contain the name of a group
-          * in the user's roster.
-          * If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
-          * "from", or "none".
-          */
-         private String value;
-
-         /**
-     	 * If the type is "subscription", then the 'value' attribute MUST be one of "both",
-     	 * "to", "from", or "none"
-     	 */
-     	public static final String SUBSCRIPTION_BOTH = "both";
-     	public static final String SUBSCRIPTION_TO = "to";
-     	public static final String SUBSCRIPTION_FROM = "from";
-     	public static final String SUBSCRIPTION_NONE = "none";
-
-         /**
-          * Returns the type constant associated with the String value.
-          */
-         protected static PrivacyRule fromString(String value) {
-             if (value == null) {
-                 return null;
-             }
-             PrivacyRule rule = new PrivacyRule();
-             rule.setType(Type.valueOf(value.toLowerCase()));
-             return rule;
-         }
-
-         /**
-          * Returns the type hold the kind of communication it will allow or block.
-          * It MUST be filled with one of these values: jid, group or subscription.
-          *
-          * @return the type of communication it represent.
-          */
-         public Type getType() {
-     		return type;
-     	}
-
-         /**
-          * Sets the action associated with the item, it can allow or deny the communication.
-          *
-          * @param type indicates if the receiver allows or denies the communication.
-          */
-         private void setType(Type type) {
-     		this.type = type;
-     	}
-
-         /**
-          * Returns the element identifier to apply the action.
-          *
-          * If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
-          * If the type is "group", then the 'value' attribute SHOULD contain the name of a group
-          * in the user's roster.
-          * If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
-          * "from", or "none".
-          *
-          * @return the identifier to apply the action.
-          */
-         public String getValue() {
-     		return value;
-     	}
-
-         /**
-          * Sets the element identifier to apply the action.
-          *
-          * If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
-          * If the type is "group", then the 'value' attribute SHOULD contain the name of a group
-          * in the user's roster.
-          * If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
-          * "from", or "none".
-          *
-          * @param value is the identifier to apply the action.
-          */
-         protected void setValue(String value) {
-        	 if (this.isSuscription()) {
-        		 setSuscriptionValue(value);
-        	 } else {
-        		 this.value = value;
-        	 }
-     	}
-
-         /**
-          * Sets the element identifier to apply the action.
-          *
-          * The 'value' attribute MUST be one of "both", "to", "from", or "none".
-          *
-          * @param value is the identifier to apply the action.
-          */
-         private void setSuscriptionValue(String value) {
-        	 String setValue;
-             if (value == null) {
-            	 // Do nothing
-             }
-             if (SUBSCRIPTION_BOTH.equalsIgnoreCase(value)) {
-            	 setValue = SUBSCRIPTION_BOTH;
-             }
-             else if (SUBSCRIPTION_TO.equalsIgnoreCase(value)) {
-            	 setValue = SUBSCRIPTION_TO;
-             }
-             else if (SUBSCRIPTION_FROM.equalsIgnoreCase(value)) {
-            	 setValue = SUBSCRIPTION_FROM;
-             }
-             else if (SUBSCRIPTION_NONE.equalsIgnoreCase(value)) {
-            	 setValue = SUBSCRIPTION_NONE;
-             }
-             // Default to available.
-             else {
-            	 setValue = null;
-             }
-     		this.value = setValue;
-     	}
-
-         /**
-          * Returns if the receiver represents a subscription rule.
-          *
-          * @return if the receiver represents a subscription rule.
-          */
-         public boolean isSuscription () {
-     		return this.getType() == Type.subscription;
-     	}
-    }
-
-    /**
-     * Type defines if the rule is based on JIDs, roster groups or presence subscription types.
-     */
-    public static enum Type {
-        /**
-         * JID being analyzed should belong to a roster group of the list's owner.
-         */
-        group,
-        /**
-         * JID being analyzed should have a resource match, domain match or bare JID match.
-         */
-        jid,
-        /**
-         * JID being analyzed should belong to a contact present in the owner's roster with
-         * the specified subscription status.
-         */
-        subscription
-    }
-}
+package org.jivesoftware.smack.packet;
+
+/**
+ * A privacy item acts a rule that when matched defines if a packet should be blocked or not.
+ *
+ * Privacy Items can handle different kind of blocking communications based on JID, group,
+ * subscription type or globally by:<ul>
+ * <li>Allowing or blocking messages.
+ * <li>Allowing or blocking inbound presence notifications.
+ * <li>Allowing or blocking outbound presence notifications.
+ * <li>Allowing or blocking IQ stanzas.
+ * <li>Allowing or blocking all communications.
+ * </ul>
+ * @author Francisco Vives
+ */
+public class PrivacyItem {
+	/** allow is the action associated with the item, it can allow or deny the communication. */
+	private boolean allow;
+	/** order is a non-negative integer that is unique among all items in the list. */
+    private int order;
+    /** rule hold the kind of communication ([jid|group|subscription]) it will allow or block and
+     * identifier to apply the action.
+     * If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
+     * If the type is "group", then the 'value' attribute SHOULD contain the name of a group
+     * in the user's roster.
+     * If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
+     * "from", or "none". */
+    private PrivacyRule rule;
+
+    /** blocks incoming IQ stanzas. */
+    private boolean filterIQ = false;
+    /** filterMessage blocks incoming message stanzas. */
+    private boolean filterMessage = false;
+    /** blocks incoming presence notifications. */
+    private boolean filterPresence_in = false;
+    /** blocks outgoing presence notifications. */
+    private boolean filterPresence_out = false;
+
+    /**
+     * Creates a new privacy item.
+     *
+     * @param type the type.
+     */
+    public PrivacyItem(String type, boolean allow, int order) {
+        this.setRule(PrivacyRule.fromString(type));
+        this.setAllow(allow);
+        this.setOrder(order);
+    }
+
+    /**
+     * Returns the action associated with the item, it MUST be filled and will allow or deny
+     * the communication.
+     *
+     * @return the allow communication status.
+     */
+    public boolean isAllow() {
+		return allow;
+	}
+
+    /**
+     * Sets the action associated with the item, it can allow or deny the communication.
+     *
+     * @param allow indicates if the receiver allow or deny the communication.
+     */
+    private void setAllow(boolean allow) {
+		this.allow = allow;
+	}
+
+
+    /**
+     * Returns whether the receiver allow or deny incoming IQ stanzas or not.
+     *
+     * @return the iq filtering status.
+     */
+    public boolean isFilterIQ() {
+		return filterIQ;
+	}
+
+
+    /**
+     * Sets whether the receiver allows or denies incoming IQ stanzas or not.
+     *
+     * @param filterIQ indicates if the receiver allows or denies incoming IQ stanzas.
+     */
+    public void setFilterIQ(boolean filterIQ) {
+		this.filterIQ = filterIQ;
+	}
+
+
+    /**
+     * Returns whether the receiver allows or denies incoming messages or not.
+     *
+     * @return the message filtering status.
+     */
+    public boolean isFilterMessage() {
+		return filterMessage;
+	}
+
+
+    /**
+     * Sets wheather the receiver allows or denies incoming messages or not.
+     *
+     * @param filterMessage indicates if the receiver allows or denies incoming messages or not.
+     */
+    public void setFilterMessage(boolean filterMessage) {
+		this.filterMessage = filterMessage;
+	}
+
+
+    /**
+     * Returns whether the receiver allows or denies incoming presence or not.
+     *
+     * @return the iq filtering incoming presence status.
+     */
+    public boolean isFilterPresence_in() {
+		return filterPresence_in;
+	}
+
+
+    /**
+     * Sets whether the receiver allows or denies incoming presence or not.
+     *
+     * @param filterPresence_in indicates if the receiver allows or denies filtering incoming presence.
+     */
+    public void setFilterPresence_in(boolean filterPresence_in) {
+		this.filterPresence_in = filterPresence_in;
+	}
+
+
+    /**
+     * Returns whether the receiver allows or denies incoming presence or not.
+     *
+     * @return the iq filtering incoming presence status.
+     */
+    public boolean isFilterPresence_out() {
+		return filterPresence_out;
+	}
+
+
+    /**
+     * Sets whether the receiver allows or denies outgoing presence or not.
+     *
+     * @param filterPresence_out indicates if the receiver allows or denies filtering outgoing presence
+     */
+    public void setFilterPresence_out(boolean filterPresence_out) {
+		this.filterPresence_out = filterPresence_out;
+	}
+
+
+    /**
+     * Returns the order where the receiver is processed. List items are processed in
+     * ascending order.
+     *
+     * The order MUST be filled and its value MUST be a non-negative integer
+     * that is unique among all items in the list.
+     *
+     * @return the order number.
+     */
+    public int getOrder() {
+		return order;
+	}
+
+
+    /**
+     * Sets the order where the receiver is processed.
+     *
+     * The order MUST be filled and its value MUST be a non-negative integer
+     * that is unique among all items in the list.
+     *
+     * @param order indicates the order in the list.
+     */
+    public void setOrder(int order) {
+		this.order = order;
+	}
+
+    /**
+     * Sets the element identifier to apply the action.
+     *
+     * If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
+     * If the type is "group", then the 'value' attribute SHOULD contain the name of a group
+     * in the user's roster.
+     * If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
+     * "from", or "none".
+     *
+     * @param value is the identifier to apply the action.
+     */
+    public void setValue(String value) {
+    	if (!(this.getRule() == null && value == null)) {
+    		this.getRule().setValue(value);
+    	}
+	}
+
+    /**
+     * Returns the type hold the kind of communication it will allow or block.
+     * It MUST be filled with one of these values: jid, group or subscription.
+     *
+     * @return the type of communication it represent.
+     */
+    public Type getType() {
+    	if (this.getRule() == null) {
+    		return null;
+    	} else {
+		return this.getRule().getType();
+    	}
+	}
+
+    /**
+     * Returns the element identifier to apply the action.
+     *
+     * If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
+     * If the type is "group", then the 'value' attribute SHOULD contain the name of a group
+     * in the user's roster.
+     * If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
+     * "from", or "none".
+     *
+     * @return the identifier to apply the action.
+     */
+    public String getValue() {
+    	if (this.getRule() == null) {
+    		return null;
+    	} else {
+		return this.getRule().getValue();
+    	}
+	}
+
+
+    /**
+     * Returns whether the receiver allows or denies every kind of communication.
+     *
+     * When filterIQ, filterMessage, filterPresence_in and filterPresence_out are not set
+     * the receiver will block all communications.
+     *
+     * @return the all communications status.
+     */
+    public boolean isFilterEverything() {
+		return !(this.isFilterIQ() || this.isFilterMessage() || this.isFilterPresence_in()
+				|| this.isFilterPresence_out());
+	}
+
+
+	private PrivacyRule getRule() {
+		return rule;
+	}
+
+	private void setRule(PrivacyRule rule) {
+		this.rule = rule;
+	}
+	/**
+	 * Answer an xml representation of the receiver according to the RFC 3921.
+	 *
+	 * @return the text xml representation.
+     */
+    public String toXML() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("<item");
+        if (this.isAllow()) {
+        	buf.append(" action=\"allow\"");
+        } else {
+        	buf.append(" action=\"deny\"");
+        }
+        buf.append(" order=\"").append(getOrder()).append("\"");
+        if (getType() != null) {
+            buf.append(" type=\"").append(getType()).append("\"");
+        }
+        if (getValue() != null) {
+            buf.append(" value=\"").append(getValue()).append("\"");
+        }
+        if (isFilterEverything()) {
+        	buf.append("/>");
+        } else {
+        	buf.append(">");
+        	if (this.isFilterIQ()) {
+            	buf.append("<iq/>");
+            }
+        	if (this.isFilterMessage()) {
+            	buf.append("<message/>");
+            }
+        	if (this.isFilterPresence_in()) {
+            	buf.append("<presence-in/>");
+            }
+        	if (this.isFilterPresence_out()) {
+            	buf.append("<presence-out/>");
+            }
+        	buf.append("</item>");
+        }
+        return buf.toString();
+    }
+
+
+    /**
+     * Privacy Rule represents the kind of action to apply.
+     * It holds the kind of communication ([jid|group|subscription]) it will allow or block and
+     * identifier to apply the action.
+     */
+
+	public static class PrivacyRule {
+    	 /**
+    	  * Type defines if the rule is based on JIDs, roster groups or presence subscription types.
+    	  * Available values are: [jid|group|subscription]
+    	  */
+         private Type type;
+         /**
+          * The value hold the element identifier to apply the action.
+          * If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
+          * If the type is "group", then the 'value' attribute SHOULD contain the name of a group
+          * in the user's roster.
+          * If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
+          * "from", or "none".
+          */
+         private String value;
+
+         /**
+     	 * If the type is "subscription", then the 'value' attribute MUST be one of "both",
+     	 * "to", "from", or "none"
+     	 */
+     	public static final String SUBSCRIPTION_BOTH = "both";
+     	public static final String SUBSCRIPTION_TO = "to";
+     	public static final String SUBSCRIPTION_FROM = "from";
+     	public static final String SUBSCRIPTION_NONE = "none";
+
+         /**
+          * Returns the type constant associated with the String value.
+          */
+         protected static PrivacyRule fromString(String value) {
+             if (value == null) {
+                 return null;
+             }
+             PrivacyRule rule = new PrivacyRule();
+             rule.setType(Type.valueOf(value.toLowerCase()));
+             return rule;
+         }
+
+         /**
+          * Returns the type hold the kind of communication it will allow or block.
+          * It MUST be filled with one of these values: jid, group or subscription.
+          *
+          * @return the type of communication it represent.
+          */
+         public Type getType() {
+     		return type;
+     	}
+
+         /**
+          * Sets the action associated with the item, it can allow or deny the communication.
+          *
+          * @param type indicates if the receiver allows or denies the communication.
+          */
+         private void setType(Type type) {
+     		this.type = type;
+     	}
+
+         /**
+          * Returns the element identifier to apply the action.
+          *
+          * If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
+          * If the type is "group", then the 'value' attribute SHOULD contain the name of a group
+          * in the user's roster.
+          * If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
+          * "from", or "none".
+          *
+          * @return the identifier to apply the action.
+          */
+         public String getValue() {
+     		return value;
+     	}
+
+         /**
+          * Sets the element identifier to apply the action.
+          *
+          * If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
+          * If the type is "group", then the 'value' attribute SHOULD contain the name of a group
+          * in the user's roster.
+          * If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
+          * "from", or "none".
+          *
+          * @param value is the identifier to apply the action.
+          */
+         protected void setValue(String value) {
+        	 if (this.isSuscription()) {
+        		 setSuscriptionValue(value);
+        	 } else {
+        		 this.value = value;
+        	 }
+     	}
+
+         /**
+          * Sets the element identifier to apply the action.
+          *
+          * The 'value' attribute MUST be one of "both", "to", "from", or "none".
+          *
+          * @param value is the identifier to apply the action.
+          */
+         private void setSuscriptionValue(String value) {
+        	 String setValue;
+             if (value == null) {
+            	 // Do nothing
+             }
+             if (SUBSCRIPTION_BOTH.equalsIgnoreCase(value)) {
+            	 setValue = SUBSCRIPTION_BOTH;
+             }
+             else if (SUBSCRIPTION_TO.equalsIgnoreCase(value)) {
+            	 setValue = SUBSCRIPTION_TO;
+             }
+             else if (SUBSCRIPTION_FROM.equalsIgnoreCase(value)) {
+            	 setValue = SUBSCRIPTION_FROM;
+             }
+             else if (SUBSCRIPTION_NONE.equalsIgnoreCase(value)) {
+            	 setValue = SUBSCRIPTION_NONE;
+             }
+             // Default to available.
+             else {
+            	 setValue = null;
+             }
+     		this.value = setValue;
+     	}
+
+         /**
+          * Returns if the receiver represents a subscription rule.
+          *
+          * @return if the receiver represents a subscription rule.
+          */
+         public boolean isSuscription () {
+     		return this.getType() == Type.subscription;
+     	}
+    }
+
+    /**
+     * Type defines if the rule is based on JIDs, roster groups or presence subscription types.
+     */
+    public static enum Type {
+        /**
+         * JID being analyzed should belong to a roster group of the list's owner.
+         */
+        group,
+        /**
+         * JID being analyzed should have a resource match, domain match or bare JID match.
+         */
+        jid,
+        /**
+         * JID being analyzed should belong to a contact present in the owner's roster with
+         * the specified subscription status.
+         */
+        subscription
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/Session.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/Session.java
index fd403ae..427c01a 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/Session.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/Session.java
@@ -1,45 +1,45 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack.packet;
-
-/**
- * IQ packet that will be sent to the server to establish a session.<p>
- *
- * If a server supports sessions, it MUST include a <i>session</i> element in the
- * stream features it advertises to a client after the completion of stream authentication.
- * Upon being informed that session establishment is required by the server the client MUST
- * establish a session if it desires to engage in instant messaging and presence functionality.<p>
- *
- * For more information refer to the following
- * <a href=http://www.xmpp.org/specs/rfc3921.html#session>link</a>.
- *
- * @author Gaston Dombiak
- */
-public class Session extends IQ {
-
-    public Session() {
-        setType(IQ.Type.SET);
-    }
-
-    public String getChildElementXML() {
-        return "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/>";
-    }
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack.packet;
+
+/**
+ * IQ packet that will be sent to the server to establish a session.<p>
+ *
+ * If a server supports sessions, it MUST include a <i>session</i> element in the
+ * stream features it advertises to a client after the completion of stream authentication.
+ * Upon being informed that session establishment is required by the server the client MUST
+ * establish a session if it desires to engage in instant messaging and presence functionality.<p>
+ *
+ * For more information refer to the following
+ * <a href=http://www.xmpp.org/specs/rfc3921.html#session>link</a>.
+ *
+ * @author Gaston Dombiak
+ */
+public class Session extends IQ {
+
+    public Session() {
+        setType(IQ.Type.SET);
+    }
+
+    public String getChildElementXML() {
+        return "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/>";
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/StreamError.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/StreamError.java
index 8bb4c75..72679a8 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/StreamError.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/StreamError.java
@@ -1,106 +1,106 @@
-/**
- * $Revision: 2408 $
- * $Date: 2004-11-02 20:53:30 -0300 (Tue, 02 Nov 2004) $
- *
- * Copyright 2003-2005 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack.packet;
-
-/**
- * Represents a stream error packet. Stream errors are unrecoverable errors where the server
- * will close the unrelying TCP connection after the stream error was sent to the client.
- * These is the list of stream errors as defined in the XMPP spec:<p>
- *
- * <table border=1>
- *      <tr><td><b>Code</b></td><td><b>Description</b></td></tr>
- *      <tr><td> bad-format </td><td> the entity has sent XML that cannot be processed </td></tr>
- *      <tr><td> unsupported-encoding </td><td>  the entity has sent a namespace prefix that is
- *          unsupported </td></tr>
- *      <tr><td> bad-namespace-prefix </td><td> Remote Server Timeout </td></tr>
- *      <tr><td> conflict </td><td> the server is closing the active stream for this entity
- *          because a new stream has been initiated that conflicts with the existing
- *          stream. </td></tr>
- *      <tr><td> connection-timeout </td><td> the entity has not generated any traffic over
- *          the stream for some period of time. </td></tr>
- *      <tr><td> host-gone </td><td> the value of the 'to' attribute provided by the initiating
- *          entity in the stream header corresponds to a hostname that is no longer hosted by
- *          the server. </td></tr>
- *      <tr><td> host-unknown </td><td> the value of the 'to' attribute provided by the
- *          initiating entity in the stream header does not correspond to a hostname that is
- *          hosted by the server. </td></tr>
- *      <tr><td> improper-addressing </td><td> a stanza sent between two servers lacks a 'to'
- *          or 'from' attribute </td></tr>
- *      <tr><td> internal-server-error </td><td> the server has experienced a
- *          misconfiguration. </td></tr>
- *      <tr><td> invalid-from </td><td> the JID or hostname provided in a 'from' address does
- *          not match an authorized JID. </td></tr>
- *      <tr><td> invalid-id </td><td> the stream ID or dialback ID is invalid or does not match
- *          an ID previously provided. </td></tr>
- *      <tr><td> invalid-namespace </td><td> the streams namespace name is invalid. </td></tr>
- *      <tr><td> invalid-xml </td><td> the entity has sent invalid XML over the stream. </td></tr>
- *      <tr><td> not-authorized </td><td> the entity has attempted to send data before the
- *          stream has been authenticated </td></tr>
- *      <tr><td> policy-violation </td><td> the entity has violated some local service
- *          policy. </td></tr>
- *      <tr><td> remote-connection-failed </td><td> Rthe server is unable to properly connect
- *          to a remote entity. </td></tr>
- *      <tr><td> resource-constraint </td><td> Rthe server lacks the system resources necessary
- *          to service the stream. </td></tr>
- *      <tr><td> restricted-xml </td><td> the entity has attempted to send restricted XML
- *          features. </td></tr>
- *      <tr><td> see-other-host </td><td>  the server will not provide service to the initiating
- *          entity but is redirecting traffic to another host. </td></tr>
- *      <tr><td> system-shutdown </td><td> the server is being shut down and all active streams
- *          are being closed. </td></tr>
- *      <tr><td> undefined-condition </td><td> the error condition is not one of those defined
- *          by the other conditions in this list. </td></tr>
- *      <tr><td> unsupported-encoding </td><td> the initiating entity has encoded the stream in
- *          an encoding that is not supported. </td></tr>
- *      <tr><td> unsupported-stanza-type </td><td> the initiating entity has sent a first-level
- *          child of the stream that is not supported. </td></tr>
- *      <tr><td> unsupported-version </td><td> the value of the 'version' attribute provided by
- *          the initiating entity in the stream header specifies a version of XMPP that is not
- *          supported. </td></tr>
- *      <tr><td> xml-not-well-formed </td><td> the initiating entity has sent XML that is
- *          not well-formed. </td></tr>
- * </table>
- *
- * @author Gaston Dombiak
- */
-public class StreamError {
-
-    private String code;
-
-    public StreamError(String code) {
-        super();
-        this.code = code;
-    }
-
-    /**
-     * Returns the error code.
-     *
-     * @return the error code.
-     */
-    public String getCode() {
-        return code;
-    }
-
-    public String toString() {
-        StringBuilder txt = new StringBuilder();
-        txt.append("stream:error (").append(code).append(")");
-        return txt.toString();
-    }
-}
+/**
+ * $Revision: 2408 $
+ * $Date: 2004-11-02 20:53:30 -0300 (Tue, 02 Nov 2004) $
+ *
+ * Copyright 2003-2005 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack.packet;
+
+/**
+ * Represents a stream error packet. Stream errors are unrecoverable errors where the server
+ * will close the unrelying TCP connection after the stream error was sent to the client.
+ * These is the list of stream errors as defined in the XMPP spec:<p>
+ *
+ * <table border=1>
+ *      <tr><td><b>Code</b></td><td><b>Description</b></td></tr>
+ *      <tr><td> bad-format </td><td> the entity has sent XML that cannot be processed </td></tr>
+ *      <tr><td> unsupported-encoding </td><td>  the entity has sent a namespace prefix that is
+ *          unsupported </td></tr>
+ *      <tr><td> bad-namespace-prefix </td><td> Remote Server Timeout </td></tr>
+ *      <tr><td> conflict </td><td> the server is closing the active stream for this entity
+ *          because a new stream has been initiated that conflicts with the existing
+ *          stream. </td></tr>
+ *      <tr><td> connection-timeout </td><td> the entity has not generated any traffic over
+ *          the stream for some period of time. </td></tr>
+ *      <tr><td> host-gone </td><td> the value of the 'to' attribute provided by the initiating
+ *          entity in the stream header corresponds to a hostname that is no longer hosted by
+ *          the server. </td></tr>
+ *      <tr><td> host-unknown </td><td> the value of the 'to' attribute provided by the
+ *          initiating entity in the stream header does not correspond to a hostname that is
+ *          hosted by the server. </td></tr>
+ *      <tr><td> improper-addressing </td><td> a stanza sent between two servers lacks a 'to'
+ *          or 'from' attribute </td></tr>
+ *      <tr><td> internal-server-error </td><td> the server has experienced a
+ *          misconfiguration. </td></tr>
+ *      <tr><td> invalid-from </td><td> the JID or hostname provided in a 'from' address does
+ *          not match an authorized JID. </td></tr>
+ *      <tr><td> invalid-id </td><td> the stream ID or dialback ID is invalid or does not match
+ *          an ID previously provided. </td></tr>
+ *      <tr><td> invalid-namespace </td><td> the streams namespace name is invalid. </td></tr>
+ *      <tr><td> invalid-xml </td><td> the entity has sent invalid XML over the stream. </td></tr>
+ *      <tr><td> not-authorized </td><td> the entity has attempted to send data before the
+ *          stream has been authenticated </td></tr>
+ *      <tr><td> policy-violation </td><td> the entity has violated some local service
+ *          policy. </td></tr>
+ *      <tr><td> remote-connection-failed </td><td> Rthe server is unable to properly connect
+ *          to a remote entity. </td></tr>
+ *      <tr><td> resource-constraint </td><td> Rthe server lacks the system resources necessary
+ *          to service the stream. </td></tr>
+ *      <tr><td> restricted-xml </td><td> the entity has attempted to send restricted XML
+ *          features. </td></tr>
+ *      <tr><td> see-other-host </td><td>  the server will not provide service to the initiating
+ *          entity but is redirecting traffic to another host. </td></tr>
+ *      <tr><td> system-shutdown </td><td> the server is being shut down and all active streams
+ *          are being closed. </td></tr>
+ *      <tr><td> undefined-condition </td><td> the error condition is not one of those defined
+ *          by the other conditions in this list. </td></tr>
+ *      <tr><td> unsupported-encoding </td><td> the initiating entity has encoded the stream in
+ *          an encoding that is not supported. </td></tr>
+ *      <tr><td> unsupported-stanza-type </td><td> the initiating entity has sent a first-level
+ *          child of the stream that is not supported. </td></tr>
+ *      <tr><td> unsupported-version </td><td> the value of the 'version' attribute provided by
+ *          the initiating entity in the stream header specifies a version of XMPP that is not
+ *          supported. </td></tr>
+ *      <tr><td> xml-not-well-formed </td><td> the initiating entity has sent XML that is
+ *          not well-formed. </td></tr>
+ * </table>
+ *
+ * @author Gaston Dombiak
+ */
+public class StreamError {
+
+    private String code;
+
+    public StreamError(String code) {
+        super();
+        this.code = code;
+    }
+
+    /**
+     * Returns the error code.
+     *
+     * @return the error code.
+     */
+    public String getCode() {
+        return code;
+    }
+
+    public String toString() {
+        StringBuilder txt = new StringBuilder();
+        txt.append("stream:error (").append(code).append(")");
+        return txt.toString();
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/provider/EmbeddedExtensionProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/provider/EmbeddedExtensionProvider.java
index e7b4b93..84b5079 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/provider/EmbeddedExtensionProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/provider/EmbeddedExtensionProvider.java
@@ -1,109 +1,109 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack.provider;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.jivesoftware.smack.util.PacketParserUtils;
-import org.jivesoftware.smackx.pubsub.provider.ItemProvider;
-import org.jivesoftware.smackx.pubsub.provider.ItemsProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * 
- * This class simplifies parsing of embedded elements by using the 
- * <a href="http://en.wikipedia.org/wiki/Template_method_pattern">Template Method Pattern</a>.  
- * After extracting the current element attributes and content of any child elements, the template method 
- * ({@link #createReturnExtension(String, String, Map, List)} is called.  Subclasses
- * then override this method to create the specific return type.
- * 
- * <p>To use this class, you simply register your subclasses as extension providers in the 
- * <b>smack.properties</b> file.  Then they will be automatically picked up and used to parse
- * any child elements.  
- * 
- * <pre>
- * For example, given the following message
- * 
- * &lt;message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo&gt;
- *    &lt;event xmlns='http://jabber.org/protocol/pubsub#event&gt;
- *       &lt;items node='princely_musings'&gt;
- *          &lt;item id='asdjkwei3i34234n356'&gt;
- *             &lt;entry xmlns='http://www.w3.org/2005/Atom'&gt;
- *                &lt;title&gt;Soliloquy&lt;/title&gt;
- *                &lt;link rel='alternative' type='text/html'/&gt;
- *                &lt;id>tag:denmark.lit,2003:entry-32397&lt;/id&gt;
- *             &lt;/entry&gt;
- *          &lt;/item&gt;
- *       &lt;/items&gt;
- *    &lt;/event&gt;
- * &lt;/message&gt;
- * 
- * I would have a classes
- * {@link ItemsProvider} extends {@link EmbeddedExtensionProvider}
- * {@link ItemProvider} extends {@link EmbeddedExtensionProvider}
- * and
- * AtomProvider extends {@link PacketExtensionProvider}
- * 
- * These classes are then registered in the meta-inf/smack.providers file
- * as follows.
- * 
- *   &lt;extensionProvider&gt;
- *      &lt;elementName&gt;items&lt;/elementName&gt;
- *      &lt;namespace&gt;http://jabber.org/protocol/pubsub#event&lt;/namespace&gt;
- *      &lt;className&gt;org.jivesoftware.smackx.provider.ItemsEventProvider&lt;/className&gt;
- *   &lt;/extensionProvider&gt;
- *   &lt;extensionProvider&gt;
- *       &lt;elementName&gt;item&lt;/elementName&gt;
- *       &lt;namespace&gt;http://jabber.org/protocol/pubsub#event&lt;/namespace&gt;
- *       &lt;className&gt;org.jivesoftware.smackx.provider.ItemProvider&lt;/className&gt;
- *   &lt;/extensionProvider&gt;
- * 
- * </pre>
- * 
- * @author Robin Collier
- */
-abstract public class EmbeddedExtensionProvider implements PacketExtensionProvider
-{
-
-	final public PacketExtension parseExtension(XmlPullParser parser) throws Exception
-	{
-        String namespace = parser.getNamespace();
-        String name = parser.getName();
-        Map<String, String> attMap = new HashMap<String, String>();
-        
-        for(int i=0; i<parser.getAttributeCount(); i++)
-        {
-        	attMap.put(parser.getAttributeName(i), parser.getAttributeValue(i));
-        }
-        List<PacketExtension> extensions = new ArrayList<PacketExtension>();
-        
-        do
-        {
-            int tag = parser.next();
-
-            if (tag == XmlPullParser.START_TAG) 
-            	extensions.add(PacketParserUtils.parsePacketExtension(parser.getName(), parser.getNamespace(), parser));
-        } while (!name.equals(parser.getName()));
-
-		return createReturnExtension(name, namespace, attMap, extensions);
-	}
-
-	abstract protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content);
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack.provider;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.jivesoftware.smack.util.PacketParserUtils;
+import org.jivesoftware.smackx.pubsub.provider.ItemProvider;
+import org.jivesoftware.smackx.pubsub.provider.ItemsProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * 
+ * This class simplifies parsing of embedded elements by using the 
+ * <a href="http://en.wikipedia.org/wiki/Template_method_pattern">Template Method Pattern</a>.  
+ * After extracting the current element attributes and content of any child elements, the template method 
+ * ({@link #createReturnExtension(String, String, Map, List)} is called.  Subclasses
+ * then override this method to create the specific return type.
+ * 
+ * <p>To use this class, you simply register your subclasses as extension providers in the 
+ * <b>smack.properties</b> file.  Then they will be automatically picked up and used to parse
+ * any child elements.  
+ * 
+ * <pre>
+ * For example, given the following message
+ * 
+ * &lt;message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo&gt;
+ *    &lt;event xmlns='http://jabber.org/protocol/pubsub#event&gt;
+ *       &lt;items node='princely_musings'&gt;
+ *          &lt;item id='asdjkwei3i34234n356'&gt;
+ *             &lt;entry xmlns='http://www.w3.org/2005/Atom'&gt;
+ *                &lt;title&gt;Soliloquy&lt;/title&gt;
+ *                &lt;link rel='alternative' type='text/html'/&gt;
+ *                &lt;id>tag:denmark.lit,2003:entry-32397&lt;/id&gt;
+ *             &lt;/entry&gt;
+ *          &lt;/item&gt;
+ *       &lt;/items&gt;
+ *    &lt;/event&gt;
+ * &lt;/message&gt;
+ * 
+ * I would have a classes
+ * {@link ItemsProvider} extends {@link EmbeddedExtensionProvider}
+ * {@link ItemProvider} extends {@link EmbeddedExtensionProvider}
+ * and
+ * AtomProvider extends {@link PacketExtensionProvider}
+ * 
+ * These classes are then registered in the meta-inf/smack.providers file
+ * as follows.
+ * 
+ *   &lt;extensionProvider&gt;
+ *      &lt;elementName&gt;items&lt;/elementName&gt;
+ *      &lt;namespace&gt;http://jabber.org/protocol/pubsub#event&lt;/namespace&gt;
+ *      &lt;className&gt;org.jivesoftware.smackx.provider.ItemsEventProvider&lt;/className&gt;
+ *   &lt;/extensionProvider&gt;
+ *   &lt;extensionProvider&gt;
+ *       &lt;elementName&gt;item&lt;/elementName&gt;
+ *       &lt;namespace&gt;http://jabber.org/protocol/pubsub#event&lt;/namespace&gt;
+ *       &lt;className&gt;org.jivesoftware.smackx.provider.ItemProvider&lt;/className&gt;
+ *   &lt;/extensionProvider&gt;
+ * 
+ * </pre>
+ * 
+ * @author Robin Collier
+ */
+abstract public class EmbeddedExtensionProvider implements PacketExtensionProvider
+{
+
+	final public PacketExtension parseExtension(XmlPullParser parser) throws Exception
+	{
+        String namespace = parser.getNamespace();
+        String name = parser.getName();
+        Map<String, String> attMap = new HashMap<String, String>();
+        
+        for(int i=0; i<parser.getAttributeCount(); i++)
+        {
+        	attMap.put(parser.getAttributeName(i), parser.getAttributeValue(i));
+        }
+        List<PacketExtension> extensions = new ArrayList<PacketExtension>();
+        
+        do
+        {
+            int tag = parser.next();
+
+            if (tag == XmlPullParser.START_TAG) 
+            	extensions.add(PacketParserUtils.parsePacketExtension(parser.getName(), parser.getNamespace(), parser));
+        } while (!name.equals(parser.getName()));
+
+		return createReturnExtension(name, namespace, attMap, extensions);
+	}
+
+	abstract protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content);
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/provider/PrivacyProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/provider/PrivacyProvider.java
index 62b3120..4ce9ea6 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/provider/PrivacyProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/provider/PrivacyProvider.java
@@ -15,137 +15,137 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jivesoftware.smack.provider;
-
-import org.jivesoftware.smack.packet.DefaultPacketExtension;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Privacy;
-import org.jivesoftware.smack.packet.PrivacyItem;
-import org.xmlpull.v1.XmlPullParser;
-
-import java.util.ArrayList;
-
-/**
- * The PrivacyProvider parses {@link Privacy} packets. {@link Privacy}
- * Parses the <tt>query</tt> sub-document and creates an instance of {@link Privacy}.
- * For each <tt>item</tt> in the <tt>list</tt> element, it creates an instance 
- * of {@link PrivacyItem} and {@link org.jivesoftware.smack.packet.PrivacyItem.PrivacyRule}.
- * 
- * @author Francisco Vives
- */
-public class PrivacyProvider implements IQProvider {
-
-	public PrivacyProvider() {
-	}
-
-	public IQ parseIQ(XmlPullParser parser) throws Exception {
-        Privacy privacy = new Privacy();
-        /* privacy.addExtension(PacketParserUtils.parsePacketExtension(parser
-                .getName(), parser.getNamespace(), parser)); */
-        privacy.addExtension(new DefaultPacketExtension(parser.getName(), parser.getNamespace()));
-        boolean done = false;
-        while (!done) {
-            int eventType = parser.next();
-            if (eventType == XmlPullParser.START_TAG) {
-                if (parser.getName().equals("active")) {
-                	String activeName = parser.getAttributeValue("", "name");
-                	if (activeName == null) {
-                		privacy.setDeclineActiveList(true);
-                	} else {
-                		privacy.setActiveName(activeName);
-                	}
-                }
-                else if (parser.getName().equals("default")) {
-                	String defaultName = parser.getAttributeValue("", "name");
-                	if (defaultName == null) {
-                		privacy.setDeclineDefaultList(true);
-                	} else {
-                		privacy.setDefaultName(defaultName);
-                	}
-                }
-                else if (parser.getName().equals("list")) {
-                    parseList(parser, privacy);
-                }
-            }
-            else if (eventType == XmlPullParser.END_TAG) {
-                if (parser.getName().equals("query")) {
-                    done = true;
-                }
-            }
-        }
-
-        return privacy;
-	}
-	
-	// Parse the list complex type
-	public void parseList(XmlPullParser parser, Privacy privacy) throws Exception {
-        boolean done = false;
-        String listName = parser.getAttributeValue("", "name");
-        ArrayList<PrivacyItem> items = new ArrayList<PrivacyItem>();
-        while (!done) {
-            int eventType = parser.next();
-            if (eventType == XmlPullParser.START_TAG) {
-                if (parser.getName().equals("item")) {
-                	items.add(parseItem(parser));
-                }
-            }
-            else if (eventType == XmlPullParser.END_TAG) {
-                if (parser.getName().equals("list")) {
-                    done = true;
-                }
-            }
-        }
-
-        privacy.setPrivacyList(listName, items);
-	}
-	
-	// Parse the list complex type
-	public PrivacyItem parseItem(XmlPullParser parser) throws Exception {
-        boolean done = false;
-        // Retrieves the required attributes
-        String actionValue = parser.getAttributeValue("", "action");
-        String orderValue = parser.getAttributeValue("", "order");
-        String type = parser.getAttributeValue("", "type");
-        
-        /* 
-         * According the action value it sets the allow status. The fall-through action is assumed 
-         * to be "allow"
-         */
-        boolean allow = true;
-        if ("allow".equalsIgnoreCase(actionValue)) {
-        	allow = true;
-        } else if ("deny".equalsIgnoreCase(actionValue)) {
-        	allow = false;
-        }
-        // Set the order number
-        int order = Integer.parseInt(orderValue);
-
-        // Create the privacy item
-        PrivacyItem item = new PrivacyItem(type, allow, order);
-        item.setValue(parser.getAttributeValue("", "value"));
-
-        while (!done) {
-            int eventType = parser.next();
-            if (eventType == XmlPullParser.START_TAG) {
-                if (parser.getName().equals("iq")) {
-                	item.setFilterIQ(true);
-                }
-                if (parser.getName().equals("message")) {
-                	item.setFilterMessage(true);
-                }
-                if (parser.getName().equals("presence-in")) {
-                	item.setFilterPresence_in(true);
-                }
-                if (parser.getName().equals("presence-out")) {
-                	item.setFilterPresence_out(true);
-                }
-            }
-            else if (eventType == XmlPullParser.END_TAG) {
-                if (parser.getName().equals("item")) {
-                    done = true;
-                }
-            }
-        }
-        return item;
-	}
-}
+package org.jivesoftware.smack.provider;
+
+import org.jivesoftware.smack.packet.DefaultPacketExtension;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Privacy;
+import org.jivesoftware.smack.packet.PrivacyItem;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.util.ArrayList;
+
+/**
+ * The PrivacyProvider parses {@link Privacy} packets. {@link Privacy}
+ * Parses the <tt>query</tt> sub-document and creates an instance of {@link Privacy}.
+ * For each <tt>item</tt> in the <tt>list</tt> element, it creates an instance 
+ * of {@link PrivacyItem} and {@link org.jivesoftware.smack.packet.PrivacyItem.PrivacyRule}.
+ * 
+ * @author Francisco Vives
+ */
+public class PrivacyProvider implements IQProvider {
+
+	public PrivacyProvider() {
+	}
+
+	public IQ parseIQ(XmlPullParser parser) throws Exception {
+        Privacy privacy = new Privacy();
+        /* privacy.addExtension(PacketParserUtils.parsePacketExtension(parser
+                .getName(), parser.getNamespace(), parser)); */
+        privacy.addExtension(new DefaultPacketExtension(parser.getName(), parser.getNamespace()));
+        boolean done = false;
+        while (!done) {
+            int eventType = parser.next();
+            if (eventType == XmlPullParser.START_TAG) {
+                if (parser.getName().equals("active")) {
+                	String activeName = parser.getAttributeValue("", "name");
+                	if (activeName == null) {
+                		privacy.setDeclineActiveList(true);
+                	} else {
+                		privacy.setActiveName(activeName);
+                	}
+                }
+                else if (parser.getName().equals("default")) {
+                	String defaultName = parser.getAttributeValue("", "name");
+                	if (defaultName == null) {
+                		privacy.setDeclineDefaultList(true);
+                	} else {
+                		privacy.setDefaultName(defaultName);
+                	}
+                }
+                else if (parser.getName().equals("list")) {
+                    parseList(parser, privacy);
+                }
+            }
+            else if (eventType == XmlPullParser.END_TAG) {
+                if (parser.getName().equals("query")) {
+                    done = true;
+                }
+            }
+        }
+
+        return privacy;
+	}
+	
+	// Parse the list complex type
+	public void parseList(XmlPullParser parser, Privacy privacy) throws Exception {
+        boolean done = false;
+        String listName = parser.getAttributeValue("", "name");
+        ArrayList<PrivacyItem> items = new ArrayList<PrivacyItem>();
+        while (!done) {
+            int eventType = parser.next();
+            if (eventType == XmlPullParser.START_TAG) {
+                if (parser.getName().equals("item")) {
+                	items.add(parseItem(parser));
+                }
+            }
+            else if (eventType == XmlPullParser.END_TAG) {
+                if (parser.getName().equals("list")) {
+                    done = true;
+                }
+            }
+        }
+
+        privacy.setPrivacyList(listName, items);
+	}
+	
+	// Parse the list complex type
+	public PrivacyItem parseItem(XmlPullParser parser) throws Exception {
+        boolean done = false;
+        // Retrieves the required attributes
+        String actionValue = parser.getAttributeValue("", "action");
+        String orderValue = parser.getAttributeValue("", "order");
+        String type = parser.getAttributeValue("", "type");
+        
+        /* 
+         * According the action value it sets the allow status. The fall-through action is assumed 
+         * to be "allow"
+         */
+        boolean allow = true;
+        if ("allow".equalsIgnoreCase(actionValue)) {
+        	allow = true;
+        } else if ("deny".equalsIgnoreCase(actionValue)) {
+        	allow = false;
+        }
+        // Set the order number
+        int order = Integer.parseInt(orderValue);
+
+        // Create the privacy item
+        PrivacyItem item = new PrivacyItem(type, allow, order);
+        item.setValue(parser.getAttributeValue("", "value"));
+
+        while (!done) {
+            int eventType = parser.next();
+            if (eventType == XmlPullParser.START_TAG) {
+                if (parser.getName().equals("iq")) {
+                	item.setFilterIQ(true);
+                }
+                if (parser.getName().equals("message")) {
+                	item.setFilterMessage(true);
+                }
+                if (parser.getName().equals("presence-in")) {
+                	item.setFilterPresence_in(true);
+                }
+                if (parser.getName().equals("presence-out")) {
+                	item.setFilterPresence_out(true);
+                }
+            }
+            else if (eventType == XmlPullParser.END_TAG) {
+                if (parser.getName().equals("item")) {
+                    done = true;
+                }
+            }
+        }
+        return item;
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLAnonymous.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLAnonymous.java
index 8ef9d18..b959e96 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLAnonymous.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLAnonymous.java
@@ -1,62 +1,62 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack.sasl;
-
-import org.jivesoftware.smack.SASLAuthentication;
-
-import java.io.IOException;
-import javax.security.auth.callback.CallbackHandler;
-
-/**
- * Implementation of the SASL ANONYMOUS mechanism
- *
- * @author Jay Kline
- */
-public class SASLAnonymous extends SASLMechanism {
-
-    public SASLAnonymous(SASLAuthentication saslAuthentication) {
-        super(saslAuthentication);
-    }
-
-    protected String getName() {
-        return "ANONYMOUS";
-    }
-
-    public void authenticate(String username, String host, CallbackHandler cbh) throws IOException {
-        authenticate();
-    }
-
-    public void authenticate(String username, String host, String password) throws IOException {
-        authenticate();
-    }
-
-    protected void authenticate() throws IOException {
-        // Send the authentication to the server
-        getSASLAuthentication().send(new AuthMechanism(getName(), null));
-    }
-
-    public void challengeReceived(String challenge) throws IOException {
-        // Build the challenge response stanza encoding the response text
-        // and send the authentication to the server
-        getSASLAuthentication().send(new Response());
-    }
-
-
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack.sasl;
+
+import org.jivesoftware.smack.SASLAuthentication;
+
+import java.io.IOException;
+import javax.security.auth.callback.CallbackHandler;
+
+/**
+ * Implementation of the SASL ANONYMOUS mechanism
+ *
+ * @author Jay Kline
+ */
+public class SASLAnonymous extends SASLMechanism {
+
+    public SASLAnonymous(SASLAuthentication saslAuthentication) {
+        super(saslAuthentication);
+    }
+
+    protected String getName() {
+        return "ANONYMOUS";
+    }
+
+    public void authenticate(String username, String host, CallbackHandler cbh) throws IOException {
+        authenticate();
+    }
+
+    public void authenticate(String username, String host, String password) throws IOException {
+        authenticate();
+    }
+
+    protected void authenticate() throws IOException {
+        // Send the authentication to the server
+        getSASLAuthentication().send(new AuthMechanism(getName(), null));
+    }
+
+    public void challengeReceived(String challenge) throws IOException {
+        // Build the challenge response stanza encoding the response text
+        // and send the authentication to the server
+        getSASLAuthentication().send(new Response());
+    }
+
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLCramMD5Mechanism.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLCramMD5Mechanism.java
index 82d218f..f2be038 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLCramMD5Mechanism.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLCramMD5Mechanism.java
@@ -1,38 +1,38 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack.sasl;
-
-import org.jivesoftware.smack.SASLAuthentication;
-
-/**
- * Implementation of the SASL CRAM-MD5 mechanism
- *
- * @author Jay Kline
- */
-public class SASLCramMD5Mechanism extends SASLMechanism {
-
-    public SASLCramMD5Mechanism(SASLAuthentication saslAuthentication) {
-        super(saslAuthentication);
-    }
-
-    protected String getName() {
-        return "CRAM-MD5";
-    }
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack.sasl;
+
+import org.jivesoftware.smack.SASLAuthentication;
+
+/**
+ * Implementation of the SASL CRAM-MD5 mechanism
+ *
+ * @author Jay Kline
+ */
+public class SASLCramMD5Mechanism extends SASLMechanism {
+
+    public SASLCramMD5Mechanism(SASLAuthentication saslAuthentication) {
+        super(saslAuthentication);
+    }
+
+    protected String getName() {
+        return "CRAM-MD5";
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLDigestMD5Mechanism.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLDigestMD5Mechanism.java
index 7af65fb..bfaec0a 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLDigestMD5Mechanism.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLDigestMD5Mechanism.java
@@ -1,38 +1,38 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack.sasl;
-
-import org.jivesoftware.smack.SASLAuthentication;
-
-/**
- * Implementation of the SASL DIGEST-MD5 mechanism
- *
- * @author Jay Kline
- */
-public class SASLDigestMD5Mechanism extends SASLMechanism {
-
-    public SASLDigestMD5Mechanism(SASLAuthentication saslAuthentication) {
-        super(saslAuthentication);
-    }
-
-    protected String getName() {
-        return "DIGEST-MD5";
-    }
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack.sasl;
+
+import org.jivesoftware.smack.SASLAuthentication;
+
+/**
+ * Implementation of the SASL DIGEST-MD5 mechanism
+ *
+ * @author Jay Kline
+ */
+public class SASLDigestMD5Mechanism extends SASLMechanism {
+
+    public SASLDigestMD5Mechanism(SASLAuthentication saslAuthentication) {
+        super(saslAuthentication);
+    }
+
+    protected String getName() {
+        return "DIGEST-MD5";
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLExternalMechanism.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLExternalMechanism.java
index dff18fb..248a650 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLExternalMechanism.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLExternalMechanism.java
@@ -1,59 +1,59 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack.sasl;
-
-import org.jivesoftware.smack.SASLAuthentication;
-
-/**
- * Implementation of the SASL EXTERNAL mechanism.
- *
- * To effectively use this mechanism, Java must be configured to properly 
- * supply a client SSL certificate (of some sort) to the server. It is up
- * to the implementer to determine how to do this.  Here is one method:
- *
- * Create a java keystore with your SSL certificate in it:
- * keytool -genkey -alias username -dname "cn=username,ou=organizationalUnit,o=organizationaName,l=locality,s=state,c=country"
- *
- * Next, set the System Properties:
- *  <ul>
- *  <li>javax.net.ssl.keyStore to the location of the keyStore
- *  <li>javax.net.ssl.keyStorePassword to the password of the keyStore
- *  <li>javax.net.ssl.trustStore to the location of the trustStore
- *  <li>javax.net.ssl.trustStorePassword to the the password of the trustStore
- *  </ul>
- *
- * Then, when the server requests or requires the client certificate, java will
- * simply provide the one in the keyStore.
- *
- * Also worth noting is the EXTERNAL mechanism in Smack is not enabled by default.
- * To enable it, the implementer will need to call SASLAuthentication.supportSASLMechamism("EXTERNAL");
- *
- * @author Jay Kline
- */
-public class SASLExternalMechanism extends SASLMechanism  {
-
-    public SASLExternalMechanism(SASLAuthentication saslAuthentication) {
-        super(saslAuthentication);
-    }
-
-    protected String getName() {
-        return "EXTERNAL";
-    }
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack.sasl;
+
+import org.jivesoftware.smack.SASLAuthentication;
+
+/**
+ * Implementation of the SASL EXTERNAL mechanism.
+ *
+ * To effectively use this mechanism, Java must be configured to properly 
+ * supply a client SSL certificate (of some sort) to the server. It is up
+ * to the implementer to determine how to do this.  Here is one method:
+ *
+ * Create a java keystore with your SSL certificate in it:
+ * keytool -genkey -alias username -dname "cn=username,ou=organizationalUnit,o=organizationaName,l=locality,s=state,c=country"
+ *
+ * Next, set the System Properties:
+ *  <ul>
+ *  <li>javax.net.ssl.keyStore to the location of the keyStore
+ *  <li>javax.net.ssl.keyStorePassword to the password of the keyStore
+ *  <li>javax.net.ssl.trustStore to the location of the trustStore
+ *  <li>javax.net.ssl.trustStorePassword to the the password of the trustStore
+ *  </ul>
+ *
+ * Then, when the server requests or requires the client certificate, java will
+ * simply provide the one in the keyStore.
+ *
+ * Also worth noting is the EXTERNAL mechanism in Smack is not enabled by default.
+ * To enable it, the implementer will need to call SASLAuthentication.supportSASLMechamism("EXTERNAL");
+ *
+ * @author Jay Kline
+ */
+public class SASLExternalMechanism extends SASLMechanism  {
+
+    public SASLExternalMechanism(SASLAuthentication saslAuthentication) {
+        super(saslAuthentication);
+    }
+
+    protected String getName() {
+        return "EXTERNAL";
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLGSSAPIMechanism.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLGSSAPIMechanism.java
index 3f0b7d8..8101ca5 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLGSSAPIMechanism.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLGSSAPIMechanism.java
@@ -1,89 +1,89 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack.sasl;
-
-import org.jivesoftware.smack.SASLAuthentication;
-import org.jivesoftware.smack.XMPPException;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.HashMap;
-import javax.security.sasl.Sasl;
-import javax.security.auth.callback.CallbackHandler;
-
-/**
- * Implementation of the SASL GSSAPI mechanism
- *
- * @author Jay Kline
- */
-public class SASLGSSAPIMechanism extends SASLMechanism {
-
-    public SASLGSSAPIMechanism(SASLAuthentication saslAuthentication) {
-        super(saslAuthentication);
-
-        System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
-        System.setProperty("java.security.auth.login.config","gss.conf");
-
-    }
-
-    protected String getName() {
-        return "GSSAPI";
-    }
-
-    /**
-     * Builds and sends the <tt>auth</tt> stanza to the server.
-     * This overrides from the abstract class because the initial token
-     * needed for GSSAPI is binary, and not safe to put in a string, thus
-     * getAuthenticationText() cannot be used.
-     *
-     * @param username the username of the user being authenticated.
-     * @param host     the hostname where the user account resides.
-     * @param cbh      the CallbackHandler (not used with GSSAPI)
-     * @throws IOException If a network error occures while authenticating.
-     */
-    public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, XMPPException {
-        String[] mechanisms = { getName() };
-        Map<String,String> props = new HashMap<String,String>();
-        props.put(Sasl.SERVER_AUTH,"TRUE");
-        sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, cbh);
-        authenticate();
-    }
-
-    /**
-     * Builds and sends the <tt>auth</tt> stanza to the server.
-     * This overrides from the abstract class because the initial token
-     * needed for GSSAPI is binary, and not safe to put in a string, thus
-     * getAuthenticationText() cannot be used.
-     *
-     * @param username the username of the user being authenticated.
-     * @param host     the hostname where the user account resides.
-     * @param password the password of the user (ignored for GSSAPI)
-     * @throws IOException If a network error occures while authenticating.
-     */
-    public void authenticate(String username, String host, String password) throws IOException, XMPPException {
-        String[] mechanisms = { getName() };
-        Map<String,String> props = new HashMap<String, String>();
-        props.put(Sasl.SERVER_AUTH,"TRUE");
-        sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, this);
-        authenticate();
-    }
-
-
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack.sasl;
+
+import org.jivesoftware.smack.SASLAuthentication;
+import org.jivesoftware.smack.XMPPException;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.HashMap;
+import javax.security.sasl.Sasl;
+import javax.security.auth.callback.CallbackHandler;
+
+/**
+ * Implementation of the SASL GSSAPI mechanism
+ *
+ * @author Jay Kline
+ */
+public class SASLGSSAPIMechanism extends SASLMechanism {
+
+    public SASLGSSAPIMechanism(SASLAuthentication saslAuthentication) {
+        super(saslAuthentication);
+
+        System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
+        System.setProperty("java.security.auth.login.config","gss.conf");
+
+    }
+
+    protected String getName() {
+        return "GSSAPI";
+    }
+
+    /**
+     * Builds and sends the <tt>auth</tt> stanza to the server.
+     * This overrides from the abstract class because the initial token
+     * needed for GSSAPI is binary, and not safe to put in a string, thus
+     * getAuthenticationText() cannot be used.
+     *
+     * @param username the username of the user being authenticated.
+     * @param host     the hostname where the user account resides.
+     * @param cbh      the CallbackHandler (not used with GSSAPI)
+     * @throws IOException If a network error occures while authenticating.
+     */
+    public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, XMPPException {
+        String[] mechanisms = { getName() };
+        Map<String,String> props = new HashMap<String,String>();
+        props.put(Sasl.SERVER_AUTH,"TRUE");
+        sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, cbh);
+        authenticate();
+    }
+
+    /**
+     * Builds and sends the <tt>auth</tt> stanza to the server.
+     * This overrides from the abstract class because the initial token
+     * needed for GSSAPI is binary, and not safe to put in a string, thus
+     * getAuthenticationText() cannot be used.
+     *
+     * @param username the username of the user being authenticated.
+     * @param host     the hostname where the user account resides.
+     * @param password the password of the user (ignored for GSSAPI)
+     * @throws IOException If a network error occures while authenticating.
+     */
+    public void authenticate(String username, String host, String password) throws IOException, XMPPException {
+        String[] mechanisms = { getName() };
+        Map<String,String> props = new HashMap<String, String>();
+        props.put(Sasl.SERVER_AUTH,"TRUE");
+        sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, this);
+        authenticate();
+    }
+
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLMechanism.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLMechanism.java
index 0d096f2..45212e4 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLMechanism.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLMechanism.java
@@ -1,404 +1,404 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack.sasl;
-
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.SASLAuthentication;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smack.util.StringUtils;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.HashMap;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.sasl.RealmCallback;
-import javax.security.sasl.RealmChoiceCallback;
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslClient;
-import javax.security.sasl.SaslException;
-
-/**
- * Base class for SASL mechanisms. Subclasses must implement these methods:
- * <ul>
- *  <li>{@link #getName()} -- returns the common name of the SASL mechanism.</li>
- * </ul>
- * Subclasses will likely want to implement their own versions of these mthods:
- *  <li>{@link #authenticate(String, String, String)} -- Initiate authentication stanza using the
- *  deprecated method.</li>
- *  <li>{@link #authenticate(String, String, CallbackHandler)} -- Initiate authentication stanza
- *  using the CallbackHandler method.</li>
- *  <li>{@link #challengeReceived(String)} -- Handle a challenge from the server.</li>
- * </ul>
- * 
- * Basic XMPP SASL authentication steps:
- * 1. Client authentication initialization, stanza sent to the server (Base64 encoded): 
- *    <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'/>
- * 2. Server sends back to the client the challenge response (Base64 encoded)
- *    sample: 
- *    realm=<sasl server realm>,nonce="OA6MG9tEQGm2hh",qop="auth",charset=utf-8,algorithm=md5-sess
- * 3. The client responds back to the server (Base 64 encoded):
- *    sample:
- *    username=<userid>,realm=<sasl server realm from above>,nonce="OA6MG9tEQGm2hh",
- *    cnonce="OA6MHXh6VqTrRk",nc=00000001,qop=auth,
- *    digest-uri=<digesturi>,
- *    response=d388dad90d4bbd760a152321f2143af7,
- *    charset=utf-8,
- *    authzid=<id>
- * 4. The server evaluates if the user is present and contained in the REALM
- *    if successful it sends: <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/> (Base64 encoded)
- *    if not successful it sends:
- *    sample:
- *    <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
- *        cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZA==
- *    </challenge>       
- * 
-
- *
- * @author Jay Kline
- */
-public abstract class SASLMechanism implements CallbackHandler {
-
-    private SASLAuthentication saslAuthentication;
-    protected SaslClient sc;
-    protected String authenticationId;
-    protected String password;
-    protected String hostname;
-
-    public SASLMechanism(SASLAuthentication saslAuthentication) {
-        this.saslAuthentication = saslAuthentication;
-    }
-
-    /**
-     * Builds and sends the <tt>auth</tt> stanza to the server. Note that this method of
-     * authentication is not recommended, since it is very inflexable. Use
-     * {@link #authenticate(String, String, CallbackHandler)} whenever possible.
-     * 
-     * Explanation of auth stanza:
-     * 
-     * The client authentication stanza needs to include the digest-uri of the form: xmpp/serverName 
-     * From RFC-2831: 
-     * digest-uri = "digest-uri" "=" digest-uri-value
-     * digest-uri-value = serv-type "/" host [ "/" serv-name ]
-     * 
-     * digest-uri: 
-     * Indicates the principal name of the service with which the client 
-     * wishes to connect, formed from the serv-type, host, and serv-name. 
-     * For example, the FTP service
-     * on "ftp.example.com" would have a "digest-uri" value of "ftp/ftp.example.com"; the SMTP
-     * server from the example above would have a "digest-uri" value of
-     * "smtp/mail3.example.com/example.com".
-     * 
-     * host:
-     * The DNS host name or IP address for the service requested. The DNS host name
-     * must be the fully-qualified canonical name of the host. The DNS host name is the
-     * preferred form; see notes on server processing of the digest-uri.
-     * 
-     * serv-name: 
-     * Indicates the name of the service if it is replicated. The service is
-     * considered to be replicated if the client's service-location process involves resolution
-     * using standard DNS lookup operations, and if these operations involve DNS records (such
-     * as SRV, or MX) which resolve one DNS name into a set of other DNS names. In this case,
-     * the initial name used by the client is the "serv-name", and the final name is the "host"
-     * component. For example, the incoming mail service for "example.com" may be replicated
-     * through the use of MX records stored in the DNS, one of which points at an SMTP server
-     * called "mail3.example.com"; it's "serv-name" would be "example.com", it's "host" would be
-     * "mail3.example.com". If the service is not replicated, or the serv-name is identical to
-     * the host, then the serv-name component MUST be omitted
-     * 
-     * digest-uri verification is needed for ejabberd 2.0.3 and higher   
-     * 
-     * @param username the username of the user being authenticated.
-     * @param host the hostname where the user account resides.
-     * @param serviceName the xmpp service location - used by the SASL client in digest-uri creation
-     * serviceName format is: host [ "/" serv-name ] as per RFC-2831
-     * @param password the password for this account.
-     * @throws IOException If a network error occurs while authenticating.
-     * @throws XMPPException If a protocol error occurs or the user is not authenticated.
-     */
-    public void authenticate(String username, String host, String serviceName, String password) throws IOException, XMPPException {
-        //Since we were not provided with a CallbackHandler, we will use our own with the given
-        //information
-
-        //Set the authenticationID as the username, since they must be the same in this case.
-        this.authenticationId = username;
-        this.password = password;
-        this.hostname = host;        
-
-        String[] mechanisms = { getName() };
-        Map<String,String> props = new HashMap<String,String>();        
-        sc = Sasl.createSaslClient(mechanisms, username, "xmpp", serviceName, props, this);
-        authenticate();
-    }
-
-    /**
-     * Same as {@link #authenticate(String, String, String, String)}, but with the hostname used as the serviceName.
-     * <p>
-     * Kept for backward compatibility only.
-     * 
-     * @param username the username of the user being authenticated.
-     * @param host the hostname where the user account resides.
-     * @param password the password for this account.
-     * @throws IOException If a network error occurs while authenticating.
-     * @throws XMPPException If a protocol error occurs or the user is not authenticated.
-     * @deprecated Please use {@link #authenticate(String, String, String, String)} instead.
-     */
-    public void authenticate(String username, String host, String password) throws IOException, XMPPException {
-        authenticate(username, host, host, password);
-    }
-    
-    /**
-     * Builds and sends the <tt>auth</tt> stanza to the server. The callback handler will handle
-     * any additional information, such as the authentication ID or realm, if it is needed.
-     *
-     * @param username the username of the user being authenticated.
-     * @param host     the hostname where the user account resides.
-     * @param cbh      the CallbackHandler to obtain user information.
-     * @throws IOException If a network error occures while authenticating.
-     * @throws XMPPException If a protocol error occurs or the user is not authenticated.
-     */
-    public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, XMPPException {
-        String[] mechanisms = { getName() };
-        Map<String,String> props = new HashMap<String,String>();
-        sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, cbh);
-        authenticate();
-    }
-
-    protected void authenticate() throws IOException, XMPPException {
-        String authenticationText = null;
-        try {
-            if(sc.hasInitialResponse()) {
-                byte[] response = sc.evaluateChallenge(new byte[0]);
-                authenticationText = StringUtils.encodeBase64(response, false);
-            }
-        } catch (SaslException e) {
-            throw new XMPPException("SASL authentication failed", e);
-        }
-
-        // Send the authentication to the server
-        getSASLAuthentication().send(new AuthMechanism(getName(), authenticationText));
-    }
-
-
-    /**
-     * The server is challenging the SASL mechanism for the stanza he just sent. Send a
-     * response to the server's challenge.
-     *
-     * @param challenge a base64 encoded string representing the challenge.
-     * @throws IOException if an exception sending the response occurs.
-     */
-    public void challengeReceived(String challenge) throws IOException {
-        byte response[];
-        if(challenge != null) {
-            response = sc.evaluateChallenge(StringUtils.decodeBase64(challenge));
-        } else {
-            response = sc.evaluateChallenge(new byte[0]);
-        }
-
-        Packet responseStanza;
-        if (response == null) {
-            responseStanza = new Response();
-        }
-        else {
-            responseStanza = new Response(StringUtils.encodeBase64(response, false));
-        }
-
-        // Send the authentication to the server
-        getSASLAuthentication().send(responseStanza);
-    }
-
-    /**
-     * Returns the common name of the SASL mechanism. E.g.: PLAIN, DIGEST-MD5 or GSSAPI.
-     *
-     * @return the common name of the SASL mechanism.
-     */
-    protected abstract String getName();
-
-
-    protected SASLAuthentication getSASLAuthentication() {
-        return saslAuthentication;
-    }
-
-    /**
-     * 
-     */
-    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
-        for (int i = 0; i < callbacks.length; i++) {
-            if (callbacks[i] instanceof NameCallback) {
-                NameCallback ncb = (NameCallback)callbacks[i];
-                ncb.setName(authenticationId);
-            } else if(callbacks[i] instanceof PasswordCallback) {
-                PasswordCallback pcb = (PasswordCallback)callbacks[i];
-                pcb.setPassword(password.toCharArray());
-            } else if(callbacks[i] instanceof RealmCallback) {
-                RealmCallback rcb = (RealmCallback)callbacks[i];
-                //Retrieve the REALM from the challenge response that the server returned when the client initiated the authentication 
-                //exchange. If this value is not null or empty, *this value* has to be sent back to the server in the client's response 
-                //to the server's challenge
-                String text = rcb.getDefaultText();
-                //The SASL client (sc) created in smack  uses rcb.getText when creating the negotiatedRealm to send it back to the server
-                //Make sure that this value matches the server's realm
-                rcb.setText(text);
-            } else if(callbacks[i] instanceof RealmChoiceCallback){
-                //unused
-                //RealmChoiceCallback rccb = (RealmChoiceCallback)callbacks[i];
-            } else {
-               throw new UnsupportedCallbackException(callbacks[i]);
-            }
-         }
-    }
-
-    /**
-     * Initiating SASL authentication by select a mechanism.
-     */
-    public class AuthMechanism extends Packet {
-        final private String name;
-        final private String authenticationText;
-
-        public AuthMechanism(String name, String authenticationText) {
-            if (name == null) {
-                throw new NullPointerException("SASL mechanism name shouldn't be null.");
-            }
-            this.name = name;
-            this.authenticationText = authenticationText;
-        }
-
-        public String toXML() {
-            StringBuilder stanza = new StringBuilder();
-            stanza.append("<auth mechanism=\"").append(name);
-            stanza.append("\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
-            if (authenticationText != null &&
-                    authenticationText.trim().length() > 0) {
-                stanza.append(authenticationText);
-            }
-            stanza.append("</auth>");
-            return stanza.toString();
-        }
-    }
-
-    /**
-     * A SASL challenge stanza.
-     */
-    public static class Challenge extends Packet {
-        final private String data;
-
-        public Challenge(String data) {
-            this.data = data;
-        }
-
-        public String toXML() {
-            StringBuilder stanza = new StringBuilder();
-            stanza.append("<challenge xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
-            if (data != null &&
-                    data.trim().length() > 0) {
-                stanza.append(data);
-            }
-            stanza.append("</challenge>");
-            return stanza.toString();
-        }
-    }
-
-    /**
-     * A SASL response stanza.
-     */
-    public class Response extends Packet {
-        final private String authenticationText;
-
-        public Response() {
-            authenticationText = null;
-        }
-
-        public Response(String authenticationText) {
-            if (authenticationText == null || authenticationText.trim().length() == 0) {
-                this.authenticationText = null;
-            }
-            else {
-                this.authenticationText = authenticationText;
-            }
-        }
-
-        public String toXML() {
-            StringBuilder stanza = new StringBuilder();
-            stanza.append("<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
-            if (authenticationText != null) {
-                stanza.append(authenticationText);
-            }
-            stanza.append("</response>");
-            return stanza.toString();
-        }
-    }
-
-    /**
-     * A SASL success stanza.
-     */
-    public static class Success extends Packet {
-        final private String data;
-
-        public Success(String data) {
-            this.data = data;
-        }
-
-        public String toXML() {
-            StringBuilder stanza = new StringBuilder();
-            stanza.append("<success xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
-            if (data != null &&
-                    data.trim().length() > 0) {
-                stanza.append(data);
-            }
-            stanza.append("</success>");
-            return stanza.toString();
-        }
-    }
-
-    /**
-     * A SASL failure stanza.
-     */
-    public static class Failure extends Packet {
-        final private String condition;
-
-        public Failure(String condition) {
-            this.condition = condition;
-        }
-
-        /**
-         * Get the SASL related error condition.
-         * 
-         * @return the SASL related error condition.
-         */
-        public String getCondition() {
-            return condition;
-        }
-
-        public String toXML() {
-            StringBuilder stanza = new StringBuilder();
-            stanza.append("<failure xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
-            if (condition != null &&
-                    condition.trim().length() > 0) {
-                stanza.append("<").append(condition).append("/>");
-            }
-            stanza.append("</failure>");
-            return stanza.toString();
-        }
-    }        
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack.sasl;
+
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.SASLAuthentication;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.util.StringUtils;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.HashMap;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.sasl.RealmCallback;
+import javax.security.sasl.RealmChoiceCallback;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslException;
+
+/**
+ * Base class for SASL mechanisms. Subclasses must implement these methods:
+ * <ul>
+ *  <li>{@link #getName()} -- returns the common name of the SASL mechanism.</li>
+ * </ul>
+ * Subclasses will likely want to implement their own versions of these mthods:
+ *  <li>{@link #authenticate(String, String, String)} -- Initiate authentication stanza using the
+ *  deprecated method.</li>
+ *  <li>{@link #authenticate(String, String, CallbackHandler)} -- Initiate authentication stanza
+ *  using the CallbackHandler method.</li>
+ *  <li>{@link #challengeReceived(String)} -- Handle a challenge from the server.</li>
+ * </ul>
+ * 
+ * Basic XMPP SASL authentication steps:
+ * 1. Client authentication initialization, stanza sent to the server (Base64 encoded): 
+ *    <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'/>
+ * 2. Server sends back to the client the challenge response (Base64 encoded)
+ *    sample: 
+ *    realm=<sasl server realm>,nonce="OA6MG9tEQGm2hh",qop="auth",charset=utf-8,algorithm=md5-sess
+ * 3. The client responds back to the server (Base 64 encoded):
+ *    sample:
+ *    username=<userid>,realm=<sasl server realm from above>,nonce="OA6MG9tEQGm2hh",
+ *    cnonce="OA6MHXh6VqTrRk",nc=00000001,qop=auth,
+ *    digest-uri=<digesturi>,
+ *    response=d388dad90d4bbd760a152321f2143af7,
+ *    charset=utf-8,
+ *    authzid=<id>
+ * 4. The server evaluates if the user is present and contained in the REALM
+ *    if successful it sends: <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/> (Base64 encoded)
+ *    if not successful it sends:
+ *    sample:
+ *    <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
+ *        cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZA==
+ *    </challenge>       
+ * 
+
+ *
+ * @author Jay Kline
+ */
+public abstract class SASLMechanism implements CallbackHandler {
+
+    private SASLAuthentication saslAuthentication;
+    protected SaslClient sc;
+    protected String authenticationId;
+    protected String password;
+    protected String hostname;
+
+    public SASLMechanism(SASLAuthentication saslAuthentication) {
+        this.saslAuthentication = saslAuthentication;
+    }
+
+    /**
+     * Builds and sends the <tt>auth</tt> stanza to the server. Note that this method of
+     * authentication is not recommended, since it is very inflexable. Use
+     * {@link #authenticate(String, String, CallbackHandler)} whenever possible.
+     * 
+     * Explanation of auth stanza:
+     * 
+     * The client authentication stanza needs to include the digest-uri of the form: xmpp/serverName 
+     * From RFC-2831: 
+     * digest-uri = "digest-uri" "=" digest-uri-value
+     * digest-uri-value = serv-type "/" host [ "/" serv-name ]
+     * 
+     * digest-uri: 
+     * Indicates the principal name of the service with which the client 
+     * wishes to connect, formed from the serv-type, host, and serv-name. 
+     * For example, the FTP service
+     * on "ftp.example.com" would have a "digest-uri" value of "ftp/ftp.example.com"; the SMTP
+     * server from the example above would have a "digest-uri" value of
+     * "smtp/mail3.example.com/example.com".
+     * 
+     * host:
+     * The DNS host name or IP address for the service requested. The DNS host name
+     * must be the fully-qualified canonical name of the host. The DNS host name is the
+     * preferred form; see notes on server processing of the digest-uri.
+     * 
+     * serv-name: 
+     * Indicates the name of the service if it is replicated. The service is
+     * considered to be replicated if the client's service-location process involves resolution
+     * using standard DNS lookup operations, and if these operations involve DNS records (such
+     * as SRV, or MX) which resolve one DNS name into a set of other DNS names. In this case,
+     * the initial name used by the client is the "serv-name", and the final name is the "host"
+     * component. For example, the incoming mail service for "example.com" may be replicated
+     * through the use of MX records stored in the DNS, one of which points at an SMTP server
+     * called "mail3.example.com"; it's "serv-name" would be "example.com", it's "host" would be
+     * "mail3.example.com". If the service is not replicated, or the serv-name is identical to
+     * the host, then the serv-name component MUST be omitted
+     * 
+     * digest-uri verification is needed for ejabberd 2.0.3 and higher   
+     * 
+     * @param username the username of the user being authenticated.
+     * @param host the hostname where the user account resides.
+     * @param serviceName the xmpp service location - used by the SASL client in digest-uri creation
+     * serviceName format is: host [ "/" serv-name ] as per RFC-2831
+     * @param password the password for this account.
+     * @throws IOException If a network error occurs while authenticating.
+     * @throws XMPPException If a protocol error occurs or the user is not authenticated.
+     */
+    public void authenticate(String username, String host, String serviceName, String password) throws IOException, XMPPException {
+        //Since we were not provided with a CallbackHandler, we will use our own with the given
+        //information
+
+        //Set the authenticationID as the username, since they must be the same in this case.
+        this.authenticationId = username;
+        this.password = password;
+        this.hostname = host;        
+
+        String[] mechanisms = { getName() };
+        Map<String,String> props = new HashMap<String,String>();        
+        sc = Sasl.createSaslClient(mechanisms, username, "xmpp", serviceName, props, this);
+        authenticate();
+    }
+
+    /**
+     * Same as {@link #authenticate(String, String, String, String)}, but with the hostname used as the serviceName.
+     * <p>
+     * Kept for backward compatibility only.
+     * 
+     * @param username the username of the user being authenticated.
+     * @param host the hostname where the user account resides.
+     * @param password the password for this account.
+     * @throws IOException If a network error occurs while authenticating.
+     * @throws XMPPException If a protocol error occurs or the user is not authenticated.
+     * @deprecated Please use {@link #authenticate(String, String, String, String)} instead.
+     */
+    public void authenticate(String username, String host, String password) throws IOException, XMPPException {
+        authenticate(username, host, host, password);
+    }
+    
+    /**
+     * Builds and sends the <tt>auth</tt> stanza to the server. The callback handler will handle
+     * any additional information, such as the authentication ID or realm, if it is needed.
+     *
+     * @param username the username of the user being authenticated.
+     * @param host     the hostname where the user account resides.
+     * @param cbh      the CallbackHandler to obtain user information.
+     * @throws IOException If a network error occures while authenticating.
+     * @throws XMPPException If a protocol error occurs or the user is not authenticated.
+     */
+    public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, XMPPException {
+        String[] mechanisms = { getName() };
+        Map<String,String> props = new HashMap<String,String>();
+        sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, cbh);
+        authenticate();
+    }
+
+    protected void authenticate() throws IOException, XMPPException {
+        String authenticationText = null;
+        try {
+            if(sc.hasInitialResponse()) {
+                byte[] response = sc.evaluateChallenge(new byte[0]);
+                authenticationText = StringUtils.encodeBase64(response, false);
+            }
+        } catch (SaslException e) {
+            throw new XMPPException("SASL authentication failed", e);
+        }
+
+        // Send the authentication to the server
+        getSASLAuthentication().send(new AuthMechanism(getName(), authenticationText));
+    }
+
+
+    /**
+     * The server is challenging the SASL mechanism for the stanza he just sent. Send a
+     * response to the server's challenge.
+     *
+     * @param challenge a base64 encoded string representing the challenge.
+     * @throws IOException if an exception sending the response occurs.
+     */
+    public void challengeReceived(String challenge) throws IOException {
+        byte response[];
+        if(challenge != null) {
+            response = sc.evaluateChallenge(StringUtils.decodeBase64(challenge));
+        } else {
+            response = sc.evaluateChallenge(new byte[0]);
+        }
+
+        Packet responseStanza;
+        if (response == null) {
+            responseStanza = new Response();
+        }
+        else {
+            responseStanza = new Response(StringUtils.encodeBase64(response, false));
+        }
+
+        // Send the authentication to the server
+        getSASLAuthentication().send(responseStanza);
+    }
+
+    /**
+     * Returns the common name of the SASL mechanism. E.g.: PLAIN, DIGEST-MD5 or GSSAPI.
+     *
+     * @return the common name of the SASL mechanism.
+     */
+    protected abstract String getName();
+
+
+    protected SASLAuthentication getSASLAuthentication() {
+        return saslAuthentication;
+    }
+
+    /**
+     * 
+     */
+    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+        for (int i = 0; i < callbacks.length; i++) {
+            if (callbacks[i] instanceof NameCallback) {
+                NameCallback ncb = (NameCallback)callbacks[i];
+                ncb.setName(authenticationId);
+            } else if(callbacks[i] instanceof PasswordCallback) {
+                PasswordCallback pcb = (PasswordCallback)callbacks[i];
+                pcb.setPassword(password.toCharArray());
+            } else if(callbacks[i] instanceof RealmCallback) {
+                RealmCallback rcb = (RealmCallback)callbacks[i];
+                //Retrieve the REALM from the challenge response that the server returned when the client initiated the authentication 
+                //exchange. If this value is not null or empty, *this value* has to be sent back to the server in the client's response 
+                //to the server's challenge
+                String text = rcb.getDefaultText();
+                //The SASL client (sc) created in smack  uses rcb.getText when creating the negotiatedRealm to send it back to the server
+                //Make sure that this value matches the server's realm
+                rcb.setText(text);
+            } else if(callbacks[i] instanceof RealmChoiceCallback){
+                //unused
+                //RealmChoiceCallback rccb = (RealmChoiceCallback)callbacks[i];
+            } else {
+               throw new UnsupportedCallbackException(callbacks[i]);
+            }
+         }
+    }
+
+    /**
+     * Initiating SASL authentication by select a mechanism.
+     */
+    public class AuthMechanism extends Packet {
+        final private String name;
+        final private String authenticationText;
+
+        public AuthMechanism(String name, String authenticationText) {
+            if (name == null) {
+                throw new NullPointerException("SASL mechanism name shouldn't be null.");
+            }
+            this.name = name;
+            this.authenticationText = authenticationText;
+        }
+
+        public String toXML() {
+            StringBuilder stanza = new StringBuilder();
+            stanza.append("<auth mechanism=\"").append(name);
+            stanza.append("\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
+            if (authenticationText != null &&
+                    authenticationText.trim().length() > 0) {
+                stanza.append(authenticationText);
+            }
+            stanza.append("</auth>");
+            return stanza.toString();
+        }
+    }
+
+    /**
+     * A SASL challenge stanza.
+     */
+    public static class Challenge extends Packet {
+        final private String data;
+
+        public Challenge(String data) {
+            this.data = data;
+        }
+
+        public String toXML() {
+            StringBuilder stanza = new StringBuilder();
+            stanza.append("<challenge xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
+            if (data != null &&
+                    data.trim().length() > 0) {
+                stanza.append(data);
+            }
+            stanza.append("</challenge>");
+            return stanza.toString();
+        }
+    }
+
+    /**
+     * A SASL response stanza.
+     */
+    public class Response extends Packet {
+        final private String authenticationText;
+
+        public Response() {
+            authenticationText = null;
+        }
+
+        public Response(String authenticationText) {
+            if (authenticationText == null || authenticationText.trim().length() == 0) {
+                this.authenticationText = null;
+            }
+            else {
+                this.authenticationText = authenticationText;
+            }
+        }
+
+        public String toXML() {
+            StringBuilder stanza = new StringBuilder();
+            stanza.append("<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
+            if (authenticationText != null) {
+                stanza.append(authenticationText);
+            }
+            stanza.append("</response>");
+            return stanza.toString();
+        }
+    }
+
+    /**
+     * A SASL success stanza.
+     */
+    public static class Success extends Packet {
+        final private String data;
+
+        public Success(String data) {
+            this.data = data;
+        }
+
+        public String toXML() {
+            StringBuilder stanza = new StringBuilder();
+            stanza.append("<success xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
+            if (data != null &&
+                    data.trim().length() > 0) {
+                stanza.append(data);
+            }
+            stanza.append("</success>");
+            return stanza.toString();
+        }
+    }
+
+    /**
+     * A SASL failure stanza.
+     */
+    public static class Failure extends Packet {
+        final private String condition;
+
+        public Failure(String condition) {
+            this.condition = condition;
+        }
+
+        /**
+         * Get the SASL related error condition.
+         * 
+         * @return the SASL related error condition.
+         */
+        public String getCondition() {
+            return condition;
+        }
+
+        public String toXML() {
+            StringBuilder stanza = new StringBuilder();
+            stanza.append("<failure xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
+            if (condition != null &&
+                    condition.trim().length() > 0) {
+                stanza.append("<").append(condition).append("/>");
+            }
+            stanza.append("</failure>");
+            return stanza.toString();
+        }
+    }        
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLPlainMechanism.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLPlainMechanism.java
index cd973eb..c341d67 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLPlainMechanism.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/sasl/SASLPlainMechanism.java
@@ -1,34 +1,34 @@
-/**
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack.sasl;
-
-import org.jivesoftware.smack.SASLAuthentication;
-
-/**
- * Implementation of the SASL PLAIN mechanism
- *
- * @author Jay Kline
- */
-public class SASLPlainMechanism extends SASLMechanism {
-
-    public SASLPlainMechanism(SASLAuthentication saslAuthentication) {
-        super(saslAuthentication);
-    }
-
-    protected String getName() {
-        return "PLAIN";
-    }
-}
+/**
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smack.sasl;
+
+import org.jivesoftware.smack.SASLAuthentication;
+
+/**
+ * Implementation of the SASL PLAIN mechanism
+ *
+ * @author Jay Kline
+ */
+public class SASLPlainMechanism extends SASLMechanism {
+
+    public SASLPlainMechanism(SASLAuthentication saslAuthentication) {
+        super(saslAuthentication);
+    }
+
+    protected String getName() {
+        return "PLAIN";
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/Base64.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/Base64.java
index ba6eb37..0923f03 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/Base64.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/Base64.java
@@ -4,1686 +4,1686 @@
  * $Date$
  *
  */
-package org.jivesoftware.smack.util;
-
-/**
+package org.jivesoftware.smack.util;
+
+/**
  * <p>Encodes and decodes to and from Base64 notation.</p>
- * This code was obtained from <a href="http://iharder.net/base64">http://iharder.net/base64</a></p>
- *
- *
- * @author Robert Harder
- * @author rob@iharder.net
- * @version 2.2.1
- */
-public class Base64
-{
-
-/* ********  P U B L I C   F I E L D S  ******** */
-
-
-    /** No options specified. Value is zero. */
-    public final static int NO_OPTIONS = 0;
-
-    /** Specify encoding. */
-    public final static int ENCODE = 1;
-
-
-    /** Specify decoding. */
-    public final static int DECODE = 0;
-
-
-    /** Specify that data should be gzip-compressed. */
-    public final static int GZIP = 2;
-
-
-    /** Don't break lines when encoding (violates strict Base64 specification) */
-    public final static int DONT_BREAK_LINES = 8;
-
-	/**
-	 * Encode using Base64-like encoding that is URL- and Filename-safe as described
-	 * in Section 4 of RFC3548:
-	 * <a href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>.
-	 * It is important to note that data encoded this way is <em>not</em> officially valid Base64,
-	 * or at the very least should not be called Base64 without also specifying that is
-	 * was encoded using the URL- and Filename-safe dialect.
-	 */
-	 public final static int URL_SAFE = 16;
-
-
-	 /**
-	  * Encode using the special "ordered" dialect of Base64 described here:
-	  * <a href="http://www.faqs.org/qa/rfcc-1940.html">http://www.faqs.org/qa/rfcc-1940.html</a>.
-	  */
-	 public final static int ORDERED = 32;
-
-
-/* ********  P R I V A T E   F I E L D S  ******** */
-
-
-    /** Maximum line length (76) of Base64 output. */
-    private final static int MAX_LINE_LENGTH = 76;
-
-
-    /** The equals sign (=) as a byte. */
-    private final static byte EQUALS_SIGN = (byte)'=';
-
-
-    /** The new line character (\n) as a byte. */
-    private final static byte NEW_LINE = (byte)'\n';
-
-
-    /** Preferred encoding. */
-    private final static String PREFERRED_ENCODING = "UTF-8";
-
-
-    // I think I end up not using the BAD_ENCODING indicator.
-    //private final static byte BAD_ENCODING    = -9; // Indicates error in encoding
-    private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding
-    private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding
-
-
-/* ********  S T A N D A R D   B A S E 6 4   A L P H A B E T  ******** */
-
-    /** The 64 valid Base64 values. */
-    //private final static byte[] ALPHABET;
-	/* Host platform me be something funny like EBCDIC, so we hardcode these values. */
-	private final static byte[] _STANDARD_ALPHABET =
-    {
-        (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
-        (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
-        (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
-        (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
-        (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
-        (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
-        (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
-        (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z',
-        (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',
-        (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/'
-    };
-
-
-    /**
-     * Translates a Base64 value to either its 6-bit reconstruction value
-     * or a negative number indicating some other meaning.
-     **/
-    private final static byte[] _STANDARD_DECODABET =
-    {
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,                 // Decimal  0 -  8
-        -5,-5,                                      // Whitespace: Tab and Linefeed
-        -9,-9,                                      // Decimal 11 - 12
-        -5,                                         // Whitespace: Carriage Return
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 14 - 26
-        -9,-9,-9,-9,-9,                             // Decimal 27 - 31
-        -5,                                         // Whitespace: Space
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,              // Decimal 33 - 42
-        62,                                         // Plus sign at decimal 43
-        -9,-9,-9,                                   // Decimal 44 - 46
-        63,                                         // Slash at decimal 47
-        52,53,54,55,56,57,58,59,60,61,              // Numbers zero through nine
-        -9,-9,-9,                                   // Decimal 58 - 60
-        -1,                                         // Equals sign at decimal 61
-        -9,-9,-9,                                      // Decimal 62 - 64
-        0,1,2,3,4,5,6,7,8,9,10,11,12,13,            // Letters 'A' through 'N'
-        14,15,16,17,18,19,20,21,22,23,24,25,        // Letters 'O' through 'Z'
-        -9,-9,-9,-9,-9,-9,                          // Decimal 91 - 96
-        26,27,28,29,30,31,32,33,34,35,36,37,38,     // Letters 'a' through 'm'
-        39,40,41,42,43,44,45,46,47,48,49,50,51,     // Letters 'n' through 'z'
-        -9,-9,-9,-9                                 // Decimal 123 - 126
-        /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 127 - 139
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 140 - 152
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 153 - 165
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 166 - 178
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 179 - 191
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 192 - 204
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 205 - 217
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 218 - 230
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 231 - 243
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9         // Decimal 244 - 255 */
-    };
-
-
-/* ********  U R L   S A F E   B A S E 6 4   A L P H A B E T  ******** */
-
-	/**
-	 * Used in the URL- and Filename-safe dialect described in Section 4 of RFC3548:
-	 * <a href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>.
-	 * Notice that the last two bytes become "hyphen" and "underscore" instead of "plus" and "slash."
-	 */
-    private final static byte[] _URL_SAFE_ALPHABET =
-    {
-      (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
-      (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
-      (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
-      (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
-      (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
-      (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
-      (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
-      (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z',
-      (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',
-      (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'-', (byte)'_'
-    };
-
-	/**
-	 * Used in decoding URL- and Filename-safe dialects of Base64.
-	 */
-    private final static byte[] _URL_SAFE_DECODABET =
-    {
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,                 // Decimal  0 -  8
-      -5,-5,                                      // Whitespace: Tab and Linefeed
-      -9,-9,                                      // Decimal 11 - 12
-      -5,                                         // Whitespace: Carriage Return
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 14 - 26
-      -9,-9,-9,-9,-9,                             // Decimal 27 - 31
-      -5,                                         // Whitespace: Space
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,              // Decimal 33 - 42
-      -9,                                         // Plus sign at decimal 43
-      -9,                                         // Decimal 44
-      62,                                         // Minus sign at decimal 45
-      -9,                                         // Decimal 46
-      -9,                                         // Slash at decimal 47
-      52,53,54,55,56,57,58,59,60,61,              // Numbers zero through nine
-      -9,-9,-9,                                   // Decimal 58 - 60
-      -1,                                         // Equals sign at decimal 61
-      -9,-9,-9,                                   // Decimal 62 - 64
-      0,1,2,3,4,5,6,7,8,9,10,11,12,13,            // Letters 'A' through 'N'
-      14,15,16,17,18,19,20,21,22,23,24,25,        // Letters 'O' through 'Z'
-      -9,-9,-9,-9,                                // Decimal 91 - 94
-      63,                                         // Underscore at decimal 95
-      -9,                                         // Decimal 96
-      26,27,28,29,30,31,32,33,34,35,36,37,38,     // Letters 'a' through 'm'
-      39,40,41,42,43,44,45,46,47,48,49,50,51,     // Letters 'n' through 'z'
-      -9,-9,-9,-9                                 // Decimal 123 - 126
-      /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 127 - 139
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 140 - 152
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 153 - 165
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 166 - 178
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 179 - 191
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 192 - 204
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 205 - 217
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 218 - 230
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 231 - 243
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9         // Decimal 244 - 255 */
-    };
-
-
-
-/* ********  O R D E R E D   B A S E 6 4   A L P H A B E T  ******** */
-
-	/**
-	 * I don't get the point of this technique, but it is described here:
-	 * <a href="http://www.faqs.org/qa/rfcc-1940.html">http://www.faqs.org/qa/rfcc-1940.html</a>.
-	 */
-    private final static byte[] _ORDERED_ALPHABET =
-    {
-      (byte)'-',
-      (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4',
-      (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9',
-      (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
-      (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
-      (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
-      (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
-      (byte)'_',
-      (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
-      (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
-      (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
-      (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z'
-    };
-
-	/**
-	 * Used in decoding the "ordered" dialect of Base64.
-	 */
-    private final static byte[] _ORDERED_DECODABET =
-    {
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,                 // Decimal  0 -  8
-      -5,-5,                                      // Whitespace: Tab and Linefeed
-      -9,-9,                                      // Decimal 11 - 12
-      -5,                                         // Whitespace: Carriage Return
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 14 - 26
-      -9,-9,-9,-9,-9,                             // Decimal 27 - 31
-      -5,                                         // Whitespace: Space
-      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,              // Decimal 33 - 42
-      -9,                                         // Plus sign at decimal 43
-      -9,                                         // Decimal 44
-      0,                                          // Minus sign at decimal 45
-      -9,                                         // Decimal 46
-      -9,                                         // Slash at decimal 47
-      1,2,3,4,5,6,7,8,9,10,                       // Numbers zero through nine
-      -9,-9,-9,                                   // Decimal 58 - 60
-      -1,                                         // Equals sign at decimal 61
-      -9,-9,-9,                                   // Decimal 62 - 64
-      11,12,13,14,15,16,17,18,19,20,21,22,23,     // Letters 'A' through 'M'
-      24,25,26,27,28,29,30,31,32,33,34,35,36,     // Letters 'N' through 'Z'
-      -9,-9,-9,-9,                                // Decimal 91 - 94
-      37,                                         // Underscore at decimal 95
-      -9,                                         // Decimal 96
-      38,39,40,41,42,43,44,45,46,47,48,49,50,     // Letters 'a' through 'm'
-      51,52,53,54,55,56,57,58,59,60,61,62,63,     // Letters 'n' through 'z'
-      -9,-9,-9,-9                                 // Decimal 123 - 126
-      /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 127 - 139
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 140 - 152
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 153 - 165
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 166 - 178
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 179 - 191
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 192 - 204
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 205 - 217
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 218 - 230
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 231 - 243
-        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9         // Decimal 244 - 255 */
-    };
-
-
-/* ********  D E T E R M I N E   W H I C H   A L H A B E T  ******** */
-
-
-	/**
-	 * Returns one of the _SOMETHING_ALPHABET byte arrays depending on
-	 * the options specified.
-	 * It's possible, though silly, to specify ORDERED and URLSAFE
-	 * in which case one of them will be picked, though there is
-	 * no guarantee as to which one will be picked.
-	 */
-	private final static byte[] getAlphabet( int options )
-	{
-		if( (options & URL_SAFE) == URL_SAFE ) return _URL_SAFE_ALPHABET;
-		else if( (options & ORDERED) == ORDERED ) return _ORDERED_ALPHABET;
-		else return _STANDARD_ALPHABET;
-
-	}	// end getAlphabet
-
-
-	/**
-	 * Returns one of the _SOMETHING_DECODABET byte arrays depending on
-	 * the options specified.
-	 * It's possible, though silly, to specify ORDERED and URL_SAFE
-	 * in which case one of them will be picked, though there is
-	 * no guarantee as to which one will be picked.
-	 */
-	private final static byte[] getDecodabet( int options )
-	{
-		if( (options & URL_SAFE) == URL_SAFE ) return _URL_SAFE_DECODABET;
-		else if( (options & ORDERED) == ORDERED ) return _ORDERED_DECODABET;
-		else return _STANDARD_DECODABET;
-
-	}	// end getAlphabet
-
-
-
-    /** Defeats instantiation. */
-    private Base64(){}
-
-    /**
-     * Prints command line usage.
-     *
-     * @param msg A message to include with usage info.
-     */
-    private final static void usage( String msg )
-    {
-        System.err.println( msg );
-        System.err.println( "Usage: java Base64 -e|-d inputfile outputfile" );
-    }   // end usage
-
-
-/* ********  E N C O D I N G   M E T H O D S  ******** */
-
-
-    /**
-     * Encodes up to the first three bytes of array <var>threeBytes</var>
-     * and returns a four-byte array in Base64 notation.
-     * The actual number of significant bytes in your array is
-     * given by <var>numSigBytes</var>.
-     * The array <var>threeBytes</var> needs only be as big as
-     * <var>numSigBytes</var>.
-     * Code can reuse a byte array by passing a four-byte array as <var>b4</var>.
-     *
-     * @param b4 A reusable byte array to reduce array instantiation
-     * @param threeBytes the array to convert
-     * @param numSigBytes the number of significant bytes in your array
-     * @return four byte array in Base64 notation.
-     * @since 1.5.1
-     */
-    private static byte[] encode3to4( byte[] b4, byte[] threeBytes, int numSigBytes, int options )
-    {
-        encode3to4( threeBytes, 0, numSigBytes, b4, 0, options );
-        return b4;
-    }   // end encode3to4
-
-
-    /**
-     * <p>Encodes up to three bytes of the array <var>source</var>
-     * and writes the resulting four Base64 bytes to <var>destination</var>.
-     * The source and destination arrays can be manipulated
-     * anywhere along their length by specifying
-     * <var>srcOffset</var> and <var>destOffset</var>.
-     * This method does not check to make sure your arrays
-     * are large enough to accomodate <var>srcOffset</var> + 3 for
-     * the <var>source</var> array or <var>destOffset</var> + 4 for
-     * the <var>destination</var> array.
-     * The actual number of significant bytes in your array is
-     * given by <var>numSigBytes</var>.</p>
-	 * <p>This is the lowest level of the encoding methods with
-	 * all possible parameters.</p>
-     *
-     * @param source the array to convert
-     * @param srcOffset the index where conversion begins
-     * @param numSigBytes the number of significant bytes in your array
-     * @param destination the array to hold the conversion
-     * @param destOffset the index where output will be put
-     * @return the <var>destination</var> array
-     * @since 1.3
-     */
-    private static byte[] encode3to4(
-     byte[] source, int srcOffset, int numSigBytes,
-     byte[] destination, int destOffset, int options )
-    {
-		byte[] ALPHABET = getAlphabet( options );
-
-        //           1         2         3
-        // 01234567890123456789012345678901 Bit position
-        // --------000000001111111122222222 Array position from threeBytes
-        // --------|    ||    ||    ||    | Six bit groups to index ALPHABET
-        //          >>18  >>12  >> 6  >> 0  Right shift necessary
-        //                0x3f  0x3f  0x3f  Additional AND
-
-        // Create buffer with zero-padding if there are only one or two
-        // significant bytes passed in the array.
-        // We have to shift left 24 in order to flush out the 1's that appear
-        // when Java treats a value as negative that is cast from a byte to an int.
-        int inBuff =   ( numSigBytes > 0 ? ((source[ srcOffset     ] << 24) >>>  8) : 0 )
-                     | ( numSigBytes > 1 ? ((source[ srcOffset + 1 ] << 24) >>> 16) : 0 )
-                     | ( numSigBytes > 2 ? ((source[ srcOffset + 2 ] << 24) >>> 24) : 0 );
-
-        switch( numSigBytes )
-        {
-            case 3:
-                destination[ destOffset     ] = ALPHABET[ (inBuff >>> 18)        ];
-                destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
-                destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>>  6) & 0x3f ];
-                destination[ destOffset + 3 ] = ALPHABET[ (inBuff       ) & 0x3f ];
-                return destination;
-
-            case 2:
-                destination[ destOffset     ] = ALPHABET[ (inBuff >>> 18)        ];
-                destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
-                destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>>  6) & 0x3f ];
-                destination[ destOffset + 3 ] = EQUALS_SIGN;
-                return destination;
-
-            case 1:
-                destination[ destOffset     ] = ALPHABET[ (inBuff >>> 18)        ];
-                destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
-                destination[ destOffset + 2 ] = EQUALS_SIGN;
-                destination[ destOffset + 3 ] = EQUALS_SIGN;
-                return destination;
-
-            default:
-                return destination;
-        }   // end switch
-    }   // end encode3to4
-
-
-
-    /**
-     * Serializes an object and returns the Base64-encoded
-     * version of that serialized object. If the object
-     * cannot be serialized or there is another error,
-     * the method will return <tt>null</tt>.
-     * The object is not GZip-compressed before being encoded.
-     *
-     * @param serializableObject The object to encode
-     * @return The Base64-encoded object
-     * @since 1.4
-     */
-    public static String encodeObject( java.io.Serializable serializableObject )
-    {
-        return encodeObject( serializableObject, NO_OPTIONS );
-    }   // end encodeObject
-
-
-
-    /**
-     * Serializes an object and returns the Base64-encoded
-     * version of that serialized object. If the object
-     * cannot be serialized or there is another error,
-     * the method will return <tt>null</tt>.
-     * <p>
-     * Valid options:<pre>
-     *   GZIP: gzip-compresses object before encoding it.
-     *   DONT_BREAK_LINES: don't break lines at 76 characters
-     *     <i>Note: Technically, this makes your encoding non-compliant.</i>
-     * </pre>
-     * <p>
-     * Example: <code>encodeObject( myObj, Base64.GZIP )</code> or
-     * <p>
-     * Example: <code>encodeObject( myObj, Base64.GZIP | Base64.DONT_BREAK_LINES )</code>
-     *
-     * @param serializableObject The object to encode
-     * @param options Specified options
-     * @return The Base64-encoded object
-     * @see Base64#GZIP
-     * @see Base64#DONT_BREAK_LINES
-     * @since 2.0
-     */
-    public static String encodeObject( java.io.Serializable serializableObject, int options )
-    {
-        // Streams
-        java.io.ByteArrayOutputStream  baos  = null;
-        java.io.OutputStream           b64os = null;
-        java.io.ObjectOutputStream     oos   = null;
-        java.util.zip.GZIPOutputStream gzos  = null;
-
-        // Isolate options
-        int gzip           = (options & GZIP);
-        int dontBreakLines = (options & DONT_BREAK_LINES);
-
-        try
-        {
-            // ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream
-            baos  = new java.io.ByteArrayOutputStream();
-            b64os = new Base64.OutputStream( baos, ENCODE | options );
-
-            // GZip?
-            if( gzip == GZIP )
-            {
-                gzos = new java.util.zip.GZIPOutputStream( b64os );
-                oos  = new java.io.ObjectOutputStream( gzos );
-            }   // end if: gzip
-            else
-                oos   = new java.io.ObjectOutputStream( b64os );
-
-            oos.writeObject( serializableObject );
-        }   // end try
-        catch( java.io.IOException e )
-        {
-            e.printStackTrace();
-            return null;
-        }   // end catch
-        finally
-        {
-            try{ oos.close();   } catch( Exception e ){}
-            try{ gzos.close();  } catch( Exception e ){}
-            try{ b64os.close(); } catch( Exception e ){}
-            try{ baos.close();  } catch( Exception e ){}
-        }   // end finally
-
-        // Return value according to relevant encoding.
-        try
-        {
-            return new String( baos.toByteArray(), PREFERRED_ENCODING );
-        }   // end try
-        catch (java.io.UnsupportedEncodingException uue)
-        {
-            return new String( baos.toByteArray() );
-        }   // end catch
-
-    }   // end encode
-
-
-
-    /**
-     * Encodes a byte array into Base64 notation.
-     * Does not GZip-compress data.
-     *
-     * @param source The data to convert
-     * @since 1.4
-     */
-    public static String encodeBytes( byte[] source )
-    {
-        return encodeBytes( source, 0, source.length, NO_OPTIONS );
-    }   // end encodeBytes
-
-
-
-    /**
-     * Encodes a byte array into Base64 notation.
-     * <p>
-     * Valid options:<pre>
-     *   GZIP: gzip-compresses object before encoding it.
-     *   DONT_BREAK_LINES: don't break lines at 76 characters
-     *     <i>Note: Technically, this makes your encoding non-compliant.</i>
-     * </pre>
-     * <p>
-     * Example: <code>encodeBytes( myData, Base64.GZIP )</code> or
-     * <p>
-     * Example: <code>encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES )</code>
-     *
-     *
-     * @param source The data to convert
-     * @param options Specified options
-     * @see Base64#GZIP
-     * @see Base64#DONT_BREAK_LINES
-     * @since 2.0
-     */
-    public static String encodeBytes( byte[] source, int options )
-    {
-        return encodeBytes( source, 0, source.length, options );
-    }   // end encodeBytes
-
-
-    /**
-     * Encodes a byte array into Base64 notation.
-     * Does not GZip-compress data.
-     *
-     * @param source The data to convert
-     * @param off Offset in array where conversion should begin
-     * @param len Length of data to convert
-     * @since 1.4
-     */
-    public static String encodeBytes( byte[] source, int off, int len )
-    {
-        return encodeBytes( source, off, len, NO_OPTIONS );
-    }   // end encodeBytes
-
-
-
-    /**
-     * Encodes a byte array into Base64 notation.
-     * <p>
-     * Valid options:<pre>
-     *   GZIP: gzip-compresses object before encoding it.
-     *   DONT_BREAK_LINES: don't break lines at 76 characters
-     *     <i>Note: Technically, this makes your encoding non-compliant.</i>
-     * </pre>
-     * <p>
-     * Example: <code>encodeBytes( myData, Base64.GZIP )</code> or
-     * <p>
-     * Example: <code>encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES )</code>
-     *
-     *
-     * @param source The data to convert
-     * @param off Offset in array where conversion should begin
-     * @param len Length of data to convert
-     * @param options Specified options; alphabet type is pulled from this (standard, url-safe, ordered)
-     * @see Base64#GZIP
-     * @see Base64#DONT_BREAK_LINES
-     * @since 2.0
-     */
-    public static String encodeBytes( byte[] source, int off, int len, int options )
-    {
-        // Isolate options
-        int dontBreakLines = ( options & DONT_BREAK_LINES );
-        int gzip           = ( options & GZIP   );
-
-        // Compress?
-        if( gzip == GZIP )
-        {
-            java.io.ByteArrayOutputStream  baos  = null;
-            java.util.zip.GZIPOutputStream gzos  = null;
-            Base64.OutputStream            b64os = null;
-
-
-            try
-            {
-                // GZip -> Base64 -> ByteArray
-                baos = new java.io.ByteArrayOutputStream();
-                b64os = new Base64.OutputStream( baos, ENCODE | options );
-                gzos  = new java.util.zip.GZIPOutputStream( b64os );
-
-                gzos.write( source, off, len );
-                gzos.close();
-            }   // end try
-            catch( java.io.IOException e )
-            {
-                e.printStackTrace();
-                return null;
-            }   // end catch
-            finally
-            {
-                try{ gzos.close();  } catch( Exception e ){}
-                try{ b64os.close(); } catch( Exception e ){}
-                try{ baos.close();  } catch( Exception e ){}
-            }   // end finally
-
-            // Return value according to relevant encoding.
-            try
-            {
-                return new String( baos.toByteArray(), PREFERRED_ENCODING );
-            }   // end try
-            catch (java.io.UnsupportedEncodingException uue)
-            {
-                return new String( baos.toByteArray() );
-            }   // end catch
-        }   // end if: compress
-
-        // Else, don't compress. Better not to use streams at all then.
-        else
-        {
-            // Convert option to boolean in way that code likes it.
-            boolean breakLines = dontBreakLines == 0;
-
-            int    len43   = len * 4 / 3;
-            byte[] outBuff = new byte[   ( len43 )                      // Main 4:3
-                                       + ( (len % 3) > 0 ? 4 : 0 )      // Account for padding
-                                       + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines
-            int d = 0;
-            int e = 0;
-            int len2 = len - 2;
-            int lineLength = 0;
-            for( ; d < len2; d+=3, e+=4 )
-            {
-                encode3to4( source, d+off, 3, outBuff, e, options );
-
-                lineLength += 4;
-                if( breakLines && lineLength == MAX_LINE_LENGTH )
-                {
-                    outBuff[e+4] = NEW_LINE;
-                    e++;
-                    lineLength = 0;
-                }   // end if: end of line
-            }   // en dfor: each piece of array
-
-            if( d < len )
-            {
-                encode3to4( source, d+off, len - d, outBuff, e, options );
-                e += 4;
-            }   // end if: some padding needed
-
-
-            // Return value according to relevant encoding.
-            try
-            {
-                return new String( outBuff, 0, e, PREFERRED_ENCODING );
-            }   // end try
-            catch (java.io.UnsupportedEncodingException uue)
-            {
-                return new String( outBuff, 0, e );
-            }   // end catch
-
-        }   // end else: don't compress
-
-    }   // end encodeBytes
-
-
-
-
-
-/* ********  D E C O D I N G   M E T H O D S  ******** */
-
-
-    /**
-     * Decodes four bytes from array <var>source</var>
-     * and writes the resulting bytes (up to three of them)
-     * to <var>destination</var>.
-     * The source and destination arrays can be manipulated
-     * anywhere along their length by specifying
-     * <var>srcOffset</var> and <var>destOffset</var>.
-     * This method does not check to make sure your arrays
-     * are large enough to accomodate <var>srcOffset</var> + 4 for
-     * the <var>source</var> array or <var>destOffset</var> + 3 for
-     * the <var>destination</var> array.
-     * This method returns the actual number of bytes that
-     * were converted from the Base64 encoding.
-	 * <p>This is the lowest level of the decoding methods with
-	 * all possible parameters.</p>
-     *
-     *
-     * @param source the array to convert
-     * @param srcOffset the index where conversion begins
-     * @param destination the array to hold the conversion
-     * @param destOffset the index where output will be put
-	 * @param options alphabet type is pulled from this (standard, url-safe, ordered)
-     * @return the number of decoded bytes converted
-     * @since 1.3
-     */
-    private static int decode4to3( byte[] source, int srcOffset, byte[] destination, int destOffset, int options )
-    {
-		byte[] DECODABET = getDecodabet( options );
-
-        // Example: Dk==
-        if( source[ srcOffset + 2] == EQUALS_SIGN )
-        {
-            // Two ways to do the same thing. Don't know which way I like best.
-            //int outBuff =   ( ( DECODABET[ source[ srcOffset    ] ] << 24 ) >>>  6 )
-            //              | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 );
-            int outBuff =   ( ( DECODABET[ source[ srcOffset    ] ] & 0xFF ) << 18 )
-                          | ( ( DECODABET[ source[ srcOffset + 1] ] & 0xFF ) << 12 );
-
-            destination[ destOffset ] = (byte)( outBuff >>> 16 );
-            return 1;
-        }
-
-        // Example: DkL=
-        else if( source[ srcOffset + 3 ] == EQUALS_SIGN )
-        {
-            // Two ways to do the same thing. Don't know which way I like best.
-            //int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] << 24 ) >>>  6 )
-            //              | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
-            //              | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 );
-            int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] & 0xFF ) << 18 )
-                          | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 )
-                          | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) <<  6 );
-
-            destination[ destOffset     ] = (byte)( outBuff >>> 16 );
-            destination[ destOffset + 1 ] = (byte)( outBuff >>>  8 );
-            return 2;
-        }
-
-        // Example: DkLE
-        else
-        {
-            try{
-            // Two ways to do the same thing. Don't know which way I like best.
-            //int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] << 24 ) >>>  6 )
-            //              | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
-            //              | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 )
-            //              | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 );
-            int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] & 0xFF ) << 18 )
-                          | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 )
-                          | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) <<  6)
-                          | ( ( DECODABET[ source[ srcOffset + 3 ] ] & 0xFF )      );
-
-
-            destination[ destOffset     ] = (byte)( outBuff >> 16 );
-            destination[ destOffset + 1 ] = (byte)( outBuff >>  8 );
-            destination[ destOffset + 2 ] = (byte)( outBuff       );
-
-            return 3;
-            }catch( Exception e){
-                System.out.println(""+source[srcOffset]+ ": " + ( DECODABET[ source[ srcOffset     ] ]  ) );
-                System.out.println(""+source[srcOffset+1]+  ": " + ( DECODABET[ source[ srcOffset + 1 ] ]  ) );
-                System.out.println(""+source[srcOffset+2]+  ": " + ( DECODABET[ source[ srcOffset + 2 ] ]  ) );
-                System.out.println(""+source[srcOffset+3]+  ": " + ( DECODABET[ source[ srcOffset + 3 ] ]  ) );
-                return -1;
-            }   // end catch
-        }
-    }   // end decodeToBytes
-
-
-
-
-    /**
-     * Very low-level access to decoding ASCII characters in
-     * the form of a byte array. Does not support automatically
-     * gunzipping or any other "fancy" features.
-     *
-     * @param source The Base64 encoded data
-     * @param off    The offset of where to begin decoding
-     * @param len    The length of characters to decode
-     * @return decoded data
-     * @since 1.3
-     */
-    public static byte[] decode( byte[] source, int off, int len, int options )
-    {
-		byte[] DECODABET = getDecodabet( options );
-
-        int    len34   = len * 3 / 4;
-        byte[] outBuff = new byte[ len34 ]; // Upper limit on size of output
-        int    outBuffPosn = 0;
-
-        byte[] b4        = new byte[4];
-        int    b4Posn    = 0;
-        int    i         = 0;
-        byte   sbiCrop   = 0;
-        byte   sbiDecode = 0;
-        for( i = off; i < off+len; i++ )
-        {
-            sbiCrop = (byte)(source[i] & 0x7f); // Only the low seven bits
-            sbiDecode = DECODABET[ sbiCrop ];
-
-            if( sbiDecode >= WHITE_SPACE_ENC ) // White space, Equals sign or better
-            {
-                if( sbiDecode >= EQUALS_SIGN_ENC )
-                {
-                    b4[ b4Posn++ ] = sbiCrop;
-                    if( b4Posn > 3 )
-                    {
-                        outBuffPosn += decode4to3( b4, 0, outBuff, outBuffPosn, options );
-                        b4Posn = 0;
-
-                        // If that was the equals sign, break out of 'for' loop
-                        if( sbiCrop == EQUALS_SIGN )
-                            break;
-                    }   // end if: quartet built
-
-                }   // end if: equals sign or better
-
-            }   // end if: white space, equals sign or better
-            else
-            {
-                System.err.println( "Bad Base64 input character at " + i + ": " + source[i] + "(decimal)" );
-                return null;
-            }   // end else:
-        }   // each input character
-
-        byte[] out = new byte[ outBuffPosn ];
-        System.arraycopy( outBuff, 0, out, 0, outBuffPosn );
-        return out;
-    }   // end decode
-
-
-
-
-    /**
-     * Decodes data from Base64 notation, automatically
-     * detecting gzip-compressed data and decompressing it.
-     *
-     * @param s the string to decode
-     * @return the decoded data
-     * @since 1.4
-     */
-    public static byte[] decode( String s )
-	{
-		return decode( s, NO_OPTIONS );
-	}
-
-
-    /**
-     * Decodes data from Base64 notation, automatically
-     * detecting gzip-compressed data and decompressing it.
-     *
-     * @param s the string to decode
-	 * @param options encode options such as URL_SAFE
-     * @return the decoded data
-     * @since 1.4
-     */
-    public static byte[] decode( String s, int options )
-    {
-        byte[] bytes;
-        try
-        {
-            bytes = s.getBytes( PREFERRED_ENCODING );
-        }   // end try
-        catch( java.io.UnsupportedEncodingException uee )
-        {
-            bytes = s.getBytes();
-        }   // end catch
-		//</change>
-
-        // Decode
-        bytes = decode( bytes, 0, bytes.length, options );
-
-
-        // Check to see if it's gzip-compressed
-        // GZIP Magic Two-Byte Number: 0x8b1f (35615)
-        if( bytes != null && bytes.length >= 4 )
-        {
-
-            int head = ((int)bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00);
-            if( java.util.zip.GZIPInputStream.GZIP_MAGIC == head )
-            {
-                java.io.ByteArrayInputStream  bais = null;
-                java.util.zip.GZIPInputStream gzis = null;
-                java.io.ByteArrayOutputStream baos = null;
-                byte[] buffer = new byte[2048];
-                int    length = 0;
-
-                try
-                {
-                    baos = new java.io.ByteArrayOutputStream();
-                    bais = new java.io.ByteArrayInputStream( bytes );
-                    gzis = new java.util.zip.GZIPInputStream( bais );
-
-                    while( ( length = gzis.read( buffer ) ) >= 0 )
-                    {
-                        baos.write(buffer,0,length);
-                    }   // end while: reading input
-
-                    // No error? Get new bytes.
-                    bytes = baos.toByteArray();
-
-                }   // end try
-                catch( java.io.IOException e )
-                {
-                    // Just return originally-decoded bytes
-                }   // end catch
-                finally
-                {
-                    try{ baos.close(); } catch( Exception e ){}
-                    try{ gzis.close(); } catch( Exception e ){}
-                    try{ bais.close(); } catch( Exception e ){}
-                }   // end finally
-
-            }   // end if: gzipped
-        }   // end if: bytes.length >= 2
-
-        return bytes;
-    }   // end decode
-
-
-
-
-    /**
-     * Attempts to decode Base64 data and deserialize a Java
-     * Object within. Returns <tt>null</tt> if there was an error.
-     *
-     * @param encodedObject The Base64 data to decode
-     * @return The decoded and deserialized object
-     * @since 1.5
-     */
-    public static Object decodeToObject( String encodedObject )
-    {
-        // Decode and gunzip if necessary
-        byte[] objBytes = decode( encodedObject );
-
-        java.io.ByteArrayInputStream  bais = null;
-        java.io.ObjectInputStream     ois  = null;
-        Object obj = null;
-
-        try
-        {
-            bais = new java.io.ByteArrayInputStream( objBytes );
-            ois  = new java.io.ObjectInputStream( bais );
-
-            obj = ois.readObject();
-        }   // end try
-        catch( java.io.IOException e )
-        {
-            e.printStackTrace();
-            obj = null;
-        }   // end catch
-        catch( java.lang.ClassNotFoundException e )
-        {
-            e.printStackTrace();
-            obj = null;
-        }   // end catch
-        finally
-        {
-            try{ bais.close(); } catch( Exception e ){}
-            try{ ois.close();  } catch( Exception e ){}
-        }   // end finally
-
-        return obj;
-    }   // end decodeObject
-
-
-
-    /**
-     * Convenience method for encoding data to a file.
-     *
-     * @param dataToEncode byte array of data to encode in base64 form
-     * @param filename Filename for saving encoded data
-     * @return <tt>true</tt> if successful, <tt>false</tt> otherwise
-     *
-     * @since 2.1
-     */
-    public static boolean encodeToFile( byte[] dataToEncode, String filename )
-    {
-        boolean success = false;
-        Base64.OutputStream bos = null;
-        try
-        {
-            bos = new Base64.OutputStream(
-                      new java.io.FileOutputStream( filename ), Base64.ENCODE );
-            bos.write( dataToEncode );
-            success = true;
-        }   // end try
-        catch( java.io.IOException e )
-        {
-
-            success = false;
-        }   // end catch: IOException
-        finally
-        {
-            try{ bos.close(); } catch( Exception e ){}
-        }   // end finally
-
-        return success;
-    }   // end encodeToFile
-
-
-    /**
-     * Convenience method for decoding data to a file.
-     *
-     * @param dataToDecode Base64-encoded data as a string
-     * @param filename Filename for saving decoded data
-     * @return <tt>true</tt> if successful, <tt>false</tt> otherwise
-     *
-     * @since 2.1
-     */
-    public static boolean decodeToFile( String dataToDecode, String filename )
-    {
-        boolean success = false;
-        Base64.OutputStream bos = null;
-        try
-        {
-                bos = new Base64.OutputStream(
-                          new java.io.FileOutputStream( filename ), Base64.DECODE );
-                bos.write( dataToDecode.getBytes( PREFERRED_ENCODING ) );
-                success = true;
-        }   // end try
-        catch( java.io.IOException e )
-        {
-            success = false;
-        }   // end catch: IOException
-        finally
-        {
-                try{ bos.close(); } catch( Exception e ){}
-        }   // end finally
-
-        return success;
-    }   // end decodeToFile
-
-
-
-
-    /**
-     * Convenience method for reading a base64-encoded
-     * file and decoding it.
-     *
-     * @param filename Filename for reading encoded data
-     * @return decoded byte array or null if unsuccessful
-     *
-     * @since 2.1
-     */
-    public static byte[] decodeFromFile( String filename )
-    {
-        byte[] decodedData = null;
-        Base64.InputStream bis = null;
-        try
-        {
-            // Set up some useful variables
-            java.io.File file = new java.io.File( filename );
-            byte[] buffer = null;
-            int length   = 0;
-            int numBytes = 0;
-
-            // Check for size of file
-            if( file.length() > Integer.MAX_VALUE )
-            {
-                System.err.println( "File is too big for this convenience method (" + file.length() + " bytes)." );
-                return null;
-            }   // end if: file too big for int index
-            buffer = new byte[ (int)file.length() ];
-
-            // Open a stream
-            bis = new Base64.InputStream(
-                      new java.io.BufferedInputStream(
-                      new java.io.FileInputStream( file ) ), Base64.DECODE );
-
-            // Read until done
-            while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 )
-                length += numBytes;
-
-            // Save in a variable to return
-            decodedData = new byte[ length ];
-            System.arraycopy( buffer, 0, decodedData, 0, length );
-
-        }   // end try
-        catch( java.io.IOException e )
-        {
-            System.err.println( "Error decoding from file " + filename );
-        }   // end catch: IOException
-        finally
-        {
-            try{ bis.close(); } catch( Exception e) {}
-        }   // end finally
-
-        return decodedData;
-    }   // end decodeFromFile
-
-
-
-    /**
-     * Convenience method for reading a binary file
-     * and base64-encoding it.
-     *
-     * @param filename Filename for reading binary data
-     * @return base64-encoded string or null if unsuccessful
-     *
-     * @since 2.1
-     */
-    public static String encodeFromFile( String filename )
-    {
-        String encodedData = null;
-        Base64.InputStream bis = null;
-        try
-        {
-            // Set up some useful variables
-            java.io.File file = new java.io.File( filename );
-            byte[] buffer = new byte[ Math.max((int)(file.length() * 1.4),40) ]; // Need max() for math on small files (v2.2.1)
-            int length   = 0;
-            int numBytes = 0;
-
-            // Open a stream
-            bis = new Base64.InputStream(
-                      new java.io.BufferedInputStream(
-                      new java.io.FileInputStream( file ) ), Base64.ENCODE );
-
-            // Read until done
-            while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 )
-                length += numBytes;
-
-            // Save in a variable to return
-            encodedData = new String( buffer, 0, length, Base64.PREFERRED_ENCODING );
-
-        }   // end try
-        catch( java.io.IOException e )
-        {
-            System.err.println( "Error encoding from file " + filename );
-        }   // end catch: IOException
-        finally
-        {
-            try{ bis.close(); } catch( Exception e) {}
-        }   // end finally
-
-        return encodedData;
-        }   // end encodeFromFile
-
-    /**
-     * Reads <tt>infile</tt> and encodes it to <tt>outfile</tt>.
-     *
-     * @param infile Input file
-     * @param outfile Output file
-     * @since 2.2
-     */
-    public static void encodeFileToFile( String infile, String outfile )
-    {
-        String encoded = Base64.encodeFromFile( infile );
-        java.io.OutputStream out = null;
-        try{
-            out = new java.io.BufferedOutputStream(
-                  new java.io.FileOutputStream( outfile ) );
-            out.write( encoded.getBytes("US-ASCII") ); // Strict, 7-bit output.
-        }   // end try
-        catch( java.io.IOException ex ) {
-            ex.printStackTrace();
-        }   // end catch
-        finally {
-            try { out.close(); }
-            catch( Exception ex ){}
-        }   // end finally
-    }   // end encodeFileToFile
-
-
-    /**
-     * Reads <tt>infile</tt> and decodes it to <tt>outfile</tt>.
-     *
-     * @param infile Input file
-     * @param outfile Output file
-     * @since 2.2
-     */
-    public static void decodeFileToFile( String infile, String outfile )
-    {
-        byte[] decoded = Base64.decodeFromFile( infile );
-        java.io.OutputStream out = null;
-        try{
-            out = new java.io.BufferedOutputStream(
-                  new java.io.FileOutputStream( outfile ) );
-            out.write( decoded );
-        }   // end try
-        catch( java.io.IOException ex ) {
-            ex.printStackTrace();
-        }   // end catch
-        finally {
-            try { out.close(); }
-            catch( Exception ex ){}
-        }   // end finally
-    }   // end decodeFileToFile
-
-
-    /* ********  I N N E R   C L A S S   I N P U T S T R E A M  ******** */
-
-
-
-    /**
-     * A {@link Base64.InputStream} will read data from another
-     * <tt>java.io.InputStream</tt>, given in the constructor,
-     * and encode/decode to/from Base64 notation on the fly.
-     *
-     * @see Base64
-     * @since 1.3
-     */
-    public static class InputStream extends java.io.FilterInputStream
-    {
-        private boolean encode;         // Encoding or decoding
-        private int     position;       // Current position in the buffer
-        private byte[]  buffer;         // Small buffer holding converted data
-        private int     bufferLength;   // Length of buffer (3 or 4)
-        private int     numSigBytes;    // Number of meaningful bytes in the buffer
-        private int     lineLength;
-        private boolean breakLines;     // Break lines at less than 80 characters
-		private int     options;        // Record options used to create the stream.
-		private byte[]  alphabet;	    // Local copies to avoid extra method calls
-		private byte[]  decodabet;		// Local copies to avoid extra method calls
-
-
-        /**
-         * Constructs a {@link Base64.InputStream} in DECODE mode.
-         *
-         * @param in the <tt>java.io.InputStream</tt> from which to read data.
-         * @since 1.3
-         */
-        public InputStream( java.io.InputStream in )
-        {
-            this( in, DECODE );
-        }   // end constructor
-
-
-        /**
-         * Constructs a {@link Base64.InputStream} in
-         * either ENCODE or DECODE mode.
-         * <p>
-         * Valid options:<pre>
-         *   ENCODE or DECODE: Encode or Decode as data is read.
-         *   DONT_BREAK_LINES: don't break lines at 76 characters
-         *     (only meaningful when encoding)
-         *     <i>Note: Technically, this makes your encoding non-compliant.</i>
-         * </pre>
-         * <p>
-         * Example: <code>new Base64.InputStream( in, Base64.DECODE )</code>
-         *
-         *
-         * @param in the <tt>java.io.InputStream</tt> from which to read data.
-         * @param options Specified options
-         * @see Base64#ENCODE
-         * @see Base64#DECODE
-         * @see Base64#DONT_BREAK_LINES
-         * @since 2.0
-         */
-        public InputStream( java.io.InputStream in, int options )
-        {
-            super( in );
-            this.breakLines   = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES;
-            this.encode       = (options & ENCODE) == ENCODE;
-            this.bufferLength = encode ? 4 : 3;
-            this.buffer       = new byte[ bufferLength ];
-            this.position     = -1;
-            this.lineLength   = 0;
-			this.options      = options; // Record for later, mostly to determine which alphabet to use
-			this.alphabet     = getAlphabet(options);
-			this.decodabet    = getDecodabet(options);
-        }   // end constructor
-
-        /**
-         * Reads enough of the input stream to convert
-         * to/from Base64 and returns the next byte.
-         *
-         * @return next byte
-         * @since 1.3
-         */
-        public int read() throws java.io.IOException
-        {
-            // Do we need to get data?
-            if( position < 0 )
-            {
-                if( encode )
-                {
-                    byte[] b3 = new byte[3];
-                    int numBinaryBytes = 0;
-                    for( int i = 0; i < 3; i++ )
-                    {
-                        try
-                        {
-                            int b = in.read();
-
-                            // If end of stream, b is -1.
-                            if( b >= 0 )
-                            {
-                                b3[i] = (byte)b;
-                                numBinaryBytes++;
-                            }   // end if: not end of stream
-
-                        }   // end try: read
-                        catch( java.io.IOException e )
-                        {
-                            // Only a problem if we got no data at all.
-                            if( i == 0 )
-                                throw e;
-
-                        }   // end catch
-                    }   // end for: each needed input byte
-
-                    if( numBinaryBytes > 0 )
-                    {
-                        encode3to4( b3, 0, numBinaryBytes, buffer, 0, options );
-                        position = 0;
-                        numSigBytes = 4;
-                    }   // end if: got data
-                    else
-                    {
-                        return -1;
-                    }   // end else
-                }   // end if: encoding
-
-                // Else decoding
-                else
-                {
-                    byte[] b4 = new byte[4];
-                    int i = 0;
-                    for( i = 0; i < 4; i++ )
-                    {
-                        // Read four "meaningful" bytes:
-                        int b = 0;
-                        do{ b = in.read(); }
-                        while( b >= 0 && decodabet[ b & 0x7f ] <= WHITE_SPACE_ENC );
-
-                        if( b < 0 )
-                            break; // Reads a -1 if end of stream
-
-                        b4[i] = (byte)b;
-                    }   // end for: each needed input byte
-
-                    if( i == 4 )
-                    {
-                        numSigBytes = decode4to3( b4, 0, buffer, 0, options );
-                        position = 0;
-                    }   // end if: got four characters
-                    else if( i == 0 ){
-                        return -1;
-                    }   // end else if: also padded correctly
-                    else
-                    {
-                        // Must have broken out from above.
-                        throw new java.io.IOException( "Improperly padded Base64 input." );
-                    }   // end
-
-                }   // end else: decode
-            }   // end else: get data
-
-            // Got data?
-            if( position >= 0 )
-            {
-                // End of relevant data?
-                if( /*!encode &&*/ position >= numSigBytes )
-                    return -1;
-
-                if( encode && breakLines && lineLength >= MAX_LINE_LENGTH )
-                {
-                    lineLength = 0;
-                    return '\n';
-                }   // end if
-                else
-                {
-                    lineLength++;   // This isn't important when decoding
-                                    // but throwing an extra "if" seems
-                                    // just as wasteful.
-
-                    int b = buffer[ position++ ];
-
-                    if( position >= bufferLength )
-                        position = -1;
-
-                    return b & 0xFF; // This is how you "cast" a byte that's
-                                     // intended to be unsigned.
-                }   // end else
-            }   // end if: position >= 0
-
-            // Else error
-            else
-            {
-                // When JDK1.4 is more accepted, use an assertion here.
-                throw new java.io.IOException( "Error in Base64 code reading stream." );
-            }   // end else
-        }   // end read
-
-
-        /**
-         * Calls {@link #read()} repeatedly until the end of stream
-         * is reached or <var>len</var> bytes are read.
-         * Returns number of bytes read into array or -1 if
-         * end of stream is encountered.
-         *
-         * @param dest array to hold values
-         * @param off offset for array
-         * @param len max number of bytes to read into array
-         * @return bytes read into array or -1 if end of stream is encountered.
-         * @since 1.3
-         */
-        public int read( byte[] dest, int off, int len ) throws java.io.IOException
-        {
-            int i;
-            int b;
-            for( i = 0; i < len; i++ )
-            {
-                b = read();
-
-                //if( b < 0 && i == 0 )
-                //    return -1;
-
-                if( b >= 0 )
-                    dest[off + i] = (byte)b;
-                else if( i == 0 )
-                    return -1;
-                else
-                    break; // Out of 'for' loop
-            }   // end for: each byte read
-            return i;
-        }   // end read
-
-    }   // end inner class InputStream
-
-
-
-
-
-
-    /* ********  I N N E R   C L A S S   O U T P U T S T R E A M  ******** */
-
-
-
-    /**
-     * A {@link Base64.OutputStream} will write data to another
-     * <tt>java.io.OutputStream</tt>, given in the constructor,
-     * and encode/decode to/from Base64 notation on the fly.
-     *
-     * @see Base64
-     * @since 1.3
-     */
-    public static class OutputStream extends java.io.FilterOutputStream
-    {
-        private boolean encode;
-        private int     position;
-        private byte[]  buffer;
-        private int     bufferLength;
-        private int     lineLength;
-        private boolean breakLines;
-        private byte[]  b4; // Scratch used in a few places
-        private boolean suspendEncoding;
-		private int options; // Record for later
-		private byte[]  alphabet;	    // Local copies to avoid extra method calls
-		private byte[]  decodabet;		// Local copies to avoid extra method calls
-
-        /**
-         * Constructs a {@link Base64.OutputStream} in ENCODE mode.
-         *
-         * @param out the <tt>java.io.OutputStream</tt> to which data will be written.
-         * @since 1.3
-         */
-        public OutputStream( java.io.OutputStream out )
-        {
-            this( out, ENCODE );
-        }   // end constructor
-
-
-        /**
-         * Constructs a {@link Base64.OutputStream} in
-         * either ENCODE or DECODE mode.
-         * <p>
-         * Valid options:<pre>
-         *   ENCODE or DECODE: Encode or Decode as data is read.
-         *   DONT_BREAK_LINES: don't break lines at 76 characters
-         *     (only meaningful when encoding)
-         *     <i>Note: Technically, this makes your encoding non-compliant.</i>
-         * </pre>
-         * <p>
-         * Example: <code>new Base64.OutputStream( out, Base64.ENCODE )</code>
-         *
-         * @param out the <tt>java.io.OutputStream</tt> to which data will be written.
-         * @param options Specified options.
-         * @see Base64#ENCODE
-         * @see Base64#DECODE
-         * @see Base64#DONT_BREAK_LINES
-         * @since 1.3
-         */
-        public OutputStream( java.io.OutputStream out, int options )
-        {
-            super( out );
-            this.breakLines   = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES;
-            this.encode       = (options & ENCODE) == ENCODE;
-            this.bufferLength = encode ? 3 : 4;
-            this.buffer       = new byte[ bufferLength ];
-            this.position     = 0;
-            this.lineLength   = 0;
-            this.suspendEncoding = false;
-            this.b4           = new byte[4];
-			this.options      = options;
-			this.alphabet     = getAlphabet(options);
-			this.decodabet    = getDecodabet(options);
-        }   // end constructor
-
-
-        /**
-         * Writes the byte to the output stream after
-         * converting to/from Base64 notation.
-         * When encoding, bytes are buffered three
-         * at a time before the output stream actually
-         * gets a write() call.
-         * When decoding, bytes are buffered four
-         * at a time.
-         *
-         * @param theByte the byte to write
-         * @since 1.3
-         */
-        public void write(int theByte) throws java.io.IOException
-        {
-            // Encoding suspended?
-            if( suspendEncoding )
-            {
-                super.out.write( theByte );
-                return;
-            }   // end if: supsended
-
-            // Encode?
-            if( encode )
-            {
-                buffer[ position++ ] = (byte)theByte;
-                if( position >= bufferLength )  // Enough to encode.
-                {
-                    out.write( encode3to4( b4, buffer, bufferLength, options ) );
-
-                    lineLength += 4;
-                    if( breakLines && lineLength >= MAX_LINE_LENGTH )
-                    {
-                        out.write( NEW_LINE );
-                        lineLength = 0;
-                    }   // end if: end of line
-
-                    position = 0;
-                }   // end if: enough to output
-            }   // end if: encoding
-
-            // Else, Decoding
-            else
-            {
-                // Meaningful Base64 character?
-                if( decodabet[ theByte & 0x7f ] > WHITE_SPACE_ENC )
-                {
-                    buffer[ position++ ] = (byte)theByte;
-                    if( position >= bufferLength )  // Enough to output.
-                    {
-                        int len = Base64.decode4to3( buffer, 0, b4, 0, options );
-                        out.write( b4, 0, len );
-                        //out.write( Base64.decode4to3( buffer ) );
-                        position = 0;
-                    }   // end if: enough to output
-                }   // end if: meaningful base64 character
-                else if( decodabet[ theByte & 0x7f ] != WHITE_SPACE_ENC )
-                {
-                    throw new java.io.IOException( "Invalid character in Base64 data." );
-                }   // end else: not white space either
-            }   // end else: decoding
-        }   // end write
-
-
-
-        /**
-         * Calls {@link #write(int)} repeatedly until <var>len</var>
-         * bytes are written.
-         *
-         * @param theBytes array from which to read bytes
-         * @param off offset for array
-         * @param len max number of bytes to read into array
-         * @since 1.3
-         */
-        public void write( byte[] theBytes, int off, int len ) throws java.io.IOException
-        {
-            // Encoding suspended?
-            if( suspendEncoding )
-            {
-                super.out.write( theBytes, off, len );
-                return;
-            }   // end if: supsended
-
-            for( int i = 0; i < len; i++ )
-            {
-                write( theBytes[ off + i ] );
-            }   // end for: each byte written
-
-        }   // end write
-
-
-
-        /**
-         * Method added by PHIL. [Thanks, PHIL. -Rob]
-         * This pads the buffer without closing the stream.
-         */
-        public void flushBase64() throws java.io.IOException
-        {
-            if( position > 0 )
-            {
-                if( encode )
-                {
-                    out.write( encode3to4( b4, buffer, position, options ) );
-                    position = 0;
-                }   // end if: encoding
-                else
-                {
-                    throw new java.io.IOException( "Base64 input not properly padded." );
-                }   // end else: decoding
-            }   // end if: buffer partially full
-
-        }   // end flush
-
-
-        /**
-         * Flushes and closes (I think, in the superclass) the stream.
-         *
-         * @since 1.3
-         */
-        public void close() throws java.io.IOException
-        {
-            // 1. Ensure that pending characters are written
-            flushBase64();
-
-            // 2. Actually close the stream
-            // Base class both flushes and closes.
-            super.close();
-
-            buffer = null;
-            out    = null;
-        }   // end close
-
-
-
-        /**
-         * Suspends encoding of the stream.
-         * May be helpful if you need to embed a piece of
-         * base640-encoded data in a stream.
-         *
-         * @since 1.5.1
-         */
-        public void suspendEncoding() throws java.io.IOException
-        {
-            flushBase64();
-            this.suspendEncoding = true;
-        }   // end suspendEncoding
-
-
-        /**
-         * Resumes encoding of the stream.
-         * May be helpful if you need to embed a piece of
-         * base640-encoded data in a stream.
-         *
-         * @since 1.5.1
-         */
-        public void resumeEncoding()
-        {
-            this.suspendEncoding = false;
-        }   // end resumeEncoding
-
-
-
-    }   // end inner class OutputStream
-
-
-}   // end class Base64
-
+ * This code was obtained from <a href="http://iharder.net/base64">http://iharder.net/base64</a></p>
+ *
+ *
+ * @author Robert Harder
+ * @author rob@iharder.net
+ * @version 2.2.1
+ */
+public class Base64
+{
+
+/* ********  P U B L I C   F I E L D S  ******** */
+
+
+    /** No options specified. Value is zero. */
+    public final static int NO_OPTIONS = 0;
+
+    /** Specify encoding. */
+    public final static int ENCODE = 1;
+
+
+    /** Specify decoding. */
+    public final static int DECODE = 0;
+
+
+    /** Specify that data should be gzip-compressed. */
+    public final static int GZIP = 2;
+
+
+    /** Don't break lines when encoding (violates strict Base64 specification) */
+    public final static int DONT_BREAK_LINES = 8;
+
+	/**
+	 * Encode using Base64-like encoding that is URL- and Filename-safe as described
+	 * in Section 4 of RFC3548:
+	 * <a href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>.
+	 * It is important to note that data encoded this way is <em>not</em> officially valid Base64,
+	 * or at the very least should not be called Base64 without also specifying that is
+	 * was encoded using the URL- and Filename-safe dialect.
+	 */
+	 public final static int URL_SAFE = 16;
+
+
+	 /**
+	  * Encode using the special "ordered" dialect of Base64 described here:
+	  * <a href="http://www.faqs.org/qa/rfcc-1940.html">http://www.faqs.org/qa/rfcc-1940.html</a>.
+	  */
+	 public final static int ORDERED = 32;
+
+
+/* ********  P R I V A T E   F I E L D S  ******** */
+
+
+    /** Maximum line length (76) of Base64 output. */
+    private final static int MAX_LINE_LENGTH = 76;
+
+
+    /** The equals sign (=) as a byte. */
+    private final static byte EQUALS_SIGN = (byte)'=';
+
+
+    /** The new line character (\n) as a byte. */
+    private final static byte NEW_LINE = (byte)'\n';
+
+
+    /** Preferred encoding. */
+    private final static String PREFERRED_ENCODING = "UTF-8";
+
+
+    // I think I end up not using the BAD_ENCODING indicator.
+    //private final static byte BAD_ENCODING    = -9; // Indicates error in encoding
+    private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding
+    private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding
+
+
+/* ********  S T A N D A R D   B A S E 6 4   A L P H A B E T  ******** */
+
+    /** The 64 valid Base64 values. */
+    //private final static byte[] ALPHABET;
+	/* Host platform me be something funny like EBCDIC, so we hardcode these values. */
+	private final static byte[] _STANDARD_ALPHABET =
+    {
+        (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
+        (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
+        (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
+        (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
+        (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
+        (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
+        (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
+        (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z',
+        (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',
+        (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/'
+    };
+
+
+    /**
+     * Translates a Base64 value to either its 6-bit reconstruction value
+     * or a negative number indicating some other meaning.
+     **/
+    private final static byte[] _STANDARD_DECODABET =
+    {
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,                 // Decimal  0 -  8
+        -5,-5,                                      // Whitespace: Tab and Linefeed
+        -9,-9,                                      // Decimal 11 - 12
+        -5,                                         // Whitespace: Carriage Return
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 14 - 26
+        -9,-9,-9,-9,-9,                             // Decimal 27 - 31
+        -5,                                         // Whitespace: Space
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,              // Decimal 33 - 42
+        62,                                         // Plus sign at decimal 43
+        -9,-9,-9,                                   // Decimal 44 - 46
+        63,                                         // Slash at decimal 47
+        52,53,54,55,56,57,58,59,60,61,              // Numbers zero through nine
+        -9,-9,-9,                                   // Decimal 58 - 60
+        -1,                                         // Equals sign at decimal 61
+        -9,-9,-9,                                      // Decimal 62 - 64
+        0,1,2,3,4,5,6,7,8,9,10,11,12,13,            // Letters 'A' through 'N'
+        14,15,16,17,18,19,20,21,22,23,24,25,        // Letters 'O' through 'Z'
+        -9,-9,-9,-9,-9,-9,                          // Decimal 91 - 96
+        26,27,28,29,30,31,32,33,34,35,36,37,38,     // Letters 'a' through 'm'
+        39,40,41,42,43,44,45,46,47,48,49,50,51,     // Letters 'n' through 'z'
+        -9,-9,-9,-9                                 // Decimal 123 - 126
+        /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 127 - 139
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 140 - 152
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 153 - 165
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 166 - 178
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 179 - 191
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 192 - 204
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 205 - 217
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 218 - 230
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 231 - 243
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9         // Decimal 244 - 255 */
+    };
+
+
+/* ********  U R L   S A F E   B A S E 6 4   A L P H A B E T  ******** */
+
+	/**
+	 * Used in the URL- and Filename-safe dialect described in Section 4 of RFC3548:
+	 * <a href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>.
+	 * Notice that the last two bytes become "hyphen" and "underscore" instead of "plus" and "slash."
+	 */
+    private final static byte[] _URL_SAFE_ALPHABET =
+    {
+      (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
+      (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
+      (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
+      (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
+      (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
+      (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
+      (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
+      (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z',
+      (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',
+      (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'-', (byte)'_'
+    };
+
+	/**
+	 * Used in decoding URL- and Filename-safe dialects of Base64.
+	 */
+    private final static byte[] _URL_SAFE_DECODABET =
+    {
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,                 // Decimal  0 -  8
+      -5,-5,                                      // Whitespace: Tab and Linefeed
+      -9,-9,                                      // Decimal 11 - 12
+      -5,                                         // Whitespace: Carriage Return
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 14 - 26
+      -9,-9,-9,-9,-9,                             // Decimal 27 - 31
+      -5,                                         // Whitespace: Space
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,              // Decimal 33 - 42
+      -9,                                         // Plus sign at decimal 43
+      -9,                                         // Decimal 44
+      62,                                         // Minus sign at decimal 45
+      -9,                                         // Decimal 46
+      -9,                                         // Slash at decimal 47
+      52,53,54,55,56,57,58,59,60,61,              // Numbers zero through nine
+      -9,-9,-9,                                   // Decimal 58 - 60
+      -1,                                         // Equals sign at decimal 61
+      -9,-9,-9,                                   // Decimal 62 - 64
+      0,1,2,3,4,5,6,7,8,9,10,11,12,13,            // Letters 'A' through 'N'
+      14,15,16,17,18,19,20,21,22,23,24,25,        // Letters 'O' through 'Z'
+      -9,-9,-9,-9,                                // Decimal 91 - 94
+      63,                                         // Underscore at decimal 95
+      -9,                                         // Decimal 96
+      26,27,28,29,30,31,32,33,34,35,36,37,38,     // Letters 'a' through 'm'
+      39,40,41,42,43,44,45,46,47,48,49,50,51,     // Letters 'n' through 'z'
+      -9,-9,-9,-9                                 // Decimal 123 - 126
+      /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 127 - 139
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 140 - 152
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 153 - 165
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 166 - 178
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 179 - 191
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 192 - 204
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 205 - 217
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 218 - 230
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 231 - 243
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9         // Decimal 244 - 255 */
+    };
+
+
+
+/* ********  O R D E R E D   B A S E 6 4   A L P H A B E T  ******** */
+
+	/**
+	 * I don't get the point of this technique, but it is described here:
+	 * <a href="http://www.faqs.org/qa/rfcc-1940.html">http://www.faqs.org/qa/rfcc-1940.html</a>.
+	 */
+    private final static byte[] _ORDERED_ALPHABET =
+    {
+      (byte)'-',
+      (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4',
+      (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9',
+      (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
+      (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
+      (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
+      (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
+      (byte)'_',
+      (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
+      (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
+      (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
+      (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z'
+    };
+
+	/**
+	 * Used in decoding the "ordered" dialect of Base64.
+	 */
+    private final static byte[] _ORDERED_DECODABET =
+    {
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,                 // Decimal  0 -  8
+      -5,-5,                                      // Whitespace: Tab and Linefeed
+      -9,-9,                                      // Decimal 11 - 12
+      -5,                                         // Whitespace: Carriage Return
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 14 - 26
+      -9,-9,-9,-9,-9,                             // Decimal 27 - 31
+      -5,                                         // Whitespace: Space
+      -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,              // Decimal 33 - 42
+      -9,                                         // Plus sign at decimal 43
+      -9,                                         // Decimal 44
+      0,                                          // Minus sign at decimal 45
+      -9,                                         // Decimal 46
+      -9,                                         // Slash at decimal 47
+      1,2,3,4,5,6,7,8,9,10,                       // Numbers zero through nine
+      -9,-9,-9,                                   // Decimal 58 - 60
+      -1,                                         // Equals sign at decimal 61
+      -9,-9,-9,                                   // Decimal 62 - 64
+      11,12,13,14,15,16,17,18,19,20,21,22,23,     // Letters 'A' through 'M'
+      24,25,26,27,28,29,30,31,32,33,34,35,36,     // Letters 'N' through 'Z'
+      -9,-9,-9,-9,                                // Decimal 91 - 94
+      37,                                         // Underscore at decimal 95
+      -9,                                         // Decimal 96
+      38,39,40,41,42,43,44,45,46,47,48,49,50,     // Letters 'a' through 'm'
+      51,52,53,54,55,56,57,58,59,60,61,62,63,     // Letters 'n' through 'z'
+      -9,-9,-9,-9                                 // Decimal 123 - 126
+      /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 127 - 139
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 140 - 152
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 153 - 165
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 166 - 178
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 179 - 191
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 192 - 204
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 205 - 217
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 218 - 230
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,     // Decimal 231 - 243
+        -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9         // Decimal 244 - 255 */
+    };
+
+
+/* ********  D E T E R M I N E   W H I C H   A L H A B E T  ******** */
+
+
+	/**
+	 * Returns one of the _SOMETHING_ALPHABET byte arrays depending on
+	 * the options specified.
+	 * It's possible, though silly, to specify ORDERED and URLSAFE
+	 * in which case one of them will be picked, though there is
+	 * no guarantee as to which one will be picked.
+	 */
+	private final static byte[] getAlphabet( int options )
+	{
+		if( (options & URL_SAFE) == URL_SAFE ) return _URL_SAFE_ALPHABET;
+		else if( (options & ORDERED) == ORDERED ) return _ORDERED_ALPHABET;
+		else return _STANDARD_ALPHABET;
+
+	}	// end getAlphabet
+
+
+	/**
+	 * Returns one of the _SOMETHING_DECODABET byte arrays depending on
+	 * the options specified.
+	 * It's possible, though silly, to specify ORDERED and URL_SAFE
+	 * in which case one of them will be picked, though there is
+	 * no guarantee as to which one will be picked.
+	 */
+	private final static byte[] getDecodabet( int options )
+	{
+		if( (options & URL_SAFE) == URL_SAFE ) return _URL_SAFE_DECODABET;
+		else if( (options & ORDERED) == ORDERED ) return _ORDERED_DECODABET;
+		else return _STANDARD_DECODABET;
+
+	}	// end getAlphabet
+
+
+
+    /** Defeats instantiation. */
+    private Base64(){}
+
+    /**
+     * Prints command line usage.
+     *
+     * @param msg A message to include with usage info.
+     */
+    private final static void usage( String msg )
+    {
+        System.err.println( msg );
+        System.err.println( "Usage: java Base64 -e|-d inputfile outputfile" );
+    }   // end usage
+
+
+/* ********  E N C O D I N G   M E T H O D S  ******** */
+
+
+    /**
+     * Encodes up to the first three bytes of array <var>threeBytes</var>
+     * and returns a four-byte array in Base64 notation.
+     * The actual number of significant bytes in your array is
+     * given by <var>numSigBytes</var>.
+     * The array <var>threeBytes</var> needs only be as big as
+     * <var>numSigBytes</var>.
+     * Code can reuse a byte array by passing a four-byte array as <var>b4</var>.
+     *
+     * @param b4 A reusable byte array to reduce array instantiation
+     * @param threeBytes the array to convert
+     * @param numSigBytes the number of significant bytes in your array
+     * @return four byte array in Base64 notation.
+     * @since 1.5.1
+     */
+    private static byte[] encode3to4( byte[] b4, byte[] threeBytes, int numSigBytes, int options )
+    {
+        encode3to4( threeBytes, 0, numSigBytes, b4, 0, options );
+        return b4;
+    }   // end encode3to4
+
+
+    /**
+     * <p>Encodes up to three bytes of the array <var>source</var>
+     * and writes the resulting four Base64 bytes to <var>destination</var>.
+     * The source and destination arrays can be manipulated
+     * anywhere along their length by specifying
+     * <var>srcOffset</var> and <var>destOffset</var>.
+     * This method does not check to make sure your arrays
+     * are large enough to accomodate <var>srcOffset</var> + 3 for
+     * the <var>source</var> array or <var>destOffset</var> + 4 for
+     * the <var>destination</var> array.
+     * The actual number of significant bytes in your array is
+     * given by <var>numSigBytes</var>.</p>
+	 * <p>This is the lowest level of the encoding methods with
+	 * all possible parameters.</p>
+     *
+     * @param source the array to convert
+     * @param srcOffset the index where conversion begins
+     * @param numSigBytes the number of significant bytes in your array
+     * @param destination the array to hold the conversion
+     * @param destOffset the index where output will be put
+     * @return the <var>destination</var> array
+     * @since 1.3
+     */
+    private static byte[] encode3to4(
+     byte[] source, int srcOffset, int numSigBytes,
+     byte[] destination, int destOffset, int options )
+    {
+		byte[] ALPHABET = getAlphabet( options );
+
+        //           1         2         3
+        // 01234567890123456789012345678901 Bit position
+        // --------000000001111111122222222 Array position from threeBytes
+        // --------|    ||    ||    ||    | Six bit groups to index ALPHABET
+        //          >>18  >>12  >> 6  >> 0  Right shift necessary
+        //                0x3f  0x3f  0x3f  Additional AND
+
+        // Create buffer with zero-padding if there are only one or two
+        // significant bytes passed in the array.
+        // We have to shift left 24 in order to flush out the 1's that appear
+        // when Java treats a value as negative that is cast from a byte to an int.
+        int inBuff =   ( numSigBytes > 0 ? ((source[ srcOffset     ] << 24) >>>  8) : 0 )
+                     | ( numSigBytes > 1 ? ((source[ srcOffset + 1 ] << 24) >>> 16) : 0 )
+                     | ( numSigBytes > 2 ? ((source[ srcOffset + 2 ] << 24) >>> 24) : 0 );
+
+        switch( numSigBytes )
+        {
+            case 3:
+                destination[ destOffset     ] = ALPHABET[ (inBuff >>> 18)        ];
+                destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
+                destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>>  6) & 0x3f ];
+                destination[ destOffset + 3 ] = ALPHABET[ (inBuff       ) & 0x3f ];
+                return destination;
+
+            case 2:
+                destination[ destOffset     ] = ALPHABET[ (inBuff >>> 18)        ];
+                destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
+                destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>>  6) & 0x3f ];
+                destination[ destOffset + 3 ] = EQUALS_SIGN;
+                return destination;
+
+            case 1:
+                destination[ destOffset     ] = ALPHABET[ (inBuff >>> 18)        ];
+                destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
+                destination[ destOffset + 2 ] = EQUALS_SIGN;
+                destination[ destOffset + 3 ] = EQUALS_SIGN;
+                return destination;
+
+            default:
+                return destination;
+        }   // end switch
+    }   // end encode3to4
+
+
+
+    /**
+     * Serializes an object and returns the Base64-encoded
+     * version of that serialized object. If the object
+     * cannot be serialized or there is another error,
+     * the method will return <tt>null</tt>.
+     * The object is not GZip-compressed before being encoded.
+     *
+     * @param serializableObject The object to encode
+     * @return The Base64-encoded object
+     * @since 1.4
+     */
+    public static String encodeObject( java.io.Serializable serializableObject )
+    {
+        return encodeObject( serializableObject, NO_OPTIONS );
+    }   // end encodeObject
+
+
+
+    /**
+     * Serializes an object and returns the Base64-encoded
+     * version of that serialized object. If the object
+     * cannot be serialized or there is another error,
+     * the method will return <tt>null</tt>.
+     * <p>
+     * Valid options:<pre>
+     *   GZIP: gzip-compresses object before encoding it.
+     *   DONT_BREAK_LINES: don't break lines at 76 characters
+     *     <i>Note: Technically, this makes your encoding non-compliant.</i>
+     * </pre>
+     * <p>
+     * Example: <code>encodeObject( myObj, Base64.GZIP )</code> or
+     * <p>
+     * Example: <code>encodeObject( myObj, Base64.GZIP | Base64.DONT_BREAK_LINES )</code>
+     *
+     * @param serializableObject The object to encode
+     * @param options Specified options
+     * @return The Base64-encoded object
+     * @see Base64#GZIP
+     * @see Base64#DONT_BREAK_LINES
+     * @since 2.0
+     */
+    public static String encodeObject( java.io.Serializable serializableObject, int options )
+    {
+        // Streams
+        java.io.ByteArrayOutputStream  baos  = null;
+        java.io.OutputStream           b64os = null;
+        java.io.ObjectOutputStream     oos   = null;
+        java.util.zip.GZIPOutputStream gzos  = null;
+
+        // Isolate options
+        int gzip           = (options & GZIP);
+        int dontBreakLines = (options & DONT_BREAK_LINES);
+
+        try
+        {
+            // ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream
+            baos  = new java.io.ByteArrayOutputStream();
+            b64os = new Base64.OutputStream( baos, ENCODE | options );
+
+            // GZip?
+            if( gzip == GZIP )
+            {
+                gzos = new java.util.zip.GZIPOutputStream( b64os );
+                oos  = new java.io.ObjectOutputStream( gzos );
+            }   // end if: gzip
+            else
+                oos   = new java.io.ObjectOutputStream( b64os );
+
+            oos.writeObject( serializableObject );
+        }   // end try
+        catch( java.io.IOException e )
+        {
+            e.printStackTrace();
+            return null;
+        }   // end catch
+        finally
+        {
+            try{ oos.close();   } catch( Exception e ){}
+            try{ gzos.close();  } catch( Exception e ){}
+            try{ b64os.close(); } catch( Exception e ){}
+            try{ baos.close();  } catch( Exception e ){}
+        }   // end finally
+
+        // Return value according to relevant encoding.
+        try
+        {
+            return new String( baos.toByteArray(), PREFERRED_ENCODING );
+        }   // end try
+        catch (java.io.UnsupportedEncodingException uue)
+        {
+            return new String( baos.toByteArray() );
+        }   // end catch
+
+    }   // end encode
+
+
+
+    /**
+     * Encodes a byte array into Base64 notation.
+     * Does not GZip-compress data.
+     *
+     * @param source The data to convert
+     * @since 1.4
+     */
+    public static String encodeBytes( byte[] source )
+    {
+        return encodeBytes( source, 0, source.length, NO_OPTIONS );
+    }   // end encodeBytes
+
+
+
+    /**
+     * Encodes a byte array into Base64 notation.
+     * <p>
+     * Valid options:<pre>
+     *   GZIP: gzip-compresses object before encoding it.
+     *   DONT_BREAK_LINES: don't break lines at 76 characters
+     *     <i>Note: Technically, this makes your encoding non-compliant.</i>
+     * </pre>
+     * <p>
+     * Example: <code>encodeBytes( myData, Base64.GZIP )</code> or
+     * <p>
+     * Example: <code>encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES )</code>
+     *
+     *
+     * @param source The data to convert
+     * @param options Specified options
+     * @see Base64#GZIP
+     * @see Base64#DONT_BREAK_LINES
+     * @since 2.0
+     */
+    public static String encodeBytes( byte[] source, int options )
+    {
+        return encodeBytes( source, 0, source.length, options );
+    }   // end encodeBytes
+
+
+    /**
+     * Encodes a byte array into Base64 notation.
+     * Does not GZip-compress data.
+     *
+     * @param source The data to convert
+     * @param off Offset in array where conversion should begin
+     * @param len Length of data to convert
+     * @since 1.4
+     */
+    public static String encodeBytes( byte[] source, int off, int len )
+    {
+        return encodeBytes( source, off, len, NO_OPTIONS );
+    }   // end encodeBytes
+
+
+
+    /**
+     * Encodes a byte array into Base64 notation.
+     * <p>
+     * Valid options:<pre>
+     *   GZIP: gzip-compresses object before encoding it.
+     *   DONT_BREAK_LINES: don't break lines at 76 characters
+     *     <i>Note: Technically, this makes your encoding non-compliant.</i>
+     * </pre>
+     * <p>
+     * Example: <code>encodeBytes( myData, Base64.GZIP )</code> or
+     * <p>
+     * Example: <code>encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES )</code>
+     *
+     *
+     * @param source The data to convert
+     * @param off Offset in array where conversion should begin
+     * @param len Length of data to convert
+     * @param options Specified options; alphabet type is pulled from this (standard, url-safe, ordered)
+     * @see Base64#GZIP
+     * @see Base64#DONT_BREAK_LINES
+     * @since 2.0
+     */
+    public static String encodeBytes( byte[] source, int off, int len, int options )
+    {
+        // Isolate options
+        int dontBreakLines = ( options & DONT_BREAK_LINES );
+        int gzip           = ( options & GZIP   );
+
+        // Compress?
+        if( gzip == GZIP )
+        {
+            java.io.ByteArrayOutputStream  baos  = null;
+            java.util.zip.GZIPOutputStream gzos  = null;
+            Base64.OutputStream            b64os = null;
+
+
+            try
+            {
+                // GZip -> Base64 -> ByteArray
+                baos = new java.io.ByteArrayOutputStream();
+                b64os = new Base64.OutputStream( baos, ENCODE | options );
+                gzos  = new java.util.zip.GZIPOutputStream( b64os );
+
+                gzos.write( source, off, len );
+                gzos.close();
+            }   // end try
+            catch( java.io.IOException e )
+            {
+                e.printStackTrace();
+                return null;
+            }   // end catch
+            finally
+            {
+                try{ gzos.close();  } catch( Exception e ){}
+                try{ b64os.close(); } catch( Exception e ){}
+                try{ baos.close();  } catch( Exception e ){}
+            }   // end finally
+
+            // Return value according to relevant encoding.
+            try
+            {
+                return new String( baos.toByteArray(), PREFERRED_ENCODING );
+            }   // end try
+            catch (java.io.UnsupportedEncodingException uue)
+            {
+                return new String( baos.toByteArray() );
+            }   // end catch
+        }   // end if: compress
+
+        // Else, don't compress. Better not to use streams at all then.
+        else
+        {
+            // Convert option to boolean in way that code likes it.
+            boolean breakLines = dontBreakLines == 0;
+
+            int    len43   = len * 4 / 3;
+            byte[] outBuff = new byte[   ( len43 )                      // Main 4:3
+                                       + ( (len % 3) > 0 ? 4 : 0 )      // Account for padding
+                                       + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines
+            int d = 0;
+            int e = 0;
+            int len2 = len - 2;
+            int lineLength = 0;
+            for( ; d < len2; d+=3, e+=4 )
+            {
+                encode3to4( source, d+off, 3, outBuff, e, options );
+
+                lineLength += 4;
+                if( breakLines && lineLength == MAX_LINE_LENGTH )
+                {
+                    outBuff[e+4] = NEW_LINE;
+                    e++;
+                    lineLength = 0;
+                }   // end if: end of line
+            }   // en dfor: each piece of array
+
+            if( d < len )
+            {
+                encode3to4( source, d+off, len - d, outBuff, e, options );
+                e += 4;
+            }   // end if: some padding needed
+
+
+            // Return value according to relevant encoding.
+            try
+            {
+                return new String( outBuff, 0, e, PREFERRED_ENCODING );
+            }   // end try
+            catch (java.io.UnsupportedEncodingException uue)
+            {
+                return new String( outBuff, 0, e );
+            }   // end catch
+
+        }   // end else: don't compress
+
+    }   // end encodeBytes
+
+
+
+
+
+/* ********  D E C O D I N G   M E T H O D S  ******** */
+
+
+    /**
+     * Decodes four bytes from array <var>source</var>
+     * and writes the resulting bytes (up to three of them)
+     * to <var>destination</var>.
+     * The source and destination arrays can be manipulated
+     * anywhere along their length by specifying
+     * <var>srcOffset</var> and <var>destOffset</var>.
+     * This method does not check to make sure your arrays
+     * are large enough to accomodate <var>srcOffset</var> + 4 for
+     * the <var>source</var> array or <var>destOffset</var> + 3 for
+     * the <var>destination</var> array.
+     * This method returns the actual number of bytes that
+     * were converted from the Base64 encoding.
+	 * <p>This is the lowest level of the decoding methods with
+	 * all possible parameters.</p>
+     *
+     *
+     * @param source the array to convert
+     * @param srcOffset the index where conversion begins
+     * @param destination the array to hold the conversion
+     * @param destOffset the index where output will be put
+	 * @param options alphabet type is pulled from this (standard, url-safe, ordered)
+     * @return the number of decoded bytes converted
+     * @since 1.3
+     */
+    private static int decode4to3( byte[] source, int srcOffset, byte[] destination, int destOffset, int options )
+    {
+		byte[] DECODABET = getDecodabet( options );
+
+        // Example: Dk==
+        if( source[ srcOffset + 2] == EQUALS_SIGN )
+        {
+            // Two ways to do the same thing. Don't know which way I like best.
+            //int outBuff =   ( ( DECODABET[ source[ srcOffset    ] ] << 24 ) >>>  6 )
+            //              | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 );
+            int outBuff =   ( ( DECODABET[ source[ srcOffset    ] ] & 0xFF ) << 18 )
+                          | ( ( DECODABET[ source[ srcOffset + 1] ] & 0xFF ) << 12 );
+
+            destination[ destOffset ] = (byte)( outBuff >>> 16 );
+            return 1;
+        }
+
+        // Example: DkL=
+        else if( source[ srcOffset + 3 ] == EQUALS_SIGN )
+        {
+            // Two ways to do the same thing. Don't know which way I like best.
+            //int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] << 24 ) >>>  6 )
+            //              | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
+            //              | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 );
+            int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] & 0xFF ) << 18 )
+                          | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 )
+                          | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) <<  6 );
+
+            destination[ destOffset     ] = (byte)( outBuff >>> 16 );
+            destination[ destOffset + 1 ] = (byte)( outBuff >>>  8 );
+            return 2;
+        }
+
+        // Example: DkLE
+        else
+        {
+            try{
+            // Two ways to do the same thing. Don't know which way I like best.
+            //int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] << 24 ) >>>  6 )
+            //              | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
+            //              | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 )
+            //              | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 );
+            int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] & 0xFF ) << 18 )
+                          | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 )
+                          | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) <<  6)
+                          | ( ( DECODABET[ source[ srcOffset + 3 ] ] & 0xFF )      );
+
+
+            destination[ destOffset     ] = (byte)( outBuff >> 16 );
+            destination[ destOffset + 1 ] = (byte)( outBuff >>  8 );
+            destination[ destOffset + 2 ] = (byte)( outBuff       );
+
+            return 3;
+            }catch( Exception e){
+                System.out.println(""+source[srcOffset]+ ": " + ( DECODABET[ source[ srcOffset     ] ]  ) );
+                System.out.println(""+source[srcOffset+1]+  ": " + ( DECODABET[ source[ srcOffset + 1 ] ]  ) );
+                System.out.println(""+source[srcOffset+2]+  ": " + ( DECODABET[ source[ srcOffset + 2 ] ]  ) );
+                System.out.println(""+source[srcOffset+3]+  ": " + ( DECODABET[ source[ srcOffset + 3 ] ]  ) );
+                return -1;
+            }   // end catch
+        }
+    }   // end decodeToBytes
+
+
+
+
+    /**
+     * Very low-level access to decoding ASCII characters in
+     * the form of a byte array. Does not support automatically
+     * gunzipping or any other "fancy" features.
+     *
+     * @param source The Base64 encoded data
+     * @param off    The offset of where to begin decoding
+     * @param len    The length of characters to decode
+     * @return decoded data
+     * @since 1.3
+     */
+    public static byte[] decode( byte[] source, int off, int len, int options )
+    {
+		byte[] DECODABET = getDecodabet( options );
+
+        int    len34   = len * 3 / 4;
+        byte[] outBuff = new byte[ len34 ]; // Upper limit on size of output
+        int    outBuffPosn = 0;
+
+        byte[] b4        = new byte[4];
+        int    b4Posn    = 0;
+        int    i         = 0;
+        byte   sbiCrop   = 0;
+        byte   sbiDecode = 0;
+        for( i = off; i < off+len; i++ )
+        {
+            sbiCrop = (byte)(source[i] & 0x7f); // Only the low seven bits
+            sbiDecode = DECODABET[ sbiCrop ];
+
+            if( sbiDecode >= WHITE_SPACE_ENC ) // White space, Equals sign or better
+            {
+                if( sbiDecode >= EQUALS_SIGN_ENC )
+                {
+                    b4[ b4Posn++ ] = sbiCrop;
+                    if( b4Posn > 3 )
+                    {
+                        outBuffPosn += decode4to3( b4, 0, outBuff, outBuffPosn, options );
+                        b4Posn = 0;
+
+                        // If that was the equals sign, break out of 'for' loop
+                        if( sbiCrop == EQUALS_SIGN )
+                            break;
+                    }   // end if: quartet built
+
+                }   // end if: equals sign or better
+
+            }   // end if: white space, equals sign or better
+            else
+            {
+                System.err.println( "Bad Base64 input character at " + i + ": " + source[i] + "(decimal)" );
+                return null;
+            }   // end else:
+        }   // each input character
+
+        byte[] out = new byte[ outBuffPosn ];
+        System.arraycopy( outBuff, 0, out, 0, outBuffPosn );
+        return out;
+    }   // end decode
+
+
+
+
+    /**
+     * Decodes data from Base64 notation, automatically
+     * detecting gzip-compressed data and decompressing it.
+     *
+     * @param s the string to decode
+     * @return the decoded data
+     * @since 1.4
+     */
+    public static byte[] decode( String s )
+	{
+		return decode( s, NO_OPTIONS );
+	}
+
+
+    /**
+     * Decodes data from Base64 notation, automatically
+     * detecting gzip-compressed data and decompressing it.
+     *
+     * @param s the string to decode
+	 * @param options encode options such as URL_SAFE
+     * @return the decoded data
+     * @since 1.4
+     */
+    public static byte[] decode( String s, int options )
+    {
+        byte[] bytes;
+        try
+        {
+            bytes = s.getBytes( PREFERRED_ENCODING );
+        }   // end try
+        catch( java.io.UnsupportedEncodingException uee )
+        {
+            bytes = s.getBytes();
+        }   // end catch
+		//</change>
+
+        // Decode
+        bytes = decode( bytes, 0, bytes.length, options );
+
+
+        // Check to see if it's gzip-compressed
+        // GZIP Magic Two-Byte Number: 0x8b1f (35615)
+        if( bytes != null && bytes.length >= 4 )
+        {
+
+            int head = ((int)bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00);
+            if( java.util.zip.GZIPInputStream.GZIP_MAGIC == head )
+            {
+                java.io.ByteArrayInputStream  bais = null;
+                java.util.zip.GZIPInputStream gzis = null;
+                java.io.ByteArrayOutputStream baos = null;
+                byte[] buffer = new byte[2048];
+                int    length = 0;
+
+                try
+                {
+                    baos = new java.io.ByteArrayOutputStream();
+                    bais = new java.io.ByteArrayInputStream( bytes );
+                    gzis = new java.util.zip.GZIPInputStream( bais );
+
+                    while( ( length = gzis.read( buffer ) ) >= 0 )
+                    {
+                        baos.write(buffer,0,length);
+                    }   // end while: reading input
+
+                    // No error? Get new bytes.
+                    bytes = baos.toByteArray();
+
+                }   // end try
+                catch( java.io.IOException e )
+                {
+                    // Just return originally-decoded bytes
+                }   // end catch
+                finally
+                {
+                    try{ baos.close(); } catch( Exception e ){}
+                    try{ gzis.close(); } catch( Exception e ){}
+                    try{ bais.close(); } catch( Exception e ){}
+                }   // end finally
+
+            }   // end if: gzipped
+        }   // end if: bytes.length >= 2
+
+        return bytes;
+    }   // end decode
+
+
+
+
+    /**
+     * Attempts to decode Base64 data and deserialize a Java
+     * Object within. Returns <tt>null</tt> if there was an error.
+     *
+     * @param encodedObject The Base64 data to decode
+     * @return The decoded and deserialized object
+     * @since 1.5
+     */
+    public static Object decodeToObject( String encodedObject )
+    {
+        // Decode and gunzip if necessary
+        byte[] objBytes = decode( encodedObject );
+
+        java.io.ByteArrayInputStream  bais = null;
+        java.io.ObjectInputStream     ois  = null;
+        Object obj = null;
+
+        try
+        {
+            bais = new java.io.ByteArrayInputStream( objBytes );
+            ois  = new java.io.ObjectInputStream( bais );
+
+            obj = ois.readObject();
+        }   // end try
+        catch( java.io.IOException e )
+        {
+            e.printStackTrace();
+            obj = null;
+        }   // end catch
+        catch( java.lang.ClassNotFoundException e )
+        {
+            e.printStackTrace();
+            obj = null;
+        }   // end catch
+        finally
+        {
+            try{ bais.close(); } catch( Exception e ){}
+            try{ ois.close();  } catch( Exception e ){}
+        }   // end finally
+
+        return obj;
+    }   // end decodeObject
+
+
+
+    /**
+     * Convenience method for encoding data to a file.
+     *
+     * @param dataToEncode byte array of data to encode in base64 form
+     * @param filename Filename for saving encoded data
+     * @return <tt>true</tt> if successful, <tt>false</tt> otherwise
+     *
+     * @since 2.1
+     */
+    public static boolean encodeToFile( byte[] dataToEncode, String filename )
+    {
+        boolean success = false;
+        Base64.OutputStream bos = null;
+        try
+        {
+            bos = new Base64.OutputStream(
+                      new java.io.FileOutputStream( filename ), Base64.ENCODE );
+            bos.write( dataToEncode );
+            success = true;
+        }   // end try
+        catch( java.io.IOException e )
+        {
+
+            success = false;
+        }   // end catch: IOException
+        finally
+        {
+            try{ bos.close(); } catch( Exception e ){}
+        }   // end finally
+
+        return success;
+    }   // end encodeToFile
+
+
+    /**
+     * Convenience method for decoding data to a file.
+     *
+     * @param dataToDecode Base64-encoded data as a string
+     * @param filename Filename for saving decoded data
+     * @return <tt>true</tt> if successful, <tt>false</tt> otherwise
+     *
+     * @since 2.1
+     */
+    public static boolean decodeToFile( String dataToDecode, String filename )
+    {
+        boolean success = false;
+        Base64.OutputStream bos = null;
+        try
+        {
+                bos = new Base64.OutputStream(
+                          new java.io.FileOutputStream( filename ), Base64.DECODE );
+                bos.write( dataToDecode.getBytes( PREFERRED_ENCODING ) );
+                success = true;
+        }   // end try
+        catch( java.io.IOException e )
+        {
+            success = false;
+        }   // end catch: IOException
+        finally
+        {
+                try{ bos.close(); } catch( Exception e ){}
+        }   // end finally
+
+        return success;
+    }   // end decodeToFile
+
+
+
+
+    /**
+     * Convenience method for reading a base64-encoded
+     * file and decoding it.
+     *
+     * @param filename Filename for reading encoded data
+     * @return decoded byte array or null if unsuccessful
+     *
+     * @since 2.1
+     */
+    public static byte[] decodeFromFile( String filename )
+    {
+        byte[] decodedData = null;
+        Base64.InputStream bis = null;
+        try
+        {
+            // Set up some useful variables
+            java.io.File file = new java.io.File( filename );
+            byte[] buffer = null;
+            int length   = 0;
+            int numBytes = 0;
+
+            // Check for size of file
+            if( file.length() > Integer.MAX_VALUE )
+            {
+                System.err.println( "File is too big for this convenience method (" + file.length() + " bytes)." );
+                return null;
+            }   // end if: file too big for int index
+            buffer = new byte[ (int)file.length() ];
+
+            // Open a stream
+            bis = new Base64.InputStream(
+                      new java.io.BufferedInputStream(
+                      new java.io.FileInputStream( file ) ), Base64.DECODE );
+
+            // Read until done
+            while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 )
+                length += numBytes;
+
+            // Save in a variable to return
+            decodedData = new byte[ length ];
+            System.arraycopy( buffer, 0, decodedData, 0, length );
+
+        }   // end try
+        catch( java.io.IOException e )
+        {
+            System.err.println( "Error decoding from file " + filename );
+        }   // end catch: IOException
+        finally
+        {
+            try{ bis.close(); } catch( Exception e) {}
+        }   // end finally
+
+        return decodedData;
+    }   // end decodeFromFile
+
+
+
+    /**
+     * Convenience method for reading a binary file
+     * and base64-encoding it.
+     *
+     * @param filename Filename for reading binary data
+     * @return base64-encoded string or null if unsuccessful
+     *
+     * @since 2.1
+     */
+    public static String encodeFromFile( String filename )
+    {
+        String encodedData = null;
+        Base64.InputStream bis = null;
+        try
+        {
+            // Set up some useful variables
+            java.io.File file = new java.io.File( filename );
+            byte[] buffer = new byte[ Math.max((int)(file.length() * 1.4),40) ]; // Need max() for math on small files (v2.2.1)
+            int length   = 0;
+            int numBytes = 0;
+
+            // Open a stream
+            bis = new Base64.InputStream(
+                      new java.io.BufferedInputStream(
+                      new java.io.FileInputStream( file ) ), Base64.ENCODE );
+
+            // Read until done
+            while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 )
+                length += numBytes;
+
+            // Save in a variable to return
+            encodedData = new String( buffer, 0, length, Base64.PREFERRED_ENCODING );
+
+        }   // end try
+        catch( java.io.IOException e )
+        {
+            System.err.println( "Error encoding from file " + filename );
+        }   // end catch: IOException
+        finally
+        {
+            try{ bis.close(); } catch( Exception e) {}
+        }   // end finally
+
+        return encodedData;
+        }   // end encodeFromFile
+
+    /**
+     * Reads <tt>infile</tt> and encodes it to <tt>outfile</tt>.
+     *
+     * @param infile Input file
+     * @param outfile Output file
+     * @since 2.2
+     */
+    public static void encodeFileToFile( String infile, String outfile )
+    {
+        String encoded = Base64.encodeFromFile( infile );
+        java.io.OutputStream out = null;
+        try{
+            out = new java.io.BufferedOutputStream(
+                  new java.io.FileOutputStream( outfile ) );
+            out.write( encoded.getBytes("US-ASCII") ); // Strict, 7-bit output.
+        }   // end try
+        catch( java.io.IOException ex ) {
+            ex.printStackTrace();
+        }   // end catch
+        finally {
+            try { out.close(); }
+            catch( Exception ex ){}
+        }   // end finally
+    }   // end encodeFileToFile
+
+
+    /**
+     * Reads <tt>infile</tt> and decodes it to <tt>outfile</tt>.
+     *
+     * @param infile Input file
+     * @param outfile Output file
+     * @since 2.2
+     */
+    public static void decodeFileToFile( String infile, String outfile )
+    {
+        byte[] decoded = Base64.decodeFromFile( infile );
+        java.io.OutputStream out = null;
+        try{
+            out = new java.io.BufferedOutputStream(
+                  new java.io.FileOutputStream( outfile ) );
+            out.write( decoded );
+        }   // end try
+        catch( java.io.IOException ex ) {
+            ex.printStackTrace();
+        }   // end catch
+        finally {
+            try { out.close(); }
+            catch( Exception ex ){}
+        }   // end finally
+    }   // end decodeFileToFile
+
+
+    /* ********  I N N E R   C L A S S   I N P U T S T R E A M  ******** */
+
+
+
+    /**
+     * A {@link Base64.InputStream} will read data from another
+     * <tt>java.io.InputStream</tt>, given in the constructor,
+     * and encode/decode to/from Base64 notation on the fly.
+     *
+     * @see Base64
+     * @since 1.3
+     */
+    public static class InputStream extends java.io.FilterInputStream
+    {
+        private boolean encode;         // Encoding or decoding
+        private int     position;       // Current position in the buffer
+        private byte[]  buffer;         // Small buffer holding converted data
+        private int     bufferLength;   // Length of buffer (3 or 4)
+        private int     numSigBytes;    // Number of meaningful bytes in the buffer
+        private int     lineLength;
+        private boolean breakLines;     // Break lines at less than 80 characters
+		private int     options;        // Record options used to create the stream.
+		private byte[]  alphabet;	    // Local copies to avoid extra method calls
+		private byte[]  decodabet;		// Local copies to avoid extra method calls
+
+
+        /**
+         * Constructs a {@link Base64.InputStream} in DECODE mode.
+         *
+         * @param in the <tt>java.io.InputStream</tt> from which to read data.
+         * @since 1.3
+         */
+        public InputStream( java.io.InputStream in )
+        {
+            this( in, DECODE );
+        }   // end constructor
+
+
+        /**
+         * Constructs a {@link Base64.InputStream} in
+         * either ENCODE or DECODE mode.
+         * <p>
+         * Valid options:<pre>
+         *   ENCODE or DECODE: Encode or Decode as data is read.
+         *   DONT_BREAK_LINES: don't break lines at 76 characters
+         *     (only meaningful when encoding)
+         *     <i>Note: Technically, this makes your encoding non-compliant.</i>
+         * </pre>
+         * <p>
+         * Example: <code>new Base64.InputStream( in, Base64.DECODE )</code>
+         *
+         *
+         * @param in the <tt>java.io.InputStream</tt> from which to read data.
+         * @param options Specified options
+         * @see Base64#ENCODE
+         * @see Base64#DECODE
+         * @see Base64#DONT_BREAK_LINES
+         * @since 2.0
+         */
+        public InputStream( java.io.InputStream in, int options )
+        {
+            super( in );
+            this.breakLines   = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES;
+            this.encode       = (options & ENCODE) == ENCODE;
+            this.bufferLength = encode ? 4 : 3;
+            this.buffer       = new byte[ bufferLength ];
+            this.position     = -1;
+            this.lineLength   = 0;
+			this.options      = options; // Record for later, mostly to determine which alphabet to use
+			this.alphabet     = getAlphabet(options);
+			this.decodabet    = getDecodabet(options);
+        }   // end constructor
+
+        /**
+         * Reads enough of the input stream to convert
+         * to/from Base64 and returns the next byte.
+         *
+         * @return next byte
+         * @since 1.3
+         */
+        public int read() throws java.io.IOException
+        {
+            // Do we need to get data?
+            if( position < 0 )
+            {
+                if( encode )
+                {
+                    byte[] b3 = new byte[3];
+                    int numBinaryBytes = 0;
+                    for( int i = 0; i < 3; i++ )
+                    {
+                        try
+                        {
+                            int b = in.read();
+
+                            // If end of stream, b is -1.
+                            if( b >= 0 )
+                            {
+                                b3[i] = (byte)b;
+                                numBinaryBytes++;
+                            }   // end if: not end of stream
+
+                        }   // end try: read
+                        catch( java.io.IOException e )
+                        {
+                            // Only a problem if we got no data at all.
+                            if( i == 0 )
+                                throw e;
+
+                        }   // end catch
+                    }   // end for: each needed input byte
+
+                    if( numBinaryBytes > 0 )
+                    {
+                        encode3to4( b3, 0, numBinaryBytes, buffer, 0, options );
+                        position = 0;
+                        numSigBytes = 4;
+                    }   // end if: got data
+                    else
+                    {
+                        return -1;
+                    }   // end else
+                }   // end if: encoding
+
+                // Else decoding
+                else
+                {
+                    byte[] b4 = new byte[4];
+                    int i = 0;
+                    for( i = 0; i < 4; i++ )
+                    {
+                        // Read four "meaningful" bytes:
+                        int b = 0;
+                        do{ b = in.read(); }
+                        while( b >= 0 && decodabet[ b & 0x7f ] <= WHITE_SPACE_ENC );
+
+                        if( b < 0 )
+                            break; // Reads a -1 if end of stream
+
+                        b4[i] = (byte)b;
+                    }   // end for: each needed input byte
+
+                    if( i == 4 )
+                    {
+                        numSigBytes = decode4to3( b4, 0, buffer, 0, options );
+                        position = 0;
+                    }   // end if: got four characters
+                    else if( i == 0 ){
+                        return -1;
+                    }   // end else if: also padded correctly
+                    else
+                    {
+                        // Must have broken out from above.
+                        throw new java.io.IOException( "Improperly padded Base64 input." );
+                    }   // end
+
+                }   // end else: decode
+            }   // end else: get data
+
+            // Got data?
+            if( position >= 0 )
+            {
+                // End of relevant data?
+                if( /*!encode &&*/ position >= numSigBytes )
+                    return -1;
+
+                if( encode && breakLines && lineLength >= MAX_LINE_LENGTH )
+                {
+                    lineLength = 0;
+                    return '\n';
+                }   // end if
+                else
+                {
+                    lineLength++;   // This isn't important when decoding
+                                    // but throwing an extra "if" seems
+                                    // just as wasteful.
+
+                    int b = buffer[ position++ ];
+
+                    if( position >= bufferLength )
+                        position = -1;
+
+                    return b & 0xFF; // This is how you "cast" a byte that's
+                                     // intended to be unsigned.
+                }   // end else
+            }   // end if: position >= 0
+
+            // Else error
+            else
+            {
+                // When JDK1.4 is more accepted, use an assertion here.
+                throw new java.io.IOException( "Error in Base64 code reading stream." );
+            }   // end else
+        }   // end read
+
+
+        /**
+         * Calls {@link #read()} repeatedly until the end of stream
+         * is reached or <var>len</var> bytes are read.
+         * Returns number of bytes read into array or -1 if
+         * end of stream is encountered.
+         *
+         * @param dest array to hold values
+         * @param off offset for array
+         * @param len max number of bytes to read into array
+         * @return bytes read into array or -1 if end of stream is encountered.
+         * @since 1.3
+         */
+        public int read( byte[] dest, int off, int len ) throws java.io.IOException
+        {
+            int i;
+            int b;
+            for( i = 0; i < len; i++ )
+            {
+                b = read();
+
+                //if( b < 0 && i == 0 )
+                //    return -1;
+
+                if( b >= 0 )
+                    dest[off + i] = (byte)b;
+                else if( i == 0 )
+                    return -1;
+                else
+                    break; // Out of 'for' loop
+            }   // end for: each byte read
+            return i;
+        }   // end read
+
+    }   // end inner class InputStream
+
+
+
+
+
+
+    /* ********  I N N E R   C L A S S   O U T P U T S T R E A M  ******** */
+
+
+
+    /**
+     * A {@link Base64.OutputStream} will write data to another
+     * <tt>java.io.OutputStream</tt>, given in the constructor,
+     * and encode/decode to/from Base64 notation on the fly.
+     *
+     * @see Base64
+     * @since 1.3
+     */
+    public static class OutputStream extends java.io.FilterOutputStream
+    {
+        private boolean encode;
+        private int     position;
+        private byte[]  buffer;
+        private int     bufferLength;
+        private int     lineLength;
+        private boolean breakLines;
+        private byte[]  b4; // Scratch used in a few places
+        private boolean suspendEncoding;
+		private int options; // Record for later
+		private byte[]  alphabet;	    // Local copies to avoid extra method calls
+		private byte[]  decodabet;		// Local copies to avoid extra method calls
+
+        /**
+         * Constructs a {@link Base64.OutputStream} in ENCODE mode.
+         *
+         * @param out the <tt>java.io.OutputStream</tt> to which data will be written.
+         * @since 1.3
+         */
+        public OutputStream( java.io.OutputStream out )
+        {
+            this( out, ENCODE );
+        }   // end constructor
+
+
+        /**
+         * Constructs a {@link Base64.OutputStream} in
+         * either ENCODE or DECODE mode.
+         * <p>
+         * Valid options:<pre>
+         *   ENCODE or DECODE: Encode or Decode as data is read.
+         *   DONT_BREAK_LINES: don't break lines at 76 characters
+         *     (only meaningful when encoding)
+         *     <i>Note: Technically, this makes your encoding non-compliant.</i>
+         * </pre>
+         * <p>
+         * Example: <code>new Base64.OutputStream( out, Base64.ENCODE )</code>
+         *
+         * @param out the <tt>java.io.OutputStream</tt> to which data will be written.
+         * @param options Specified options.
+         * @see Base64#ENCODE
+         * @see Base64#DECODE
+         * @see Base64#DONT_BREAK_LINES
+         * @since 1.3
+         */
+        public OutputStream( java.io.OutputStream out, int options )
+        {
+            super( out );
+            this.breakLines   = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES;
+            this.encode       = (options & ENCODE) == ENCODE;
+            this.bufferLength = encode ? 3 : 4;
+            this.buffer       = new byte[ bufferLength ];
+            this.position     = 0;
+            this.lineLength   = 0;
+            this.suspendEncoding = false;
+            this.b4           = new byte[4];
+			this.options      = options;
+			this.alphabet     = getAlphabet(options);
+			this.decodabet    = getDecodabet(options);
+        }   // end constructor
+
+
+        /**
+         * Writes the byte to the output stream after
+         * converting to/from Base64 notation.
+         * When encoding, bytes are buffered three
+         * at a time before the output stream actually
+         * gets a write() call.
+         * When decoding, bytes are buffered four
+         * at a time.
+         *
+         * @param theByte the byte to write
+         * @since 1.3
+         */
+        public void write(int theByte) throws java.io.IOException
+        {
+            // Encoding suspended?
+            if( suspendEncoding )
+            {
+                super.out.write( theByte );
+                return;
+            }   // end if: supsended
+
+            // Encode?
+            if( encode )
+            {
+                buffer[ position++ ] = (byte)theByte;
+                if( position >= bufferLength )  // Enough to encode.
+                {
+                    out.write( encode3to4( b4, buffer, bufferLength, options ) );
+
+                    lineLength += 4;
+                    if( breakLines && lineLength >= MAX_LINE_LENGTH )
+                    {
+                        out.write( NEW_LINE );
+                        lineLength = 0;
+                    }   // end if: end of line
+
+                    position = 0;
+                }   // end if: enough to output
+            }   // end if: encoding
+
+            // Else, Decoding
+            else
+            {
+                // Meaningful Base64 character?
+                if( decodabet[ theByte & 0x7f ] > WHITE_SPACE_ENC )
+                {
+                    buffer[ position++ ] = (byte)theByte;
+                    if( position >= bufferLength )  // Enough to output.
+                    {
+                        int len = Base64.decode4to3( buffer, 0, b4, 0, options );
+                        out.write( b4, 0, len );
+                        //out.write( Base64.decode4to3( buffer ) );
+                        position = 0;
+                    }   // end if: enough to output
+                }   // end if: meaningful base64 character
+                else if( decodabet[ theByte & 0x7f ] != WHITE_SPACE_ENC )
+                {
+                    throw new java.io.IOException( "Invalid character in Base64 data." );
+                }   // end else: not white space either
+            }   // end else: decoding
+        }   // end write
+
+
+
+        /**
+         * Calls {@link #write(int)} repeatedly until <var>len</var>
+         * bytes are written.
+         *
+         * @param theBytes array from which to read bytes
+         * @param off offset for array
+         * @param len max number of bytes to read into array
+         * @since 1.3
+         */
+        public void write( byte[] theBytes, int off, int len ) throws java.io.IOException
+        {
+            // Encoding suspended?
+            if( suspendEncoding )
+            {
+                super.out.write( theBytes, off, len );
+                return;
+            }   // end if: supsended
+
+            for( int i = 0; i < len; i++ )
+            {
+                write( theBytes[ off + i ] );
+            }   // end for: each byte written
+
+        }   // end write
+
+
+
+        /**
+         * Method added by PHIL. [Thanks, PHIL. -Rob]
+         * This pads the buffer without closing the stream.
+         */
+        public void flushBase64() throws java.io.IOException
+        {
+            if( position > 0 )
+            {
+                if( encode )
+                {
+                    out.write( encode3to4( b4, buffer, position, options ) );
+                    position = 0;
+                }   // end if: encoding
+                else
+                {
+                    throw new java.io.IOException( "Base64 input not properly padded." );
+                }   // end else: decoding
+            }   // end if: buffer partially full
+
+        }   // end flush
+
+
+        /**
+         * Flushes and closes (I think, in the superclass) the stream.
+         *
+         * @since 1.3
+         */
+        public void close() throws java.io.IOException
+        {
+            // 1. Ensure that pending characters are written
+            flushBase64();
+
+            // 2. Actually close the stream
+            // Base class both flushes and closes.
+            super.close();
+
+            buffer = null;
+            out    = null;
+        }   // end close
+
+
+
+        /**
+         * Suspends encoding of the stream.
+         * May be helpful if you need to embed a piece of
+         * base640-encoded data in a stream.
+         *
+         * @since 1.5.1
+         */
+        public void suspendEncoding() throws java.io.IOException
+        {
+            flushBase64();
+            this.suspendEncoding = true;
+        }   // end suspendEncoding
+
+
+        /**
+         * Resumes encoding of the stream.
+         * May be helpful if you need to embed a piece of
+         * base640-encoded data in a stream.
+         *
+         * @since 1.5.1
+         */
+        public void resumeEncoding()
+        {
+            this.suspendEncoding = false;
+        }   // end resumeEncoding
+
+
+
+    }   // end inner class OutputStream
+
+
+}   // end class Base64
+
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/SyncPacketSend.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/SyncPacketSend.java
index 6506cbd..58cf1f8 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/SyncPacketSend.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/SyncPacketSend.java
@@ -1,64 +1,64 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smack.util;
-
-import org.jivesoftware.smack.PacketCollector;
-import org.jivesoftware.smack.SmackConfiguration;
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.SmackError;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.filter.PacketFilter;
-import org.jivesoftware.smack.filter.PacketIDFilter;
-import org.jivesoftware.smack.packet.Packet;
-
-/**
- * Utility class for doing synchronous calls to the server.  Provides several
- * methods for sending a packet to the server and waiting for the reply.
- * 
- * @author Robin Collier
- */
-final public class SyncPacketSend
-{
-	private SyncPacketSend()
-	{	}
-	
-	static public Packet getReply(Connection connection, Packet packet, long timeout)
-		throws XMPPException
-	{
-        PacketFilter responseFilter = new PacketIDFilter(packet.getPacketID());
-        PacketCollector response = connection.createPacketCollector(responseFilter);
-        
-        connection.sendPacket(packet);
-
-        // Wait up to a certain number of seconds for a reply.
-        Packet result = response.nextResult(timeout);
-
-        // Stop queuing results
-        response.cancel();
-
-        if (result == null) {
-            throw new XMPPException(SmackError.NO_RESPONSE_FROM_SERVER);
-        }
-        else if (result.getError() != null) {
-            throw new XMPPException(result.getError());
-        }
-        return result;
-	}
-
-	static public Packet getReply(Connection connection, Packet packet)
-		throws XMPPException
-	{
-		return getReply(connection, packet, SmackConfiguration.getPacketReplyTimeout());
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smack.util;
+
+import org.jivesoftware.smack.PacketCollector;
+import org.jivesoftware.smack.SmackConfiguration;
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.SmackError;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.filter.PacketIDFilter;
+import org.jivesoftware.smack.packet.Packet;
+
+/**
+ * Utility class for doing synchronous calls to the server.  Provides several
+ * methods for sending a packet to the server and waiting for the reply.
+ * 
+ * @author Robin Collier
+ */
+final public class SyncPacketSend
+{
+	private SyncPacketSend()
+	{	}
+	
+	static public Packet getReply(Connection connection, Packet packet, long timeout)
+		throws XMPPException
+	{
+        PacketFilter responseFilter = new PacketIDFilter(packet.getPacketID());
+        PacketCollector response = connection.createPacketCollector(responseFilter);
+        
+        connection.sendPacket(packet);
+
+        // Wait up to a certain number of seconds for a reply.
+        Packet result = response.nextResult(timeout);
+
+        // Stop queuing results
+        response.cancel();
+
+        if (result == null) {
+            throw new XMPPException(SmackError.NO_RESPONSE_FROM_SERVER);
+        }
+        else if (result.getError() != null) {
+            throw new XMPPException(result.getError());
+        }
+        return result;
+	}
+
+	static public Packet getReply(Connection connection, Packet packet)
+		throws XMPPException
+	{
+		return getReply(connection, packet, SmackConfiguration.getPacketReplyTimeout());
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/LastActivityManager.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/LastActivityManager.java
index a9d1f12..7729bc0 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/LastActivityManager.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/LastActivityManager.java
@@ -1,230 +1,230 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2006 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx;
-
-import org.jivesoftware.smack.*;
-import org.jivesoftware.smack.filter.AndFilter;
-import org.jivesoftware.smack.filter.IQTypeFilter;
-import org.jivesoftware.smack.filter.PacketIDFilter;
-import org.jivesoftware.smack.filter.PacketTypeFilter;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Message;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smack.packet.Presence;
-import org.jivesoftware.smackx.packet.DiscoverInfo;
-import org.jivesoftware.smackx.packet.LastActivity;
-
-/**
- * A last activity manager for handling information about the last activity
- * associated with a Jabber ID. A manager handles incoming LastActivity requests
- * of existing Connections. It also allows to request last activity information
- * of other users.
- * <p>
- * 
- * LastActivity (XEP-0012) based on the sending JID's type allows for retrieval
- * of:
- * <ol>
- * <li>How long a particular user has been idle
- * <li>How long a particular user has been logged-out and the message the
- * specified when doing so.
- * <li>How long a host has been up.
- * </ol>
- * <p/>
- * 
- * For example to get the idle time of a user logged in a resource, simple send
- * the LastActivity packet to them, as in the following code:
- * <p>
- * 
- * <pre>
- * Connection con = new XMPPConnection(&quot;jabber.org&quot;);
- * con.login(&quot;john&quot;, &quot;doe&quot;);
- * LastActivity activity = LastActivity.getLastActivity(con, &quot;xray@jabber.org/Smack&quot;);
- * </pre>
- * 
- * To get the lapsed time since the last user logout is the same as above but
- * with out the resource:
- * 
- * <pre>
- * LastActivity activity = LastActivity.getLastActivity(con, &quot;xray@jabber.org&quot;);
- * </pre>
- * 
- * To get the uptime of a host, you simple send the LastActivity packet to it,
- * as in the following code example:
- * <p>
- * 
- * <pre>
- * LastActivity activity = LastActivity.getLastActivity(con, &quot;jabber.org&quot;);
- * </pre>
- * 
- * @author Gabriel Guardincerri
- * @see <a href="http://xmpp.org/extensions/xep-0012.html">XEP-0012: Last
- *      Activity</a>
- */
-
-public class LastActivityManager {
-
-    private long lastMessageSent;
-
-    private Connection connection;
-
-    // Enable the LastActivity support on every established connection
-    static {
-        Connection.addConnectionCreationListener(new ConnectionCreationListener() {
-            public void connectionCreated(Connection connection) {
-                new LastActivityManager(connection);
-            }
-        });
-    }
-
-    /**
-     * Creates a last activity manager to response last activity requests.
-     * 
-     * @param connection
-     *            The Connection that the last activity requests will use.
-     */
-    private LastActivityManager(Connection connection) {
-        this.connection = connection;
-
-        // Listen to all the sent messages to reset the idle time on each one
-        connection.addPacketSendingListener(new PacketListener() {
-            public void processPacket(Packet packet) {
-                Presence presence = (Presence) packet;
-                Presence.Mode mode = presence.getMode();
-                if (mode == null) return;
-                switch (mode) {
-                case available:
-                case chat:
-                    // We assume that only a switch to available and chat indicates user activity
-                    // since other mode changes could be also a result of some sort of automatism
-                    resetIdleTime();
-                }
-            }
-        }, new PacketTypeFilter(Presence.class));
-
-        connection.addPacketListener(new PacketListener() {
-            @Override
-            public void processPacket(Packet packet) {
-                Message message = (Message) packet;
-                // if it's not an error message, reset the idle time
-                if (message.getType() == Message.Type.error) return;
-                resetIdleTime();
-            }
-        }, new PacketTypeFilter(Message.class));
-
-        // Register a listener for a last activity query
-        connection.addPacketListener(new PacketListener() {
-
-            public void processPacket(Packet packet) {
-                LastActivity message = new LastActivity();
-                message.setType(IQ.Type.RESULT);
-                message.setTo(packet.getFrom());
-                message.setFrom(packet.getTo());
-                message.setPacketID(packet.getPacketID());
-                message.setLastActivity(getIdleTime());
-
-                LastActivityManager.this.connection.sendPacket(message);
-            }
-
-        }, new AndFilter(new IQTypeFilter(IQ.Type.GET), new PacketTypeFilter(LastActivity.class)));
-        ServiceDiscoveryManager.getInstanceFor(connection).addFeature(LastActivity.NAMESPACE);
-        resetIdleTime();
-    }
-
-    /**
-     * Resets the idle time to 0, this should be invoked when a new message is
-     * sent.
-     */
-    private void resetIdleTime() {
-        long now = System.currentTimeMillis();
-        synchronized (this) {
-            lastMessageSent = now;
-        }
-    }
-
-    /**
-     * The idle time is the lapsed time between the last message sent and now.
-     * 
-     * @return the lapsed time between the last message sent and now.
-     */
-    private long getIdleTime() {
-        long lms;
-        long now = System.currentTimeMillis();
-        synchronized (this) {
-            lms = lastMessageSent;
-        }
-        return ((now - lms) / 1000);
-    }
-
-    /**
-     * Returns the last activity of a particular jid. If the jid is a full JID
-     * (i.e., a JID of the form of 'user@host/resource') then the last activity
-     * is the idle time of that connected resource. On the other hand, when the
-     * jid is a bare JID (e.g. 'user@host') then the last activity is the lapsed
-     * time since the last logout or 0 if the user is currently logged in.
-     * Moreover, when the jid is a server or component (e.g., a JID of the form
-     * 'host') the last activity is the uptime.
-     * 
-     * @param con
-     *            the current Connection.
-     * @param jid
-     *            the JID of the user.
-     * @return the LastActivity packet of the jid.
-     * @throws XMPPException
-     *             thrown if a server error has occured.
-     */
-    public static LastActivity getLastActivity(Connection con, String jid) throws XMPPException {
-        LastActivity activity = new LastActivity();
-        activity.setTo(jid);
-
-        PacketCollector collector = con.createPacketCollector(new PacketIDFilter(activity.getPacketID()));
-        con.sendPacket(activity);
-
-        LastActivity response = (LastActivity) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server on status set.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response;
-    }
-
-    /**
-     * Returns true if Last Activity (XEP-0012) is supported by a given JID
-     * 
-     * @param connection the connection to be used
-     * @param jid a JID to be tested for Last Activity support
-     * @return true if Last Activity is supported, otherwise false
-     */
-    public static boolean isLastActivitySupported(Connection connection, String jid) {
-        try {
-            DiscoverInfo result =
-                ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(jid);
-            return result.containsFeature(LastActivity.NAMESPACE);
-        }
-        catch (XMPPException e) {
-            return false;
-        }
-    }
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2006 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx;
+
+import org.jivesoftware.smack.*;
+import org.jivesoftware.smack.filter.AndFilter;
+import org.jivesoftware.smack.filter.IQTypeFilter;
+import org.jivesoftware.smack.filter.PacketIDFilter;
+import org.jivesoftware.smack.filter.PacketTypeFilter;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Message;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.packet.Presence;
+import org.jivesoftware.smackx.packet.DiscoverInfo;
+import org.jivesoftware.smackx.packet.LastActivity;
+
+/**
+ * A last activity manager for handling information about the last activity
+ * associated with a Jabber ID. A manager handles incoming LastActivity requests
+ * of existing Connections. It also allows to request last activity information
+ * of other users.
+ * <p>
+ * 
+ * LastActivity (XEP-0012) based on the sending JID's type allows for retrieval
+ * of:
+ * <ol>
+ * <li>How long a particular user has been idle
+ * <li>How long a particular user has been logged-out and the message the
+ * specified when doing so.
+ * <li>How long a host has been up.
+ * </ol>
+ * <p/>
+ * 
+ * For example to get the idle time of a user logged in a resource, simple send
+ * the LastActivity packet to them, as in the following code:
+ * <p>
+ * 
+ * <pre>
+ * Connection con = new XMPPConnection(&quot;jabber.org&quot;);
+ * con.login(&quot;john&quot;, &quot;doe&quot;);
+ * LastActivity activity = LastActivity.getLastActivity(con, &quot;xray@jabber.org/Smack&quot;);
+ * </pre>
+ * 
+ * To get the lapsed time since the last user logout is the same as above but
+ * with out the resource:
+ * 
+ * <pre>
+ * LastActivity activity = LastActivity.getLastActivity(con, &quot;xray@jabber.org&quot;);
+ * </pre>
+ * 
+ * To get the uptime of a host, you simple send the LastActivity packet to it,
+ * as in the following code example:
+ * <p>
+ * 
+ * <pre>
+ * LastActivity activity = LastActivity.getLastActivity(con, &quot;jabber.org&quot;);
+ * </pre>
+ * 
+ * @author Gabriel Guardincerri
+ * @see <a href="http://xmpp.org/extensions/xep-0012.html">XEP-0012: Last
+ *      Activity</a>
+ */
+
+public class LastActivityManager {
+
+    private long lastMessageSent;
+
+    private Connection connection;
+
+    // Enable the LastActivity support on every established connection
+    static {
+        Connection.addConnectionCreationListener(new ConnectionCreationListener() {
+            public void connectionCreated(Connection connection) {
+                new LastActivityManager(connection);
+            }
+        });
+    }
+
+    /**
+     * Creates a last activity manager to response last activity requests.
+     * 
+     * @param connection
+     *            The Connection that the last activity requests will use.
+     */
+    private LastActivityManager(Connection connection) {
+        this.connection = connection;
+
+        // Listen to all the sent messages to reset the idle time on each one
+        connection.addPacketSendingListener(new PacketListener() {
+            public void processPacket(Packet packet) {
+                Presence presence = (Presence) packet;
+                Presence.Mode mode = presence.getMode();
+                if (mode == null) return;
+                switch (mode) {
+                case available:
+                case chat:
+                    // We assume that only a switch to available and chat indicates user activity
+                    // since other mode changes could be also a result of some sort of automatism
+                    resetIdleTime();
+                }
+            }
+        }, new PacketTypeFilter(Presence.class));
+
+        connection.addPacketListener(new PacketListener() {
+            @Override
+            public void processPacket(Packet packet) {
+                Message message = (Message) packet;
+                // if it's not an error message, reset the idle time
+                if (message.getType() == Message.Type.error) return;
+                resetIdleTime();
+            }
+        }, new PacketTypeFilter(Message.class));
+
+        // Register a listener for a last activity query
+        connection.addPacketListener(new PacketListener() {
+
+            public void processPacket(Packet packet) {
+                LastActivity message = new LastActivity();
+                message.setType(IQ.Type.RESULT);
+                message.setTo(packet.getFrom());
+                message.setFrom(packet.getTo());
+                message.setPacketID(packet.getPacketID());
+                message.setLastActivity(getIdleTime());
+
+                LastActivityManager.this.connection.sendPacket(message);
+            }
+
+        }, new AndFilter(new IQTypeFilter(IQ.Type.GET), new PacketTypeFilter(LastActivity.class)));
+        ServiceDiscoveryManager.getInstanceFor(connection).addFeature(LastActivity.NAMESPACE);
+        resetIdleTime();
+    }
+
+    /**
+     * Resets the idle time to 0, this should be invoked when a new message is
+     * sent.
+     */
+    private void resetIdleTime() {
+        long now = System.currentTimeMillis();
+        synchronized (this) {
+            lastMessageSent = now;
+        }
+    }
+
+    /**
+     * The idle time is the lapsed time between the last message sent and now.
+     * 
+     * @return the lapsed time between the last message sent and now.
+     */
+    private long getIdleTime() {
+        long lms;
+        long now = System.currentTimeMillis();
+        synchronized (this) {
+            lms = lastMessageSent;
+        }
+        return ((now - lms) / 1000);
+    }
+
+    /**
+     * Returns the last activity of a particular jid. If the jid is a full JID
+     * (i.e., a JID of the form of 'user@host/resource') then the last activity
+     * is the idle time of that connected resource. On the other hand, when the
+     * jid is a bare JID (e.g. 'user@host') then the last activity is the lapsed
+     * time since the last logout or 0 if the user is currently logged in.
+     * Moreover, when the jid is a server or component (e.g., a JID of the form
+     * 'host') the last activity is the uptime.
+     * 
+     * @param con
+     *            the current Connection.
+     * @param jid
+     *            the JID of the user.
+     * @return the LastActivity packet of the jid.
+     * @throws XMPPException
+     *             thrown if a server error has occured.
+     */
+    public static LastActivity getLastActivity(Connection con, String jid) throws XMPPException {
+        LastActivity activity = new LastActivity();
+        activity.setTo(jid);
+
+        PacketCollector collector = con.createPacketCollector(new PacketIDFilter(activity.getPacketID()));
+        con.sendPacket(activity);
+
+        LastActivity response = (LastActivity) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server on status set.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response;
+    }
+
+    /**
+     * Returns true if Last Activity (XEP-0012) is supported by a given JID
+     * 
+     * @param connection the connection to be used
+     * @param jid a JID to be tested for Last Activity support
+     * @return true if Last Activity is supported, otherwise false
+     */
+    public static boolean isLastActivitySupported(Connection connection, String jid) {
+        try {
+            DiscoverInfo result =
+                ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(jid);
+            return result.containsFeature(LastActivity.NAMESPACE);
+        }
+        catch (XMPPException e) {
+            return false;
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/SharedGroupManager.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/SharedGroupManager.java
index 76cd527..44ab670 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/SharedGroupManager.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/SharedGroupManager.java
@@ -17,56 +17,56 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jivesoftware.smackx;
-
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.PacketCollector;
-import org.jivesoftware.smack.SmackConfiguration;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.filter.PacketIDFilter;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smackx.packet.SharedGroupsInfo;
-
-import java.util.List;
-
-/**
- * A SharedGroupManager provides services for discovering the shared groups where a user belongs.<p>
- *
- * Important note: This functionality is not part of the XMPP spec and it will only work
- * with Wildfire.
- *
- * @author Gaston Dombiak
- */
-public class SharedGroupManager {
-
-    /**
-     * Returns the collection that will contain the name of the shared groups where the user
-     * logged in with the specified session belongs.
-     *
-     * @param connection connection to use to get the user's shared groups.
-     * @return collection with the shared groups' name of the logged user.
-     */
-    public static List<String> getSharedGroups(Connection connection) throws XMPPException {
-        // Discover the shared groups of the logged user
-        SharedGroupsInfo info = new SharedGroupsInfo();
-        info.setType(IQ.Type.GET);
-
-        // Create a packet collector to listen for a response.
-        PacketCollector collector =
-            connection.createPacketCollector(new PacketIDFilter(info.getPacketID()));
-
-        connection.sendPacket(info);
-
-        // Wait up to 5 seconds for a result.
-        IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-        // Stop queuing results
-        collector.cancel();
-        if (result == null) {
-            throw new XMPPException("No response from the server.");
-        }
-        if (result.getType() == IQ.Type.ERROR) {
-            throw new XMPPException(result.getError());
-        }
-        return ((SharedGroupsInfo) result).getGroups();
-    }
-}
+package org.jivesoftware.smackx;
+
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.PacketCollector;
+import org.jivesoftware.smack.SmackConfiguration;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.filter.PacketIDFilter;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smackx.packet.SharedGroupsInfo;
+
+import java.util.List;
+
+/**
+ * A SharedGroupManager provides services for discovering the shared groups where a user belongs.<p>
+ *
+ * Important note: This functionality is not part of the XMPP spec and it will only work
+ * with Wildfire.
+ *
+ * @author Gaston Dombiak
+ */
+public class SharedGroupManager {
+
+    /**
+     * Returns the collection that will contain the name of the shared groups where the user
+     * logged in with the specified session belongs.
+     *
+     * @param connection connection to use to get the user's shared groups.
+     * @return collection with the shared groups' name of the logged user.
+     */
+    public static List<String> getSharedGroups(Connection connection) throws XMPPException {
+        // Discover the shared groups of the logged user
+        SharedGroupsInfo info = new SharedGroupsInfo();
+        info.setType(IQ.Type.GET);
+
+        // Create a packet collector to listen for a response.
+        PacketCollector collector =
+            connection.createPacketCollector(new PacketIDFilter(info.getPacketID()));
+
+        connection.sendPacket(info);
+
+        // Wait up to 5 seconds for a result.
+        IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+        // Stop queuing results
+        collector.cancel();
+        if (result == null) {
+            throw new XMPPException("No response from the server.");
+        }
+        if (result.getType() == IQ.Type.ERROR) {
+            throw new XMPPException(result.getError());
+        }
+        return ((SharedGroupsInfo) result).getGroups();
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/BytestreamListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/BytestreamListener.java
index be78255..87ab2f5 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/BytestreamListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/BytestreamListener.java
@@ -1,47 +1,47 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams;
-
-import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamListener;
-import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
-import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamListener;
-import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager;
-
-/**
- * BytestreamListener are notified if a remote user wants to initiate a bytestream. Implement this
- * interface to handle incoming bytestream requests.
- * <p>
- * BytestreamListener can be registered at the {@link Socks5BytestreamManager} or the
- * {@link InBandBytestreamManager}.
- * <p>
- * There are two ways to add this listener. See
- * {@link BytestreamManager#addIncomingBytestreamListener(BytestreamListener)} and
- * {@link BytestreamManager#addIncomingBytestreamListener(BytestreamListener, String)} for further
- * details.
- * <p>
- * {@link Socks5BytestreamListener} or {@link InBandBytestreamListener} provide a more specific
- * interface of the BytestreamListener.
- * 
- * @author Henning Staib
- */
-public interface BytestreamListener {
-
-    /**
-     * This listener is notified if a bytestream request from another user has been received.
-     * 
-     * @param request the incoming bytestream request
-     */
-    public void incomingBytestreamRequest(BytestreamRequest request);
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams;
+
+import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamListener;
+import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
+import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamListener;
+import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager;
+
+/**
+ * BytestreamListener are notified if a remote user wants to initiate a bytestream. Implement this
+ * interface to handle incoming bytestream requests.
+ * <p>
+ * BytestreamListener can be registered at the {@link Socks5BytestreamManager} or the
+ * {@link InBandBytestreamManager}.
+ * <p>
+ * There are two ways to add this listener. See
+ * {@link BytestreamManager#addIncomingBytestreamListener(BytestreamListener)} and
+ * {@link BytestreamManager#addIncomingBytestreamListener(BytestreamListener, String)} for further
+ * details.
+ * <p>
+ * {@link Socks5BytestreamListener} or {@link InBandBytestreamListener} provide a more specific
+ * interface of the BytestreamListener.
+ * 
+ * @author Henning Staib
+ */
+public interface BytestreamListener {
+
+    /**
+     * This listener is notified if a bytestream request from another user has been received.
+     * 
+     * @param request the incoming bytestream request
+     */
+    public void incomingBytestreamRequest(BytestreamRequest request);
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/BytestreamManager.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/BytestreamManager.java
index ca6bbc6..232af2a 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/BytestreamManager.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/BytestreamManager.java
@@ -1,114 +1,114 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams;
-
-import java.io.IOException;
-
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
-import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager;
-
-/**
- * BytestreamManager provides a generic interface for bytestream managers.
- * <p>
- * There are two implementations of the interface. See {@link Socks5BytestreamManager} and
- * {@link InBandBytestreamManager}.
- * 
- * @author Henning Staib
- */
-public interface BytestreamManager {
-
-    /**
-     * Adds {@link BytestreamListener} that is called for every incoming bytestream request unless
-     * there is a user specific {@link BytestreamListener} registered.
-     * <p>
-     * See {@link Socks5BytestreamManager#addIncomingBytestreamListener(BytestreamListener)} and
-     * {@link InBandBytestreamManager#addIncomingBytestreamListener(BytestreamListener)} for further
-     * details.
-     * 
-     * @param listener the listener to register
-     */
-    public void addIncomingBytestreamListener(BytestreamListener listener);
-
-    /**
-     * Removes the given listener from the list of listeners for all incoming bytestream requests.
-     * 
-     * @param listener the listener to remove
-     */
-    public void removeIncomingBytestreamListener(BytestreamListener listener);
-
-    /**
-     * Adds {@link BytestreamListener} that is called for every incoming bytestream request unless
-     * there is a user specific {@link BytestreamListener} registered.
-     * <p>
-     * Use this method if you are awaiting an incoming bytestream request from a specific user.
-     * <p>
-     * See {@link Socks5BytestreamManager#addIncomingBytestreamListener(BytestreamListener, String)}
-     * and {@link InBandBytestreamManager#addIncomingBytestreamListener(BytestreamListener, String)}
-     * for further details.
-     * 
-     * @param listener the listener to register
-     * @param initiatorJID the JID of the user that wants to establish a bytestream
-     */
-    public void addIncomingBytestreamListener(BytestreamListener listener, String initiatorJID);
-
-    /**
-     * Removes the listener for the given user.
-     * 
-     * @param initiatorJID the JID of the user the listener should be removed
-     */
-    public void removeIncomingBytestreamListener(String initiatorJID);
-
-    /**
-     * Establishes a bytestream with the given user and returns the session to send/receive data
-     * to/from the user.
-     * <p>
-     * Use this method to establish bytestreams to users accepting all incoming bytestream requests
-     * since this method doesn't provide a way to tell the user something about the data to be sent.
-     * <p>
-     * To establish a bytestream after negotiation the kind of data to be sent (e.g. file transfer)
-     * use {@link #establishSession(String, String)}.
-     * <p>
-     * See {@link Socks5BytestreamManager#establishSession(String)} and
-     * {@link InBandBytestreamManager#establishSession(String)} for further details.
-     * 
-     * @param targetJID the JID of the user a bytestream should be established
-     * @return the session to send/receive data to/from the user
-     * @throws XMPPException if an error occurred while establishing the session
-     * @throws IOException if an IO error occurred while establishing the session
-     * @throws InterruptedException if the thread was interrupted while waiting in a blocking
-     *         operation
-     */
-    public BytestreamSession establishSession(String targetJID) throws XMPPException, IOException,
-                    InterruptedException;
-
-    /**
-     * Establishes a bytestream with the given user and returns the session to send/receive data
-     * to/from the user.
-     * <p>
-     * See {@link Socks5BytestreamManager#establishSession(String)} and
-     * {@link InBandBytestreamManager#establishSession(String)} for further details.
-     * 
-     * @param targetJID the JID of the user a bytestream should be established
-     * @param sessionID the session ID for the bytestream request
-     * @return the session to send/receive data to/from the user
-     * @throws XMPPException if an error occurred while establishing the session
-     * @throws IOException if an IO error occurred while establishing the session
-     * @throws InterruptedException if the thread was interrupted while waiting in a blocking
-     *         operation
-     */
-    public BytestreamSession establishSession(String targetJID, String sessionID)
-                    throws XMPPException, IOException, InterruptedException;
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams;
+
+import java.io.IOException;
+
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
+import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager;
+
+/**
+ * BytestreamManager provides a generic interface for bytestream managers.
+ * <p>
+ * There are two implementations of the interface. See {@link Socks5BytestreamManager} and
+ * {@link InBandBytestreamManager}.
+ * 
+ * @author Henning Staib
+ */
+public interface BytestreamManager {
+
+    /**
+     * Adds {@link BytestreamListener} that is called for every incoming bytestream request unless
+     * there is a user specific {@link BytestreamListener} registered.
+     * <p>
+     * See {@link Socks5BytestreamManager#addIncomingBytestreamListener(BytestreamListener)} and
+     * {@link InBandBytestreamManager#addIncomingBytestreamListener(BytestreamListener)} for further
+     * details.
+     * 
+     * @param listener the listener to register
+     */
+    public void addIncomingBytestreamListener(BytestreamListener listener);
+
+    /**
+     * Removes the given listener from the list of listeners for all incoming bytestream requests.
+     * 
+     * @param listener the listener to remove
+     */
+    public void removeIncomingBytestreamListener(BytestreamListener listener);
+
+    /**
+     * Adds {@link BytestreamListener} that is called for every incoming bytestream request unless
+     * there is a user specific {@link BytestreamListener} registered.
+     * <p>
+     * Use this method if you are awaiting an incoming bytestream request from a specific user.
+     * <p>
+     * See {@link Socks5BytestreamManager#addIncomingBytestreamListener(BytestreamListener, String)}
+     * and {@link InBandBytestreamManager#addIncomingBytestreamListener(BytestreamListener, String)}
+     * for further details.
+     * 
+     * @param listener the listener to register
+     * @param initiatorJID the JID of the user that wants to establish a bytestream
+     */
+    public void addIncomingBytestreamListener(BytestreamListener listener, String initiatorJID);
+
+    /**
+     * Removes the listener for the given user.
+     * 
+     * @param initiatorJID the JID of the user the listener should be removed
+     */
+    public void removeIncomingBytestreamListener(String initiatorJID);
+
+    /**
+     * Establishes a bytestream with the given user and returns the session to send/receive data
+     * to/from the user.
+     * <p>
+     * Use this method to establish bytestreams to users accepting all incoming bytestream requests
+     * since this method doesn't provide a way to tell the user something about the data to be sent.
+     * <p>
+     * To establish a bytestream after negotiation the kind of data to be sent (e.g. file transfer)
+     * use {@link #establishSession(String, String)}.
+     * <p>
+     * See {@link Socks5BytestreamManager#establishSession(String)} and
+     * {@link InBandBytestreamManager#establishSession(String)} for further details.
+     * 
+     * @param targetJID the JID of the user a bytestream should be established
+     * @return the session to send/receive data to/from the user
+     * @throws XMPPException if an error occurred while establishing the session
+     * @throws IOException if an IO error occurred while establishing the session
+     * @throws InterruptedException if the thread was interrupted while waiting in a blocking
+     *         operation
+     */
+    public BytestreamSession establishSession(String targetJID) throws XMPPException, IOException,
+                    InterruptedException;
+
+    /**
+     * Establishes a bytestream with the given user and returns the session to send/receive data
+     * to/from the user.
+     * <p>
+     * See {@link Socks5BytestreamManager#establishSession(String)} and
+     * {@link InBandBytestreamManager#establishSession(String)} for further details.
+     * 
+     * @param targetJID the JID of the user a bytestream should be established
+     * @param sessionID the session ID for the bytestream request
+     * @return the session to send/receive data to/from the user
+     * @throws XMPPException if an error occurred while establishing the session
+     * @throws IOException if an IO error occurred while establishing the session
+     * @throws InterruptedException if the thread was interrupted while waiting in a blocking
+     *         operation
+     */
+    public BytestreamSession establishSession(String targetJID, String sessionID)
+                    throws XMPPException, IOException, InterruptedException;
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/BytestreamRequest.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/BytestreamRequest.java
index e368bad..e16474b 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/BytestreamRequest.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/BytestreamRequest.java
@@ -1,59 +1,59 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams;
-
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamRequest;
-import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest;
-
-/**
- * BytestreamRequest provides an interface to handle incoming bytestream requests.
- * <p>
- * There are two implementations of the interface. See {@link Socks5BytestreamRequest} and
- * {@link InBandBytestreamRequest}.
- * 
- * @author Henning Staib
- */
-public interface BytestreamRequest {
-
-    /**
-     * Returns the sender of the bytestream open request.
-     * 
-     * @return the sender of the bytestream open request
-     */
-    public String getFrom();
-
-    /**
-     * Returns the session ID of the bytestream open request.
-     * 
-     * @return the session ID of the bytestream open request
-     */
-    public String getSessionID();
-
-    /**
-     * Accepts the bytestream open request and returns the session to send/receive data.
-     * 
-     * @return the session to send/receive data
-     * @throws XMPPException if an error occurred while accepting the bytestream request
-     * @throws InterruptedException if the thread was interrupted while waiting in a blocking
-     *         operation
-     */
-    public BytestreamSession accept() throws XMPPException, InterruptedException;
-
-    /**
-     * Rejects the bytestream request by sending a reject error to the initiator.
-     */
-    public void reject();
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams;
+
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamRequest;
+import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest;
+
+/**
+ * BytestreamRequest provides an interface to handle incoming bytestream requests.
+ * <p>
+ * There are two implementations of the interface. See {@link Socks5BytestreamRequest} and
+ * {@link InBandBytestreamRequest}.
+ * 
+ * @author Henning Staib
+ */
+public interface BytestreamRequest {
+
+    /**
+     * Returns the sender of the bytestream open request.
+     * 
+     * @return the sender of the bytestream open request
+     */
+    public String getFrom();
+
+    /**
+     * Returns the session ID of the bytestream open request.
+     * 
+     * @return the session ID of the bytestream open request
+     */
+    public String getSessionID();
+
+    /**
+     * Accepts the bytestream open request and returns the session to send/receive data.
+     * 
+     * @return the session to send/receive data
+     * @throws XMPPException if an error occurred while accepting the bytestream request
+     * @throws InterruptedException if the thread was interrupted while waiting in a blocking
+     *         operation
+     */
+    public BytestreamSession accept() throws XMPPException, InterruptedException;
+
+    /**
+     * Rejects the bytestream request by sending a reject error to the initiator.
+     */
+    public void reject();
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/BytestreamSession.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/BytestreamSession.java
index 7aafc35..3041d77 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/BytestreamSession.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/BytestreamSession.java
@@ -1,81 +1,81 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamSession;
-import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession;
-
-/**
- * BytestreamSession provides an interface for established bytestream sessions.
- * <p>
- * There are two implementations of the interface. See {@link Socks5BytestreamSession} and
- * {@link InBandBytestreamSession}.
- * 
- * @author Henning Staib
- */
-public interface BytestreamSession {
-
-    /**
-     * Returns the InputStream associated with this session to send data.
-     * 
-     * @return the InputStream associated with this session to send data
-     * @throws IOException if an error occurs while retrieving the input stream
-     */
-    public InputStream getInputStream() throws IOException;
-
-    /**
-     * Returns the OutputStream associated with this session to receive data.
-     * 
-     * @return the OutputStream associated with this session to receive data
-     * @throws IOException if an error occurs while retrieving the output stream
-     */
-    public OutputStream getOutputStream() throws IOException;
-
-    /**
-     * Closes the bytestream session.
-     * <p>
-     * Closing the session will also close the input stream and the output stream associated to this
-     * session.
-     * 
-     * @throws IOException if an error occurs while closing the session
-     */
-    public void close() throws IOException;
-
-    /**
-     * Returns the timeout for read operations of the input stream associated with this session. 0
-     * returns implies that the option is disabled (i.e., timeout of infinity). Default is 0.
-     * 
-     * @return the timeout for read operations
-     * @throws IOException if there is an error in the underlying protocol
-     */
-    public int getReadTimeout() throws IOException;
-
-    /**
-     * Sets the specified timeout, in milliseconds. With this option set to a non-zero timeout, a
-     * read() call on the input stream associated with this session will block for only this amount
-     * of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the
-     * session is still valid. The option must be enabled prior to entering the blocking operation
-     * to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite
-     * timeout. Default is 0.
-     * 
-     * @param timeout the specified timeout, in milliseconds
-     * @throws IOException if there is an error in the underlying protocol
-     */
-    public void setReadTimeout(int timeout) throws IOException;
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamSession;
+import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession;
+
+/**
+ * BytestreamSession provides an interface for established bytestream sessions.
+ * <p>
+ * There are two implementations of the interface. See {@link Socks5BytestreamSession} and
+ * {@link InBandBytestreamSession}.
+ * 
+ * @author Henning Staib
+ */
+public interface BytestreamSession {
+
+    /**
+     * Returns the InputStream associated with this session to send data.
+     * 
+     * @return the InputStream associated with this session to send data
+     * @throws IOException if an error occurs while retrieving the input stream
+     */
+    public InputStream getInputStream() throws IOException;
+
+    /**
+     * Returns the OutputStream associated with this session to receive data.
+     * 
+     * @return the OutputStream associated with this session to receive data
+     * @throws IOException if an error occurs while retrieving the output stream
+     */
+    public OutputStream getOutputStream() throws IOException;
+
+    /**
+     * Closes the bytestream session.
+     * <p>
+     * Closing the session will also close the input stream and the output stream associated to this
+     * session.
+     * 
+     * @throws IOException if an error occurs while closing the session
+     */
+    public void close() throws IOException;
+
+    /**
+     * Returns the timeout for read operations of the input stream associated with this session. 0
+     * returns implies that the option is disabled (i.e., timeout of infinity). Default is 0.
+     * 
+     * @return the timeout for read operations
+     * @throws IOException if there is an error in the underlying protocol
+     */
+    public int getReadTimeout() throws IOException;
+
+    /**
+     * Sets the specified timeout, in milliseconds. With this option set to a non-zero timeout, a
+     * read() call on the input stream associated with this session will block for only this amount
+     * of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the
+     * session is still valid. The option must be enabled prior to entering the blocking operation
+     * to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite
+     * timeout. Default is 0.
+     * 
+     * @param timeout the specified timeout, in milliseconds
+     * @throws IOException if there is an error in the underlying protocol
+     */
+    public void setReadTimeout(int timeout) throws IOException;
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/CloseListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/CloseListener.java
index 7690e95..83ca51c 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/CloseListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/CloseListener.java
@@ -1,75 +1,75 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.ibb;
-
-import org.jivesoftware.smack.PacketListener;
-import org.jivesoftware.smack.filter.AndFilter;
-import org.jivesoftware.smack.filter.IQTypeFilter;
-import org.jivesoftware.smack.filter.PacketFilter;
-import org.jivesoftware.smack.filter.PacketTypeFilter;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smackx.bytestreams.ibb.packet.Close;
-
-/**
- * CloseListener handles all In-Band Bytestream close requests.
- * <p>
- * If a close request is received it looks if a stored In-Band Bytestream
- * session exists and closes it. If no session with the given session ID exists
- * an &lt;item-not-found/&gt; error is returned to the sender.
- * 
- * @author Henning Staib
- */
-class CloseListener implements PacketListener {
-
-    /* manager containing the listeners and the XMPP connection */
-    private final InBandBytestreamManager manager;
-
-    /* packet filter for all In-Band Bytestream close requests */
-    private final PacketFilter closeFilter = new AndFilter(new PacketTypeFilter(
-                    Close.class), new IQTypeFilter(IQ.Type.SET));
-
-    /**
-     * Constructor.
-     * 
-     * @param manager the In-Band Bytestream manager
-     */
-    protected CloseListener(InBandBytestreamManager manager) {
-        this.manager = manager;
-    }
-
-    public void processPacket(Packet packet) {
-        Close closeRequest = (Close) packet;
-        InBandBytestreamSession ibbSession = this.manager.getSessions().get(
-                        closeRequest.getSessionID());
-        if (ibbSession == null) {
-            this.manager.replyItemNotFoundPacket(closeRequest);
-        }
-        else {
-            ibbSession.closeByPeer(closeRequest);
-            this.manager.getSessions().remove(closeRequest.getSessionID());
-        }
-
-    }
-
-    /**
-     * Returns the packet filter for In-Band Bytestream close requests.
-     * 
-     * @return the packet filter for In-Band Bytestream close requests
-     */
-    protected PacketFilter getFilter() {
-        return this.closeFilter;
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.ibb;
+
+import org.jivesoftware.smack.PacketListener;
+import org.jivesoftware.smack.filter.AndFilter;
+import org.jivesoftware.smack.filter.IQTypeFilter;
+import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.filter.PacketTypeFilter;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smackx.bytestreams.ibb.packet.Close;
+
+/**
+ * CloseListener handles all In-Band Bytestream close requests.
+ * <p>
+ * If a close request is received it looks if a stored In-Band Bytestream
+ * session exists and closes it. If no session with the given session ID exists
+ * an &lt;item-not-found/&gt; error is returned to the sender.
+ * 
+ * @author Henning Staib
+ */
+class CloseListener implements PacketListener {
+
+    /* manager containing the listeners and the XMPP connection */
+    private final InBandBytestreamManager manager;
+
+    /* packet filter for all In-Band Bytestream close requests */
+    private final PacketFilter closeFilter = new AndFilter(new PacketTypeFilter(
+                    Close.class), new IQTypeFilter(IQ.Type.SET));
+
+    /**
+     * Constructor.
+     * 
+     * @param manager the In-Band Bytestream manager
+     */
+    protected CloseListener(InBandBytestreamManager manager) {
+        this.manager = manager;
+    }
+
+    public void processPacket(Packet packet) {
+        Close closeRequest = (Close) packet;
+        InBandBytestreamSession ibbSession = this.manager.getSessions().get(
+                        closeRequest.getSessionID());
+        if (ibbSession == null) {
+            this.manager.replyItemNotFoundPacket(closeRequest);
+        }
+        else {
+            ibbSession.closeByPeer(closeRequest);
+            this.manager.getSessions().remove(closeRequest.getSessionID());
+        }
+
+    }
+
+    /**
+     * Returns the packet filter for In-Band Bytestream close requests.
+     * 
+     * @return the packet filter for In-Band Bytestream close requests
+     */
+    protected PacketFilter getFilter() {
+        return this.closeFilter;
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/DataListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/DataListener.java
index 166c146..6ef759c 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/DataListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/DataListener.java
@@ -1,73 +1,73 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.ibb;
-
-import org.jivesoftware.smack.PacketListener;
-import org.jivesoftware.smack.filter.AndFilter;
-import org.jivesoftware.smack.filter.PacketFilter;
-import org.jivesoftware.smack.filter.PacketTypeFilter;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smackx.bytestreams.ibb.packet.Data;
-
-/**
- * DataListener handles all In-Band Bytestream IQ stanzas containing a data
- * packet extension that don't belong to an existing session.
- * <p>
- * If a data packet is received it looks if a stored In-Band Bytestream session
- * exists. If no session with the given session ID exists an
- * &lt;item-not-found/&gt; error is returned to the sender.
- * <p>
- * Data packets belonging to a running In-Band Bytestream session are processed
- * by more specific listeners registered when an {@link InBandBytestreamSession}
- * is created.
- * 
- * @author Henning Staib
- */
-class DataListener implements PacketListener {
-
-    /* manager containing the listeners and the XMPP connection */
-    private final InBandBytestreamManager manager;
-
-    /* packet filter for all In-Band Bytestream data packets */
-    private final PacketFilter dataFilter = new AndFilter(
-                    new PacketTypeFilter(Data.class));
-
-    /**
-     * Constructor.
-     * 
-     * @param manager the In-Band Bytestream manager
-     */
-    public DataListener(InBandBytestreamManager manager) {
-        this.manager = manager;
-    }
-
-    public void processPacket(Packet packet) {
-        Data data = (Data) packet;
-        InBandBytestreamSession ibbSession = this.manager.getSessions().get(
-                        data.getDataPacketExtension().getSessionID());
-        if (ibbSession == null) {
-            this.manager.replyItemNotFoundPacket(data);
-        }
-    }
-
-    /**
-     * Returns the packet filter for In-Band Bytestream data packets.
-     * 
-     * @return the packet filter for In-Band Bytestream data packets
-     */
-    protected PacketFilter getFilter() {
-        return this.dataFilter;
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.ibb;
+
+import org.jivesoftware.smack.PacketListener;
+import org.jivesoftware.smack.filter.AndFilter;
+import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.filter.PacketTypeFilter;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smackx.bytestreams.ibb.packet.Data;
+
+/**
+ * DataListener handles all In-Band Bytestream IQ stanzas containing a data
+ * packet extension that don't belong to an existing session.
+ * <p>
+ * If a data packet is received it looks if a stored In-Band Bytestream session
+ * exists. If no session with the given session ID exists an
+ * &lt;item-not-found/&gt; error is returned to the sender.
+ * <p>
+ * Data packets belonging to a running In-Band Bytestream session are processed
+ * by more specific listeners registered when an {@link InBandBytestreamSession}
+ * is created.
+ * 
+ * @author Henning Staib
+ */
+class DataListener implements PacketListener {
+
+    /* manager containing the listeners and the XMPP connection */
+    private final InBandBytestreamManager manager;
+
+    /* packet filter for all In-Band Bytestream data packets */
+    private final PacketFilter dataFilter = new AndFilter(
+                    new PacketTypeFilter(Data.class));
+
+    /**
+     * Constructor.
+     * 
+     * @param manager the In-Band Bytestream manager
+     */
+    public DataListener(InBandBytestreamManager manager) {
+        this.manager = manager;
+    }
+
+    public void processPacket(Packet packet) {
+        Data data = (Data) packet;
+        InBandBytestreamSession ibbSession = this.manager.getSessions().get(
+                        data.getDataPacketExtension().getSessionID());
+        if (ibbSession == null) {
+            this.manager.replyItemNotFoundPacket(data);
+        }
+    }
+
+    /**
+     * Returns the packet filter for In-Band Bytestream data packets.
+     * 
+     * @return the packet filter for In-Band Bytestream data packets
+     */
+    protected PacketFilter getFilter() {
+        return this.dataFilter;
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamListener.java
index 68791a6..6c84013 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamListener.java
@@ -1,46 +1,46 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.ibb;
-
-import org.jivesoftware.smackx.bytestreams.BytestreamListener;
-import org.jivesoftware.smackx.bytestreams.BytestreamRequest;
-
-/**
- * InBandBytestreamListener are informed if a remote user wants to initiate an In-Band Bytestream.
- * Implement this interface to handle incoming In-Band Bytestream requests.
- * <p>
- * There are two ways to add this listener. See
- * {@link InBandBytestreamManager#addIncomingBytestreamListener(BytestreamListener)} and
- * {@link InBandBytestreamManager#addIncomingBytestreamListener(BytestreamListener, String)} for
- * further details.
- * 
- * @author Henning Staib
- */
-public abstract class InBandBytestreamListener implements BytestreamListener {
-
-    
-    
-    public void incomingBytestreamRequest(BytestreamRequest request) {
-        incomingBytestreamRequest((InBandBytestreamRequest) request);
-    }
-
-    /**
-     * This listener is notified if an In-Band Bytestream request from another user has been
-     * received.
-     * 
-     * @param request the incoming In-Band Bytestream request
-     */
-    public abstract void incomingBytestreamRequest(InBandBytestreamRequest request);
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.ibb;
+
+import org.jivesoftware.smackx.bytestreams.BytestreamListener;
+import org.jivesoftware.smackx.bytestreams.BytestreamRequest;
+
+/**
+ * InBandBytestreamListener are informed if a remote user wants to initiate an In-Band Bytestream.
+ * Implement this interface to handle incoming In-Band Bytestream requests.
+ * <p>
+ * There are two ways to add this listener. See
+ * {@link InBandBytestreamManager#addIncomingBytestreamListener(BytestreamListener)} and
+ * {@link InBandBytestreamManager#addIncomingBytestreamListener(BytestreamListener, String)} for
+ * further details.
+ * 
+ * @author Henning Staib
+ */
+public abstract class InBandBytestreamListener implements BytestreamListener {
+
+    
+    
+    public void incomingBytestreamRequest(BytestreamRequest request) {
+        incomingBytestreamRequest((InBandBytestreamRequest) request);
+    }
+
+    /**
+     * This listener is notified if an In-Band Bytestream request from another user has been
+     * received.
+     * 
+     * @param request the incoming In-Band Bytestream request
+     */
+    public abstract void incomingBytestreamRequest(InBandBytestreamRequest request);
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java
index ef52531..a4f3592 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java
@@ -1,546 +1,546 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.ibb;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.jivesoftware.smack.AbstractConnectionListener;
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.ConnectionCreationListener;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.XMPPError;
-import org.jivesoftware.smack.util.SyncPacketSend;
-import org.jivesoftware.smackx.bytestreams.BytestreamListener;
-import org.jivesoftware.smackx.bytestreams.BytestreamManager;
-import org.jivesoftware.smackx.bytestreams.ibb.packet.Open;
-import org.jivesoftware.smackx.filetransfer.FileTransferManager;
-
-/**
- * The InBandBytestreamManager class handles establishing In-Band Bytestreams as specified in the <a
- * href="http://xmpp.org/extensions/xep-0047.html">XEP-0047</a>.
- * <p>
- * The In-Band Bytestreams (IBB) enables two entities to establish a virtual bytestream over which
- * they can exchange Base64-encoded chunks of data over XMPP itself. It is the fall-back mechanism
- * in case the Socks5 bytestream method of transferring data is not available.
- * <p>
- * There are two ways to send data over an In-Band Bytestream. It could either use IQ stanzas to
- * send data packets or message stanzas. If IQ stanzas are used every data packet is acknowledged by
- * the receiver. This is the recommended way to avoid possible rate-limiting penalties. Message
- * stanzas are not acknowledged because most XMPP server implementation don't support stanza
- * flow-control method like <a href="http://xmpp.org/extensions/xep-0079.html">Advanced Message
- * Processing</a>. To set the stanza that should be used invoke {@link #setStanza(StanzaType)}.
- * <p>
- * To establish an In-Band Bytestream invoke the {@link #establishSession(String)} method. This will
- * negotiate an in-band bytestream with the given target JID and return a session.
- * <p>
- * If a session ID for the In-Band Bytestream was already negotiated (e.g. while negotiating a file
- * transfer) invoke {@link #establishSession(String, String)}.
- * <p>
- * To handle incoming In-Band Bytestream requests add an {@link InBandBytestreamListener} to the
- * manager. There are two ways to add this listener. If you want to be informed about incoming
- * In-Band Bytestreams from a specific user add the listener by invoking
- * {@link #addIncomingBytestreamListener(BytestreamListener, String)}. If the listener should
- * respond to all In-Band Bytestream requests invoke
- * {@link #addIncomingBytestreamListener(BytestreamListener)}.
- * <p>
- * Note that the registered {@link InBandBytestreamListener} will NOT be notified on incoming
- * In-Band bytestream requests sent in the context of <a
- * href="http://xmpp.org/extensions/xep-0096.html">XEP-0096</a> file transfer. (See
- * {@link FileTransferManager})
- * <p>
- * If no {@link InBandBytestreamListener}s are registered, all incoming In-Band bytestream requests
- * will be rejected by returning a &lt;not-acceptable/&gt; error to the initiator.
- * 
- * @author Henning Staib
- */
-public class InBandBytestreamManager implements BytestreamManager {
-
-    /**
-     * Stanzas that can be used to encapsulate In-Band Bytestream data packets.
-     */
-    public enum StanzaType {
-
-        /**
-         * IQ stanza.
-         */
-        IQ,
-
-        /**
-         * Message stanza.
-         */
-        MESSAGE
-    }
-
-    /*
-     * create a new InBandBytestreamManager and register its shutdown listener on every established
-     * connection
-     */
-    static {
-        Connection.addConnectionCreationListener(new ConnectionCreationListener() {
-            public void connectionCreated(Connection connection) {
-                final InBandBytestreamManager manager;
-                manager = InBandBytestreamManager.getByteStreamManager(connection);
-
-                // register shutdown listener
-                connection.addConnectionListener(new AbstractConnectionListener() {
-
-                    public void connectionClosed() {
-                        manager.disableService();
-                    }
-
-                });
-
-            }
-        });
-    }
-
-    /**
-     * The XMPP namespace of the In-Band Bytestream
-     */
-    public static final String NAMESPACE = "http://jabber.org/protocol/ibb";
-
-    /**
-     * Maximum block size that is allowed for In-Band Bytestreams
-     */
-    public static final int MAXIMUM_BLOCK_SIZE = 65535;
-
-    /* prefix used to generate session IDs */
-    private static final String SESSION_ID_PREFIX = "jibb_";
-
-    /* random generator to create session IDs */
-    private final static Random randomGenerator = new Random();
-
-    /* stores one InBandBytestreamManager for each XMPP connection */
-    private final static Map<Connection, InBandBytestreamManager> managers = new HashMap<Connection, InBandBytestreamManager>();
-
-    /* XMPP connection */
-    private final Connection connection;
-
-    /*
-     * assigns a user to a listener that is informed if an In-Band Bytestream request for this user
-     * is received
-     */
-    private final Map<String, BytestreamListener> userListeners = new ConcurrentHashMap<String, BytestreamListener>();
-
-    /*
-     * list of listeners that respond to all In-Band Bytestream requests if there are no user
-     * specific listeners for that request
-     */
-    private final List<BytestreamListener> allRequestListeners = Collections.synchronizedList(new LinkedList<BytestreamListener>());
-
-    /* listener that handles all incoming In-Band Bytestream requests */
-    private final InitiationListener initiationListener;
-
-    /* listener that handles all incoming In-Band Bytestream IQ data packets */
-    private final DataListener dataListener;
-
-    /* listener that handles all incoming In-Band Bytestream close requests */
-    private final CloseListener closeListener;
-
-    /* assigns a session ID to the In-Band Bytestream session */
-    private final Map<String, InBandBytestreamSession> sessions = new ConcurrentHashMap<String, InBandBytestreamSession>();
-
-    /* block size used for new In-Band Bytestreams */
-    private int defaultBlockSize = 4096;
-
-    /* maximum block size allowed for this connection */
-    private int maximumBlockSize = MAXIMUM_BLOCK_SIZE;
-
-    /* the stanza used to send data packets */
-    private StanzaType stanza = StanzaType.IQ;
-
-    /*
-     * list containing session IDs of In-Band Bytestream open packets that should be ignored by the
-     * InitiationListener
-     */
-    private List<String> ignoredBytestreamRequests = Collections.synchronizedList(new LinkedList<String>());
-
-    /**
-     * Returns the InBandBytestreamManager to handle In-Band Bytestreams for a given
-     * {@link Connection}.
-     * 
-     * @param connection the XMPP connection
-     * @return the InBandBytestreamManager for the given XMPP connection
-     */
-    public static synchronized InBandBytestreamManager getByteStreamManager(Connection connection) {
-        if (connection == null)
-            return null;
-        InBandBytestreamManager manager = managers.get(connection);
-        if (manager == null) {
-            manager = new InBandBytestreamManager(connection);
-            managers.put(connection, manager);
-        }
-        return manager;
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param connection the XMPP connection
-     */
-    private InBandBytestreamManager(Connection connection) {
-        this.connection = connection;
-
-        // register bytestream open packet listener
-        this.initiationListener = new InitiationListener(this);
-        this.connection.addPacketListener(this.initiationListener,
-                        this.initiationListener.getFilter());
-
-        // register bytestream data packet listener
-        this.dataListener = new DataListener(this);
-        this.connection.addPacketListener(this.dataListener, this.dataListener.getFilter());
-
-        // register bytestream close packet listener
-        this.closeListener = new CloseListener(this);
-        this.connection.addPacketListener(this.closeListener, this.closeListener.getFilter());
-
-    }
-
-    /**
-     * Adds InBandBytestreamListener that is called for every incoming in-band bytestream request
-     * unless there is a user specific InBandBytestreamListener registered.
-     * <p>
-     * If no listeners are registered all In-Band Bytestream request are rejected with a
-     * &lt;not-acceptable/&gt; error.
-     * <p>
-     * Note that the registered {@link InBandBytestreamListener} will NOT be notified on incoming
-     * Socks5 bytestream requests sent in the context of <a
-     * href="http://xmpp.org/extensions/xep-0096.html">XEP-0096</a> file transfer. (See
-     * {@link FileTransferManager})
-     * 
-     * @param listener the listener to register
-     */
-    public void addIncomingBytestreamListener(BytestreamListener listener) {
-        this.allRequestListeners.add(listener);
-    }
-
-    /**
-     * Removes the given listener from the list of listeners for all incoming In-Band Bytestream
-     * requests.
-     * 
-     * @param listener the listener to remove
-     */
-    public void removeIncomingBytestreamListener(BytestreamListener listener) {
-        this.allRequestListeners.remove(listener);
-    }
-
-    /**
-     * Adds InBandBytestreamListener that is called for every incoming in-band bytestream request
-     * from the given user.
-     * <p>
-     * Use this method if you are awaiting an incoming Socks5 bytestream request from a specific
-     * user.
-     * <p>
-     * If no listeners are registered all In-Band Bytestream request are rejected with a
-     * &lt;not-acceptable/&gt; error.
-     * <p>
-     * Note that the registered {@link InBandBytestreamListener} will NOT be notified on incoming
-     * Socks5 bytestream requests sent in the context of <a
-     * href="http://xmpp.org/extensions/xep-0096.html">XEP-0096</a> file transfer. (See
-     * {@link FileTransferManager})
-     * 
-     * @param listener the listener to register
-     * @param initiatorJID the JID of the user that wants to establish an In-Band Bytestream
-     */
-    public void addIncomingBytestreamListener(BytestreamListener listener, String initiatorJID) {
-        this.userListeners.put(initiatorJID, listener);
-    }
-
-    /**
-     * Removes the listener for the given user.
-     * 
-     * @param initiatorJID the JID of the user the listener should be removed
-     */
-    public void removeIncomingBytestreamListener(String initiatorJID) {
-        this.userListeners.remove(initiatorJID);
-    }
-
-    /**
-     * Use this method to ignore the next incoming In-Band Bytestream request containing the given
-     * session ID. No listeners will be notified for this request and and no error will be returned
-     * to the initiator.
-     * <p>
-     * This method should be used if you are awaiting an In-Band Bytestream request as a reply to
-     * another packet (e.g. file transfer).
-     * 
-     * @param sessionID to be ignored
-     */
-    public void ignoreBytestreamRequestOnce(String sessionID) {
-        this.ignoredBytestreamRequests.add(sessionID);
-    }
-
-    /**
-     * Returns the default block size that is used for all outgoing in-band bytestreams for this
-     * connection.
-     * <p>
-     * The recommended default block size is 4096 bytes. See <a
-     * href="http://xmpp.org/extensions/xep-0047.html#usage">XEP-0047</a> Section 5.
-     * 
-     * @return the default block size
-     */
-    public int getDefaultBlockSize() {
-        return defaultBlockSize;
-    }
-
-    /**
-     * Sets the default block size that is used for all outgoing in-band bytestreams for this
-     * connection.
-     * <p>
-     * The default block size must be between 1 and 65535 bytes. The recommended default block size
-     * is 4096 bytes. See <a href="http://xmpp.org/extensions/xep-0047.html#usage">XEP-0047</a>
-     * Section 5.
-     * 
-     * @param defaultBlockSize the default block size to set
-     */
-    public void setDefaultBlockSize(int defaultBlockSize) {
-        if (defaultBlockSize <= 0 || defaultBlockSize > MAXIMUM_BLOCK_SIZE) {
-            throw new IllegalArgumentException("Default block size must be between 1 and "
-                            + MAXIMUM_BLOCK_SIZE);
-        }
-        this.defaultBlockSize = defaultBlockSize;
-    }
-
-    /**
-     * Returns the maximum block size that is allowed for In-Band Bytestreams for this connection.
-     * <p>
-     * Incoming In-Band Bytestream open request will be rejected with an
-     * &lt;resource-constraint/&gt; error if the block size is greater then the maximum allowed
-     * block size.
-     * <p>
-     * The default maximum block size is 65535 bytes.
-     * 
-     * @return the maximum block size
-     */
-    public int getMaximumBlockSize() {
-        return maximumBlockSize;
-    }
-
-    /**
-     * Sets the maximum block size that is allowed for In-Band Bytestreams for this connection.
-     * <p>
-     * The maximum block size must be between 1 and 65535 bytes.
-     * <p>
-     * Incoming In-Band Bytestream open request will be rejected with an
-     * &lt;resource-constraint/&gt; error if the block size is greater then the maximum allowed
-     * block size.
-     * 
-     * @param maximumBlockSize the maximum block size to set
-     */
-    public void setMaximumBlockSize(int maximumBlockSize) {
-        if (maximumBlockSize <= 0 || maximumBlockSize > MAXIMUM_BLOCK_SIZE) {
-            throw new IllegalArgumentException("Maximum block size must be between 1 and "
-                            + MAXIMUM_BLOCK_SIZE);
-        }
-        this.maximumBlockSize = maximumBlockSize;
-    }
-
-    /**
-     * Returns the stanza used to send data packets.
-     * <p>
-     * Default is {@link StanzaType#IQ}. See <a
-     * href="http://xmpp.org/extensions/xep-0047.html#message">XEP-0047</a> Section 4.
-     * 
-     * @return the stanza used to send data packets
-     */
-    public StanzaType getStanza() {
-        return stanza;
-    }
-
-    /**
-     * Sets the stanza used to send data packets.
-     * <p>
-     * The use of {@link StanzaType#IQ} is recommended. See <a
-     * href="http://xmpp.org/extensions/xep-0047.html#message">XEP-0047</a> Section 4.
-     * 
-     * @param stanza the stanza to set
-     */
-    public void setStanza(StanzaType stanza) {
-        this.stanza = stanza;
-    }
-
-    /**
-     * Establishes an In-Band Bytestream with the given user and returns the session to send/receive
-     * data to/from the user.
-     * <p>
-     * Use this method to establish In-Band Bytestreams to users accepting all incoming In-Band
-     * Bytestream requests since this method doesn't provide a way to tell the user something about
-     * the data to be sent.
-     * <p>
-     * To establish an In-Band Bytestream after negotiation the kind of data to be sent (e.g. file
-     * transfer) use {@link #establishSession(String, String)}.
-     * 
-     * @param targetJID the JID of the user an In-Band Bytestream should be established
-     * @return the session to send/receive data to/from the user
-     * @throws XMPPException if the user doesn't support or accept in-band bytestreams, or if the
-     *         user prefers smaller block sizes
-     */
-    public InBandBytestreamSession establishSession(String targetJID) throws XMPPException {
-        String sessionID = getNextSessionID();
-        return establishSession(targetJID, sessionID);
-    }
-
-    /**
-     * Establishes an In-Band Bytestream with the given user using the given session ID and returns
-     * the session to send/receive data to/from the user.
-     * 
-     * @param targetJID the JID of the user an In-Band Bytestream should be established
-     * @param sessionID the session ID for the In-Band Bytestream request
-     * @return the session to send/receive data to/from the user
-     * @throws XMPPException if the user doesn't support or accept in-band bytestreams, or if the
-     *         user prefers smaller block sizes
-     */
-    public InBandBytestreamSession establishSession(String targetJID, String sessionID)
-                    throws XMPPException {
-        Open byteStreamRequest = new Open(sessionID, this.defaultBlockSize, this.stanza);
-        byteStreamRequest.setTo(targetJID);
-
-        // sending packet will throw exception on timeout or error reply
-        SyncPacketSend.getReply(this.connection, byteStreamRequest);
-
-        InBandBytestreamSession inBandBytestreamSession = new InBandBytestreamSession(
-                        this.connection, byteStreamRequest, targetJID);
-        this.sessions.put(sessionID, inBandBytestreamSession);
-
-        return inBandBytestreamSession;
-    }
-
-    /**
-     * Responses to the given IQ packet's sender with an XMPP error that an In-Band Bytestream is
-     * not accepted.
-     * 
-     * @param request IQ packet that should be answered with a not-acceptable error
-     */
-    protected void replyRejectPacket(IQ request) {
-        XMPPError xmppError = new XMPPError(XMPPError.Condition.no_acceptable);
-        IQ error = IQ.createErrorResponse(request, xmppError);
-        this.connection.sendPacket(error);
-    }
-
-    /**
-     * Responses to the given IQ packet's sender with an XMPP error that an In-Band Bytestream open
-     * request is rejected because its block size is greater than the maximum allowed block size.
-     * 
-     * @param request IQ packet that should be answered with a resource-constraint error
-     */
-    protected void replyResourceConstraintPacket(IQ request) {
-        XMPPError xmppError = new XMPPError(XMPPError.Condition.resource_constraint);
-        IQ error = IQ.createErrorResponse(request, xmppError);
-        this.connection.sendPacket(error);
-    }
-
-    /**
-     * Responses to the given IQ packet's sender with an XMPP error that an In-Band Bytestream
-     * session could not be found.
-     * 
-     * @param request IQ packet that should be answered with a item-not-found error
-     */
-    protected void replyItemNotFoundPacket(IQ request) {
-        XMPPError xmppError = new XMPPError(XMPPError.Condition.item_not_found);
-        IQ error = IQ.createErrorResponse(request, xmppError);
-        this.connection.sendPacket(error);
-    }
-
-    /**
-     * Returns a new unique session ID.
-     * 
-     * @return a new unique session ID
-     */
-    private String getNextSessionID() {
-        StringBuilder buffer = new StringBuilder();
-        buffer.append(SESSION_ID_PREFIX);
-        buffer.append(Math.abs(randomGenerator.nextLong()));
-        return buffer.toString();
-    }
-
-    /**
-     * Returns the XMPP connection.
-     * 
-     * @return the XMPP connection
-     */
-    protected Connection getConnection() {
-        return this.connection;
-    }
-
-    /**
-     * Returns the {@link InBandBytestreamListener} that should be informed if a In-Band Bytestream
-     * request from the given initiator JID is received.
-     * 
-     * @param initiator the initiator's JID
-     * @return the listener
-     */
-    protected BytestreamListener getUserListener(String initiator) {
-        return this.userListeners.get(initiator);
-    }
-
-    /**
-     * Returns a list of {@link InBandBytestreamListener} that are informed if there are no
-     * listeners for a specific initiator.
-     * 
-     * @return list of listeners
-     */
-    protected List<BytestreamListener> getAllRequestListeners() {
-        return this.allRequestListeners;
-    }
-
-    /**
-     * Returns the sessions map.
-     * 
-     * @return the sessions map
-     */
-    protected Map<String, InBandBytestreamSession> getSessions() {
-        return sessions;
-    }
-
-    /**
-     * Returns the list of session IDs that should be ignored by the InitialtionListener
-     * 
-     * @return list of session IDs
-     */
-    protected List<String> getIgnoredBytestreamRequests() {
-        return ignoredBytestreamRequests;
-    }
-
-    /**
-     * Disables the InBandBytestreamManager by removing its packet listeners and resetting its
-     * internal status.
-     */
-    private void disableService() {
-
-        // remove manager from static managers map
-        managers.remove(connection);
-
-        // remove all listeners registered by this manager
-        this.connection.removePacketListener(this.initiationListener);
-        this.connection.removePacketListener(this.dataListener);
-        this.connection.removePacketListener(this.closeListener);
-
-        // shutdown threads
-        this.initiationListener.shutdown();
-
-        // reset internal status
-        this.userListeners.clear();
-        this.allRequestListeners.clear();
-        this.sessions.clear();
-        this.ignoredBytestreamRequests.clear();
-
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.ibb;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.jivesoftware.smack.AbstractConnectionListener;
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.ConnectionCreationListener;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.XMPPError;
+import org.jivesoftware.smack.util.SyncPacketSend;
+import org.jivesoftware.smackx.bytestreams.BytestreamListener;
+import org.jivesoftware.smackx.bytestreams.BytestreamManager;
+import org.jivesoftware.smackx.bytestreams.ibb.packet.Open;
+import org.jivesoftware.smackx.filetransfer.FileTransferManager;
+
+/**
+ * The InBandBytestreamManager class handles establishing In-Band Bytestreams as specified in the <a
+ * href="http://xmpp.org/extensions/xep-0047.html">XEP-0047</a>.
+ * <p>
+ * The In-Band Bytestreams (IBB) enables two entities to establish a virtual bytestream over which
+ * they can exchange Base64-encoded chunks of data over XMPP itself. It is the fall-back mechanism
+ * in case the Socks5 bytestream method of transferring data is not available.
+ * <p>
+ * There are two ways to send data over an In-Band Bytestream. It could either use IQ stanzas to
+ * send data packets or message stanzas. If IQ stanzas are used every data packet is acknowledged by
+ * the receiver. This is the recommended way to avoid possible rate-limiting penalties. Message
+ * stanzas are not acknowledged because most XMPP server implementation don't support stanza
+ * flow-control method like <a href="http://xmpp.org/extensions/xep-0079.html">Advanced Message
+ * Processing</a>. To set the stanza that should be used invoke {@link #setStanza(StanzaType)}.
+ * <p>
+ * To establish an In-Band Bytestream invoke the {@link #establishSession(String)} method. This will
+ * negotiate an in-band bytestream with the given target JID and return a session.
+ * <p>
+ * If a session ID for the In-Band Bytestream was already negotiated (e.g. while negotiating a file
+ * transfer) invoke {@link #establishSession(String, String)}.
+ * <p>
+ * To handle incoming In-Band Bytestream requests add an {@link InBandBytestreamListener} to the
+ * manager. There are two ways to add this listener. If you want to be informed about incoming
+ * In-Band Bytestreams from a specific user add the listener by invoking
+ * {@link #addIncomingBytestreamListener(BytestreamListener, String)}. If the listener should
+ * respond to all In-Band Bytestream requests invoke
+ * {@link #addIncomingBytestreamListener(BytestreamListener)}.
+ * <p>
+ * Note that the registered {@link InBandBytestreamListener} will NOT be notified on incoming
+ * In-Band bytestream requests sent in the context of <a
+ * href="http://xmpp.org/extensions/xep-0096.html">XEP-0096</a> file transfer. (See
+ * {@link FileTransferManager})
+ * <p>
+ * If no {@link InBandBytestreamListener}s are registered, all incoming In-Band bytestream requests
+ * will be rejected by returning a &lt;not-acceptable/&gt; error to the initiator.
+ * 
+ * @author Henning Staib
+ */
+public class InBandBytestreamManager implements BytestreamManager {
+
+    /**
+     * Stanzas that can be used to encapsulate In-Band Bytestream data packets.
+     */
+    public enum StanzaType {
+
+        /**
+         * IQ stanza.
+         */
+        IQ,
+
+        /**
+         * Message stanza.
+         */
+        MESSAGE
+    }
+
+    /*
+     * create a new InBandBytestreamManager and register its shutdown listener on every established
+     * connection
+     */
+    static {
+        Connection.addConnectionCreationListener(new ConnectionCreationListener() {
+            public void connectionCreated(Connection connection) {
+                final InBandBytestreamManager manager;
+                manager = InBandBytestreamManager.getByteStreamManager(connection);
+
+                // register shutdown listener
+                connection.addConnectionListener(new AbstractConnectionListener() {
+
+                    public void connectionClosed() {
+                        manager.disableService();
+                    }
+
+                });
+
+            }
+        });
+    }
+
+    /**
+     * The XMPP namespace of the In-Band Bytestream
+     */
+    public static final String NAMESPACE = "http://jabber.org/protocol/ibb";
+
+    /**
+     * Maximum block size that is allowed for In-Band Bytestreams
+     */
+    public static final int MAXIMUM_BLOCK_SIZE = 65535;
+
+    /* prefix used to generate session IDs */
+    private static final String SESSION_ID_PREFIX = "jibb_";
+
+    /* random generator to create session IDs */
+    private final static Random randomGenerator = new Random();
+
+    /* stores one InBandBytestreamManager for each XMPP connection */
+    private final static Map<Connection, InBandBytestreamManager> managers = new HashMap<Connection, InBandBytestreamManager>();
+
+    /* XMPP connection */
+    private final Connection connection;
+
+    /*
+     * assigns a user to a listener that is informed if an In-Band Bytestream request for this user
+     * is received
+     */
+    private final Map<String, BytestreamListener> userListeners = new ConcurrentHashMap<String, BytestreamListener>();
+
+    /*
+     * list of listeners that respond to all In-Band Bytestream requests if there are no user
+     * specific listeners for that request
+     */
+    private final List<BytestreamListener> allRequestListeners = Collections.synchronizedList(new LinkedList<BytestreamListener>());
+
+    /* listener that handles all incoming In-Band Bytestream requests */
+    private final InitiationListener initiationListener;
+
+    /* listener that handles all incoming In-Band Bytestream IQ data packets */
+    private final DataListener dataListener;
+
+    /* listener that handles all incoming In-Band Bytestream close requests */
+    private final CloseListener closeListener;
+
+    /* assigns a session ID to the In-Band Bytestream session */
+    private final Map<String, InBandBytestreamSession> sessions = new ConcurrentHashMap<String, InBandBytestreamSession>();
+
+    /* block size used for new In-Band Bytestreams */
+    private int defaultBlockSize = 4096;
+
+    /* maximum block size allowed for this connection */
+    private int maximumBlockSize = MAXIMUM_BLOCK_SIZE;
+
+    /* the stanza used to send data packets */
+    private StanzaType stanza = StanzaType.IQ;
+
+    /*
+     * list containing session IDs of In-Band Bytestream open packets that should be ignored by the
+     * InitiationListener
+     */
+    private List<String> ignoredBytestreamRequests = Collections.synchronizedList(new LinkedList<String>());
+
+    /**
+     * Returns the InBandBytestreamManager to handle In-Band Bytestreams for a given
+     * {@link Connection}.
+     * 
+     * @param connection the XMPP connection
+     * @return the InBandBytestreamManager for the given XMPP connection
+     */
+    public static synchronized InBandBytestreamManager getByteStreamManager(Connection connection) {
+        if (connection == null)
+            return null;
+        InBandBytestreamManager manager = managers.get(connection);
+        if (manager == null) {
+            manager = new InBandBytestreamManager(connection);
+            managers.put(connection, manager);
+        }
+        return manager;
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param connection the XMPP connection
+     */
+    private InBandBytestreamManager(Connection connection) {
+        this.connection = connection;
+
+        // register bytestream open packet listener
+        this.initiationListener = new InitiationListener(this);
+        this.connection.addPacketListener(this.initiationListener,
+                        this.initiationListener.getFilter());
+
+        // register bytestream data packet listener
+        this.dataListener = new DataListener(this);
+        this.connection.addPacketListener(this.dataListener, this.dataListener.getFilter());
+
+        // register bytestream close packet listener
+        this.closeListener = new CloseListener(this);
+        this.connection.addPacketListener(this.closeListener, this.closeListener.getFilter());
+
+    }
+
+    /**
+     * Adds InBandBytestreamListener that is called for every incoming in-band bytestream request
+     * unless there is a user specific InBandBytestreamListener registered.
+     * <p>
+     * If no listeners are registered all In-Band Bytestream request are rejected with a
+     * &lt;not-acceptable/&gt; error.
+     * <p>
+     * Note that the registered {@link InBandBytestreamListener} will NOT be notified on incoming
+     * Socks5 bytestream requests sent in the context of <a
+     * href="http://xmpp.org/extensions/xep-0096.html">XEP-0096</a> file transfer. (See
+     * {@link FileTransferManager})
+     * 
+     * @param listener the listener to register
+     */
+    public void addIncomingBytestreamListener(BytestreamListener listener) {
+        this.allRequestListeners.add(listener);
+    }
+
+    /**
+     * Removes the given listener from the list of listeners for all incoming In-Band Bytestream
+     * requests.
+     * 
+     * @param listener the listener to remove
+     */
+    public void removeIncomingBytestreamListener(BytestreamListener listener) {
+        this.allRequestListeners.remove(listener);
+    }
+
+    /**
+     * Adds InBandBytestreamListener that is called for every incoming in-band bytestream request
+     * from the given user.
+     * <p>
+     * Use this method if you are awaiting an incoming Socks5 bytestream request from a specific
+     * user.
+     * <p>
+     * If no listeners are registered all In-Band Bytestream request are rejected with a
+     * &lt;not-acceptable/&gt; error.
+     * <p>
+     * Note that the registered {@link InBandBytestreamListener} will NOT be notified on incoming
+     * Socks5 bytestream requests sent in the context of <a
+     * href="http://xmpp.org/extensions/xep-0096.html">XEP-0096</a> file transfer. (See
+     * {@link FileTransferManager})
+     * 
+     * @param listener the listener to register
+     * @param initiatorJID the JID of the user that wants to establish an In-Band Bytestream
+     */
+    public void addIncomingBytestreamListener(BytestreamListener listener, String initiatorJID) {
+        this.userListeners.put(initiatorJID, listener);
+    }
+
+    /**
+     * Removes the listener for the given user.
+     * 
+     * @param initiatorJID the JID of the user the listener should be removed
+     */
+    public void removeIncomingBytestreamListener(String initiatorJID) {
+        this.userListeners.remove(initiatorJID);
+    }
+
+    /**
+     * Use this method to ignore the next incoming In-Band Bytestream request containing the given
+     * session ID. No listeners will be notified for this request and and no error will be returned
+     * to the initiator.
+     * <p>
+     * This method should be used if you are awaiting an In-Band Bytestream request as a reply to
+     * another packet (e.g. file transfer).
+     * 
+     * @param sessionID to be ignored
+     */
+    public void ignoreBytestreamRequestOnce(String sessionID) {
+        this.ignoredBytestreamRequests.add(sessionID);
+    }
+
+    /**
+     * Returns the default block size that is used for all outgoing in-band bytestreams for this
+     * connection.
+     * <p>
+     * The recommended default block size is 4096 bytes. See <a
+     * href="http://xmpp.org/extensions/xep-0047.html#usage">XEP-0047</a> Section 5.
+     * 
+     * @return the default block size
+     */
+    public int getDefaultBlockSize() {
+        return defaultBlockSize;
+    }
+
+    /**
+     * Sets the default block size that is used for all outgoing in-band bytestreams for this
+     * connection.
+     * <p>
+     * The default block size must be between 1 and 65535 bytes. The recommended default block size
+     * is 4096 bytes. See <a href="http://xmpp.org/extensions/xep-0047.html#usage">XEP-0047</a>
+     * Section 5.
+     * 
+     * @param defaultBlockSize the default block size to set
+     */
+    public void setDefaultBlockSize(int defaultBlockSize) {
+        if (defaultBlockSize <= 0 || defaultBlockSize > MAXIMUM_BLOCK_SIZE) {
+            throw new IllegalArgumentException("Default block size must be between 1 and "
+                            + MAXIMUM_BLOCK_SIZE);
+        }
+        this.defaultBlockSize = defaultBlockSize;
+    }
+
+    /**
+     * Returns the maximum block size that is allowed for In-Band Bytestreams for this connection.
+     * <p>
+     * Incoming In-Band Bytestream open request will be rejected with an
+     * &lt;resource-constraint/&gt; error if the block size is greater then the maximum allowed
+     * block size.
+     * <p>
+     * The default maximum block size is 65535 bytes.
+     * 
+     * @return the maximum block size
+     */
+    public int getMaximumBlockSize() {
+        return maximumBlockSize;
+    }
+
+    /**
+     * Sets the maximum block size that is allowed for In-Band Bytestreams for this connection.
+     * <p>
+     * The maximum block size must be between 1 and 65535 bytes.
+     * <p>
+     * Incoming In-Band Bytestream open request will be rejected with an
+     * &lt;resource-constraint/&gt; error if the block size is greater then the maximum allowed
+     * block size.
+     * 
+     * @param maximumBlockSize the maximum block size to set
+     */
+    public void setMaximumBlockSize(int maximumBlockSize) {
+        if (maximumBlockSize <= 0 || maximumBlockSize > MAXIMUM_BLOCK_SIZE) {
+            throw new IllegalArgumentException("Maximum block size must be between 1 and "
+                            + MAXIMUM_BLOCK_SIZE);
+        }
+        this.maximumBlockSize = maximumBlockSize;
+    }
+
+    /**
+     * Returns the stanza used to send data packets.
+     * <p>
+     * Default is {@link StanzaType#IQ}. See <a
+     * href="http://xmpp.org/extensions/xep-0047.html#message">XEP-0047</a> Section 4.
+     * 
+     * @return the stanza used to send data packets
+     */
+    public StanzaType getStanza() {
+        return stanza;
+    }
+
+    /**
+     * Sets the stanza used to send data packets.
+     * <p>
+     * The use of {@link StanzaType#IQ} is recommended. See <a
+     * href="http://xmpp.org/extensions/xep-0047.html#message">XEP-0047</a> Section 4.
+     * 
+     * @param stanza the stanza to set
+     */
+    public void setStanza(StanzaType stanza) {
+        this.stanza = stanza;
+    }
+
+    /**
+     * Establishes an In-Band Bytestream with the given user and returns the session to send/receive
+     * data to/from the user.
+     * <p>
+     * Use this method to establish In-Band Bytestreams to users accepting all incoming In-Band
+     * Bytestream requests since this method doesn't provide a way to tell the user something about
+     * the data to be sent.
+     * <p>
+     * To establish an In-Band Bytestream after negotiation the kind of data to be sent (e.g. file
+     * transfer) use {@link #establishSession(String, String)}.
+     * 
+     * @param targetJID the JID of the user an In-Band Bytestream should be established
+     * @return the session to send/receive data to/from the user
+     * @throws XMPPException if the user doesn't support or accept in-band bytestreams, or if the
+     *         user prefers smaller block sizes
+     */
+    public InBandBytestreamSession establishSession(String targetJID) throws XMPPException {
+        String sessionID = getNextSessionID();
+        return establishSession(targetJID, sessionID);
+    }
+
+    /**
+     * Establishes an In-Band Bytestream with the given user using the given session ID and returns
+     * the session to send/receive data to/from the user.
+     * 
+     * @param targetJID the JID of the user an In-Band Bytestream should be established
+     * @param sessionID the session ID for the In-Band Bytestream request
+     * @return the session to send/receive data to/from the user
+     * @throws XMPPException if the user doesn't support or accept in-band bytestreams, or if the
+     *         user prefers smaller block sizes
+     */
+    public InBandBytestreamSession establishSession(String targetJID, String sessionID)
+                    throws XMPPException {
+        Open byteStreamRequest = new Open(sessionID, this.defaultBlockSize, this.stanza);
+        byteStreamRequest.setTo(targetJID);
+
+        // sending packet will throw exception on timeout or error reply
+        SyncPacketSend.getReply(this.connection, byteStreamRequest);
+
+        InBandBytestreamSession inBandBytestreamSession = new InBandBytestreamSession(
+                        this.connection, byteStreamRequest, targetJID);
+        this.sessions.put(sessionID, inBandBytestreamSession);
+
+        return inBandBytestreamSession;
+    }
+
+    /**
+     * Responses to the given IQ packet's sender with an XMPP error that an In-Band Bytestream is
+     * not accepted.
+     * 
+     * @param request IQ packet that should be answered with a not-acceptable error
+     */
+    protected void replyRejectPacket(IQ request) {
+        XMPPError xmppError = new XMPPError(XMPPError.Condition.no_acceptable);
+        IQ error = IQ.createErrorResponse(request, xmppError);
+        this.connection.sendPacket(error);
+    }
+
+    /**
+     * Responses to the given IQ packet's sender with an XMPP error that an In-Band Bytestream open
+     * request is rejected because its block size is greater than the maximum allowed block size.
+     * 
+     * @param request IQ packet that should be answered with a resource-constraint error
+     */
+    protected void replyResourceConstraintPacket(IQ request) {
+        XMPPError xmppError = new XMPPError(XMPPError.Condition.resource_constraint);
+        IQ error = IQ.createErrorResponse(request, xmppError);
+        this.connection.sendPacket(error);
+    }
+
+    /**
+     * Responses to the given IQ packet's sender with an XMPP error that an In-Band Bytestream
+     * session could not be found.
+     * 
+     * @param request IQ packet that should be answered with a item-not-found error
+     */
+    protected void replyItemNotFoundPacket(IQ request) {
+        XMPPError xmppError = new XMPPError(XMPPError.Condition.item_not_found);
+        IQ error = IQ.createErrorResponse(request, xmppError);
+        this.connection.sendPacket(error);
+    }
+
+    /**
+     * Returns a new unique session ID.
+     * 
+     * @return a new unique session ID
+     */
+    private String getNextSessionID() {
+        StringBuilder buffer = new StringBuilder();
+        buffer.append(SESSION_ID_PREFIX);
+        buffer.append(Math.abs(randomGenerator.nextLong()));
+        return buffer.toString();
+    }
+
+    /**
+     * Returns the XMPP connection.
+     * 
+     * @return the XMPP connection
+     */
+    protected Connection getConnection() {
+        return this.connection;
+    }
+
+    /**
+     * Returns the {@link InBandBytestreamListener} that should be informed if a In-Band Bytestream
+     * request from the given initiator JID is received.
+     * 
+     * @param initiator the initiator's JID
+     * @return the listener
+     */
+    protected BytestreamListener getUserListener(String initiator) {
+        return this.userListeners.get(initiator);
+    }
+
+    /**
+     * Returns a list of {@link InBandBytestreamListener} that are informed if there are no
+     * listeners for a specific initiator.
+     * 
+     * @return list of listeners
+     */
+    protected List<BytestreamListener> getAllRequestListeners() {
+        return this.allRequestListeners;
+    }
+
+    /**
+     * Returns the sessions map.
+     * 
+     * @return the sessions map
+     */
+    protected Map<String, InBandBytestreamSession> getSessions() {
+        return sessions;
+    }
+
+    /**
+     * Returns the list of session IDs that should be ignored by the InitialtionListener
+     * 
+     * @return list of session IDs
+     */
+    protected List<String> getIgnoredBytestreamRequests() {
+        return ignoredBytestreamRequests;
+    }
+
+    /**
+     * Disables the InBandBytestreamManager by removing its packet listeners and resetting its
+     * internal status.
+     */
+    private void disableService() {
+
+        // remove manager from static managers map
+        managers.remove(connection);
+
+        // remove all listeners registered by this manager
+        this.connection.removePacketListener(this.initiationListener);
+        this.connection.removePacketListener(this.dataListener);
+        this.connection.removePacketListener(this.closeListener);
+
+        // shutdown threads
+        this.initiationListener.shutdown();
+
+        // reset internal status
+        this.userListeners.clear();
+        this.allRequestListeners.clear();
+        this.sessions.clear();
+        this.ignoredBytestreamRequests.clear();
+
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamRequest.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamRequest.java
index 5bc689a..310b844 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamRequest.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamRequest.java
@@ -1,92 +1,92 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.ibb;
-
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smackx.bytestreams.BytestreamRequest;
-import org.jivesoftware.smackx.bytestreams.ibb.packet.Open;
-
-/**
- * InBandBytestreamRequest class handles incoming In-Band Bytestream requests.
- * 
- * @author Henning Staib
- */
-public class InBandBytestreamRequest implements BytestreamRequest {
-
-    /* the bytestream initialization request */
-    private final Open byteStreamRequest;
-
-    /*
-     * In-Band Bytestream manager containing the XMPP connection and helper
-     * methods
-     */
-    private final InBandBytestreamManager manager;
-
-    protected InBandBytestreamRequest(InBandBytestreamManager manager,
-                    Open byteStreamRequest) {
-        this.manager = manager;
-        this.byteStreamRequest = byteStreamRequest;
-    }
-
-    /**
-     * Returns the sender of the In-Band Bytestream open request.
-     * 
-     * @return the sender of the In-Band Bytestream open request
-     */
-    public String getFrom() {
-        return this.byteStreamRequest.getFrom();
-    }
-
-    /**
-     * Returns the session ID of the In-Band Bytestream open request.
-     * 
-     * @return the session ID of the In-Band Bytestream open request
-     */
-    public String getSessionID() {
-        return this.byteStreamRequest.getSessionID();
-    }
-
-    /**
-     * Accepts the In-Band Bytestream open request and returns the session to
-     * send/receive data.
-     * 
-     * @return the session to send/receive data
-     * @throws XMPPException if stream is invalid.
-     */
-    public InBandBytestreamSession accept() throws XMPPException {
-        Connection connection = this.manager.getConnection();
-
-        // create In-Band Bytestream session and store it
-        InBandBytestreamSession ibbSession = new InBandBytestreamSession(connection,
-                        this.byteStreamRequest, this.byteStreamRequest.getFrom());
-        this.manager.getSessions().put(this.byteStreamRequest.getSessionID(), ibbSession);
-
-        // acknowledge request
-        IQ resultIQ = IQ.createResultIQ(this.byteStreamRequest);
-        connection.sendPacket(resultIQ);
-
-        return ibbSession;
-    }
-
-    /**
-     * Rejects the In-Band Bytestream request by sending a reject error to the
-     * initiator.
-     */
-    public void reject() {
-        this.manager.replyRejectPacket(this.byteStreamRequest);
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.ibb;
+
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smackx.bytestreams.BytestreamRequest;
+import org.jivesoftware.smackx.bytestreams.ibb.packet.Open;
+
+/**
+ * InBandBytestreamRequest class handles incoming In-Band Bytestream requests.
+ * 
+ * @author Henning Staib
+ */
+public class InBandBytestreamRequest implements BytestreamRequest {
+
+    /* the bytestream initialization request */
+    private final Open byteStreamRequest;
+
+    /*
+     * In-Band Bytestream manager containing the XMPP connection and helper
+     * methods
+     */
+    private final InBandBytestreamManager manager;
+
+    protected InBandBytestreamRequest(InBandBytestreamManager manager,
+                    Open byteStreamRequest) {
+        this.manager = manager;
+        this.byteStreamRequest = byteStreamRequest;
+    }
+
+    /**
+     * Returns the sender of the In-Band Bytestream open request.
+     * 
+     * @return the sender of the In-Band Bytestream open request
+     */
+    public String getFrom() {
+        return this.byteStreamRequest.getFrom();
+    }
+
+    /**
+     * Returns the session ID of the In-Band Bytestream open request.
+     * 
+     * @return the session ID of the In-Band Bytestream open request
+     */
+    public String getSessionID() {
+        return this.byteStreamRequest.getSessionID();
+    }
+
+    /**
+     * Accepts the In-Band Bytestream open request and returns the session to
+     * send/receive data.
+     * 
+     * @return the session to send/receive data
+     * @throws XMPPException if stream is invalid.
+     */
+    public InBandBytestreamSession accept() throws XMPPException {
+        Connection connection = this.manager.getConnection();
+
+        // create In-Band Bytestream session and store it
+        InBandBytestreamSession ibbSession = new InBandBytestreamSession(connection,
+                        this.byteStreamRequest, this.byteStreamRequest.getFrom());
+        this.manager.getSessions().put(this.byteStreamRequest.getSessionID(), ibbSession);
+
+        // acknowledge request
+        IQ resultIQ = IQ.createResultIQ(this.byteStreamRequest);
+        connection.sendPacket(resultIQ);
+
+        return ibbSession;
+    }
+
+    /**
+     * Rejects the In-Band Bytestream request by sending a reject error to the
+     * initiator.
+     */
+    public void reject() {
+        this.manager.replyRejectPacket(this.byteStreamRequest);
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java
index a33682c..6323d87 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java
@@ -1,795 +1,795 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.ibb;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.SocketTimeoutException;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.PacketListener;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.filter.AndFilter;
-import org.jivesoftware.smack.filter.PacketFilter;
-import org.jivesoftware.smack.filter.PacketTypeFilter;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Message;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.packet.XMPPError;
-import org.jivesoftware.smack.util.StringUtils;
-import org.jivesoftware.smack.util.SyncPacketSend;
-import org.jivesoftware.smackx.bytestreams.BytestreamSession;
-import org.jivesoftware.smackx.bytestreams.ibb.packet.Close;
-import org.jivesoftware.smackx.bytestreams.ibb.packet.Data;
-import org.jivesoftware.smackx.bytestreams.ibb.packet.DataPacketExtension;
-import org.jivesoftware.smackx.bytestreams.ibb.packet.Open;
-
-/**
- * InBandBytestreamSession class represents an In-Band Bytestream session.
- * <p>
- * In-band bytestreams are bidirectional and this session encapsulates the streams for both
- * directions.
- * <p>
- * Note that closing the In-Band Bytestream session will close both streams. If both streams are
- * closed individually the session will be closed automatically once the second stream is closed.
- * Use the {@link #setCloseBothStreamsEnabled(boolean)} method if both streams should be closed
- * automatically if one of them is closed.
- * 
- * @author Henning Staib
- */
-public class InBandBytestreamSession implements BytestreamSession {
-
-    /* XMPP connection */
-    private final Connection connection;
-
-    /* the In-Band Bytestream open request for this session */
-    private final Open byteStreamRequest;
-
-    /*
-     * the input stream for this session (either IQIBBInputStream or MessageIBBInputStream)
-     */
-    private IBBInputStream inputStream;
-
-    /*
-     * the output stream for this session (either IQIBBOutputStream or MessageIBBOutputStream)
-     */
-    private IBBOutputStream outputStream;
-
-    /* JID of the remote peer */
-    private String remoteJID;
-
-    /* flag to close both streams if one of them is closed */
-    private boolean closeBothStreamsEnabled = false;
-
-    /* flag to indicate if session is closed */
-    private boolean isClosed = false;
-
-    /**
-     * Constructor.
-     * 
-     * @param connection the XMPP connection
-     * @param byteStreamRequest the In-Band Bytestream open request for this session
-     * @param remoteJID JID of the remote peer
-     */
-    protected InBandBytestreamSession(Connection connection, Open byteStreamRequest,
-                    String remoteJID) {
-        this.connection = connection;
-        this.byteStreamRequest = byteStreamRequest;
-        this.remoteJID = remoteJID;
-
-        // initialize streams dependent to the uses stanza type
-        switch (byteStreamRequest.getStanza()) {
-        case IQ:
-            this.inputStream = new IQIBBInputStream();
-            this.outputStream = new IQIBBOutputStream();
-            break;
-        case MESSAGE:
-            this.inputStream = new MessageIBBInputStream();
-            this.outputStream = new MessageIBBOutputStream();
-            break;
-        }
-
-    }
-
-    public InputStream getInputStream() {
-        return this.inputStream;
-    }
-
-    public OutputStream getOutputStream() {
-        return this.outputStream;
-    }
-
-    public int getReadTimeout() {
-        return this.inputStream.readTimeout;
-    }
-
-    public void setReadTimeout(int timeout) {
-        if (timeout < 0) {
-            throw new IllegalArgumentException("Timeout must be >= 0");
-        }
-        this.inputStream.readTimeout = timeout;
-    }
-
-    /**
-     * Returns whether both streams should be closed automatically if one of the streams is closed.
-     * Default is <code>false</code>.
-     * 
-     * @return <code>true</code> if both streams will be closed if one of the streams is closed,
-     *         <code>false</code> if both streams can be closed independently.
-     */
-    public boolean isCloseBothStreamsEnabled() {
-        return closeBothStreamsEnabled;
-    }
-
-    /**
-     * Sets whether both streams should be closed automatically if one of the streams is closed.
-     * Default is <code>false</code>.
-     * 
-     * @param closeBothStreamsEnabled <code>true</code> if both streams should be closed if one of
-     *        the streams is closed, <code>false</code> if both streams should be closed
-     *        independently
-     */
-    public void setCloseBothStreamsEnabled(boolean closeBothStreamsEnabled) {
-        this.closeBothStreamsEnabled = closeBothStreamsEnabled;
-    }
-
-    public void close() throws IOException {
-        closeByLocal(true); // close input stream
-        closeByLocal(false); // close output stream
-    }
-
-    /**
-     * This method is invoked if a request to close the In-Band Bytestream has been received.
-     * 
-     * @param closeRequest the close request from the remote peer
-     */
-    protected void closeByPeer(Close closeRequest) {
-
-        /*
-         * close streams without flushing them, because stream is already considered closed on the
-         * remote peers side
-         */
-        this.inputStream.closeInternal();
-        this.inputStream.cleanup();
-        this.outputStream.closeInternal(false);
-
-        // acknowledge close request
-        IQ confirmClose = IQ.createResultIQ(closeRequest);
-        this.connection.sendPacket(confirmClose);
-
-    }
-
-    /**
-     * This method is invoked if one of the streams has been closed locally, if an error occurred
-     * locally or if the whole session should be closed.
-     * 
-     * @throws IOException if an error occurs while sending the close request
-     */
-    protected synchronized void closeByLocal(boolean in) throws IOException {
-        if (this.isClosed) {
-            return;
-        }
-
-        if (this.closeBothStreamsEnabled) {
-            this.inputStream.closeInternal();
-            this.outputStream.closeInternal(true);
-        }
-        else {
-            if (in) {
-                this.inputStream.closeInternal();
-            }
-            else {
-                // close stream but try to send any data left
-                this.outputStream.closeInternal(true);
-            }
-        }
-
-        if (this.inputStream.isClosed && this.outputStream.isClosed) {
-            this.isClosed = true;
-
-            // send close request
-            Close close = new Close(this.byteStreamRequest.getSessionID());
-            close.setTo(this.remoteJID);
-            try {
-                SyncPacketSend.getReply(this.connection, close);
-            }
-            catch (XMPPException e) {
-                throw new IOException("Error while closing stream: " + e.getMessage());
-            }
-
-            this.inputStream.cleanup();
-
-            // remove session from manager
-            InBandBytestreamManager.getByteStreamManager(this.connection).getSessions().remove(this);
-        }
-
-    }
-
-    /**
-     * IBBInputStream class is the base implementation of an In-Band Bytestream input stream.
-     * Subclasses of this input stream must provide a packet listener along with a packet filter to
-     * collect the In-Band Bytestream data packets.
-     */
-    private abstract class IBBInputStream extends InputStream {
-
-        /* the data packet listener to fill the data queue */
-        private final PacketListener dataPacketListener;
-
-        /* queue containing received In-Band Bytestream data packets */
-        protected final BlockingQueue<DataPacketExtension> dataQueue = new LinkedBlockingQueue<DataPacketExtension>();
-
-        /* buffer containing the data from one data packet */
-        private byte[] buffer;
-
-        /* pointer to the next byte to read from buffer */
-        private int bufferPointer = -1;
-
-        /* data packet sequence (range from 0 to 65535) */
-        private long seq = -1;
-
-        /* flag to indicate if input stream is closed */
-        private boolean isClosed = false;
-
-        /* flag to indicate if close method was invoked */
-        private boolean closeInvoked = false;
-
-        /* timeout for read operations */
-        private int readTimeout = 0;
-
-        /**
-         * Constructor.
-         */
-        public IBBInputStream() {
-            // add data packet listener to connection
-            this.dataPacketListener = getDataPacketListener();
-            connection.addPacketListener(this.dataPacketListener, getDataPacketFilter());
-        }
-
-        /**
-         * Returns the packet listener that processes In-Band Bytestream data packets.
-         * 
-         * @return the data packet listener
-         */
-        protected abstract PacketListener getDataPacketListener();
-
-        /**
-         * Returns the packet filter that accepts In-Band Bytestream data packets.
-         * 
-         * @return the data packet filter
-         */
-        protected abstract PacketFilter getDataPacketFilter();
-
-        public synchronized int read() throws IOException {
-            checkClosed();
-
-            // if nothing read yet or whole buffer has been read fill buffer
-            if (bufferPointer == -1 || bufferPointer >= buffer.length) {
-                // if no data available and stream was closed return -1
-                if (!loadBuffer()) {
-                    return -1;
-                }
-            }
-
-            // return byte and increment buffer pointer
-            return ((int) buffer[bufferPointer++]) & 0xff;
-        }
-
-        public synchronized int read(byte[] b, int off, int len) throws IOException {
-            if (b == null) {
-                throw new NullPointerException();
-            }
-            else if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length)
-                            || ((off + len) < 0)) {
-                throw new IndexOutOfBoundsException();
-            }
-            else if (len == 0) {
-                return 0;
-            }
-
-            checkClosed();
-
-            // if nothing read yet or whole buffer has been read fill buffer
-            if (bufferPointer == -1 || bufferPointer >= buffer.length) {
-                // if no data available and stream was closed return -1
-                if (!loadBuffer()) {
-                    return -1;
-                }
-            }
-
-            // if more bytes wanted than available return all available
-            int bytesAvailable = buffer.length - bufferPointer;
-            if (len > bytesAvailable) {
-                len = bytesAvailable;
-            }
-
-            System.arraycopy(buffer, bufferPointer, b, off, len);
-            bufferPointer += len;
-            return len;
-        }
-
-        public synchronized int read(byte[] b) throws IOException {
-            return read(b, 0, b.length);
-        }
-
-        /**
-         * This method blocks until a data packet is received, the stream is closed or the current
-         * thread is interrupted.
-         * 
-         * @return <code>true</code> if data was received, otherwise <code>false</code>
-         * @throws IOException if data packets are out of sequence
-         */
-        private synchronized boolean loadBuffer() throws IOException {
-
-            // wait until data is available or stream is closed
-            DataPacketExtension data = null;
-            try {
-                if (this.readTimeout == 0) {
-                    while (data == null) {
-                        if (isClosed && this.dataQueue.isEmpty()) {
-                            return false;
-                        }
-                        data = this.dataQueue.poll(1000, TimeUnit.MILLISECONDS);
-                    }
-                }
-                else {
-                    data = this.dataQueue.poll(this.readTimeout, TimeUnit.MILLISECONDS);
-                    if (data == null) {
-                        throw new SocketTimeoutException();
-                    }
-                }
-            }
-            catch (InterruptedException e) {
-                // Restore the interrupted status
-                Thread.currentThread().interrupt();
-                return false;
-            }
-
-            // handle sequence overflow
-            if (this.seq == 65535) {
-                this.seq = -1;
-            }
-
-            // check if data packets sequence is successor of last seen sequence
-            long seq = data.getSeq();
-            if (seq - 1 != this.seq) {
-                // packets out of order; close stream/session
-                InBandBytestreamSession.this.close();
-                throw new IOException("Packets out of sequence");
-            }
-            else {
-                this.seq = seq;
-            }
-
-            // set buffer to decoded data
-            buffer = data.getDecodedData();
-            bufferPointer = 0;
-            return true;
-        }
-
-        /**
-         * Checks if this stream is closed and throws an IOException if necessary
-         * 
-         * @throws IOException if stream is closed and no data should be read anymore
-         */
-        private void checkClosed() throws IOException {
-            /* throw no exception if there is data available, but not if close method was invoked */
-            if ((isClosed && this.dataQueue.isEmpty()) || closeInvoked) {
-                // clear data queue in case additional data was received after stream was closed
-                this.dataQueue.clear();
-                throw new IOException("Stream is closed");
-            }
-        }
-
-        public boolean markSupported() {
-            return false;
-        }
-
-        public void close() throws IOException {
-            if (isClosed) {
-                return;
-            }
-
-            this.closeInvoked = true;
-
-            InBandBytestreamSession.this.closeByLocal(true);
-        }
-
-        /**
-         * This method sets the close flag and removes the data packet listener.
-         */
-        private void closeInternal() {
-            if (isClosed) {
-                return;
-            }
-            isClosed = true;
-        }
-
-        /**
-         * Invoked if the session is closed.
-         */
-        private void cleanup() {
-            connection.removePacketListener(this.dataPacketListener);
-        }
-
-    }
-
-    /**
-     * IQIBBInputStream class implements IBBInputStream to be used with IQ stanzas encapsulating the
-     * data packets.
-     */
-    private class IQIBBInputStream extends IBBInputStream {
-
-        protected PacketListener getDataPacketListener() {
-            return new PacketListener() {
-
-                private long lastSequence = -1;
-
-                public void processPacket(Packet packet) {
-                    // get data packet extension
-                    DataPacketExtension data = (DataPacketExtension) packet.getExtension(
-                                    DataPacketExtension.ELEMENT_NAME,
-                                    InBandBytestreamManager.NAMESPACE);
-
-                    /*
-                     * check if sequence was not used already (see XEP-0047 Section 2.2)
-                     */
-                    if (data.getSeq() <= this.lastSequence) {
-                        IQ unexpectedRequest = IQ.createErrorResponse((IQ) packet, new XMPPError(
-                                        XMPPError.Condition.unexpected_request));
-                        connection.sendPacket(unexpectedRequest);
-                        return;
-
-                    }
-
-                    // check if encoded data is valid (see XEP-0047 Section 2.2)
-                    if (data.getDecodedData() == null) {
-                        // data is invalid; respond with bad-request error
-                        IQ badRequest = IQ.createErrorResponse((IQ) packet, new XMPPError(
-                                        XMPPError.Condition.bad_request));
-                        connection.sendPacket(badRequest);
-                        return;
-                    }
-
-                    // data is valid; add to data queue
-                    dataQueue.offer(data);
-
-                    // confirm IQ
-                    IQ confirmData = IQ.createResultIQ((IQ) packet);
-                    connection.sendPacket(confirmData);
-
-                    // set last seen sequence
-                    this.lastSequence = data.getSeq();
-                    if (this.lastSequence == 65535) {
-                        this.lastSequence = -1;
-                    }
-
-                }
-
-            };
-        }
-
-        protected PacketFilter getDataPacketFilter() {
-            /*
-             * filter all IQ stanzas having type 'SET' (represented by Data class), containing a
-             * data packet extension, matching session ID and recipient
-             */
-            return new AndFilter(new PacketTypeFilter(Data.class), new IBBDataPacketFilter());
-        }
-
-    }
-
-    /**
-     * MessageIBBInputStream class implements IBBInputStream to be used with message stanzas
-     * encapsulating the data packets.
-     */
-    private class MessageIBBInputStream extends IBBInputStream {
-
-        protected PacketListener getDataPacketListener() {
-            return new PacketListener() {
-
-                public void processPacket(Packet packet) {
-                    // get data packet extension
-                    DataPacketExtension data = (DataPacketExtension) packet.getExtension(
-                                    DataPacketExtension.ELEMENT_NAME,
-                                    InBandBytestreamManager.NAMESPACE);
-
-                    // check if encoded data is valid
-                    if (data.getDecodedData() == null) {
-                        /*
-                         * TODO once a majority of XMPP server implementation support XEP-0079
-                         * Advanced Message Processing the invalid message could be answered with an
-                         * appropriate error. For now we just ignore the packet. Subsequent packets
-                         * with an increased sequence will cause the input stream to close the
-                         * stream/session.
-                         */
-                        return;
-                    }
-
-                    // data is valid; add to data queue
-                    dataQueue.offer(data);
-
-                    // TODO confirm packet once XMPP servers support XEP-0079
-                }
-
-            };
-        }
-
-        @Override
-        protected PacketFilter getDataPacketFilter() {
-            /*
-             * filter all message stanzas containing a data packet extension, matching session ID
-             * and recipient
-             */
-            return new AndFilter(new PacketTypeFilter(Message.class), new IBBDataPacketFilter());
-        }
-
-    }
-
-    /**
-     * IBBDataPacketFilter class filters all packets from the remote peer of this session,
-     * containing an In-Band Bytestream data packet extension whose session ID matches this sessions
-     * ID.
-     */
-    private class IBBDataPacketFilter implements PacketFilter {
-
-        public boolean accept(Packet packet) {
-            // sender equals remote peer
-            if (!packet.getFrom().equalsIgnoreCase(remoteJID)) {
-                return false;
-            }
-
-            // stanza contains data packet extension
-            PacketExtension packetExtension = packet.getExtension(DataPacketExtension.ELEMENT_NAME,
-                            InBandBytestreamManager.NAMESPACE);
-            if (packetExtension == null || !(packetExtension instanceof DataPacketExtension)) {
-                return false;
-            }
-
-            // session ID equals this session ID
-            DataPacketExtension data = (DataPacketExtension) packetExtension;
-            if (!data.getSessionID().equals(byteStreamRequest.getSessionID())) {
-                return false;
-            }
-
-            return true;
-        }
-
-    }
-
-    /**
-     * IBBOutputStream class is the base implementation of an In-Band Bytestream output stream.
-     * Subclasses of this output stream must provide a method to send data over XMPP stream.
-     */
-    private abstract class IBBOutputStream extends OutputStream {
-
-        /* buffer with the size of this sessions block size */
-        protected final byte[] buffer;
-
-        /* pointer to next byte to write to buffer */
-        protected int bufferPointer = 0;
-
-        /* data packet sequence (range from 0 to 65535) */
-        protected long seq = 0;
-
-        /* flag to indicate if output stream is closed */
-        protected boolean isClosed = false;
-
-        /**
-         * Constructor.
-         */
-        public IBBOutputStream() {
-            this.buffer = new byte[(byteStreamRequest.getBlockSize()/4)*3];
-        }
-
-        /**
-         * Writes the given data packet to the XMPP stream.
-         * 
-         * @param data the data packet
-         * @throws IOException if an I/O error occurred while sending or if the stream is closed
-         */
-        protected abstract void writeToXML(DataPacketExtension data) throws IOException;
-
-        public synchronized void write(int b) throws IOException {
-            if (this.isClosed) {
-                throw new IOException("Stream is closed");
-            }
-
-            // if buffer is full flush buffer
-            if (bufferPointer >= buffer.length) {
-                flushBuffer();
-            }
-
-            buffer[bufferPointer++] = (byte) b;
-        }
-
-        public synchronized void write(byte b[], int off, int len) throws IOException {
-            if (b == null) {
-                throw new NullPointerException();
-            }
-            else if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length)
-                            || ((off + len) < 0)) {
-                throw new IndexOutOfBoundsException();
-            }
-            else if (len == 0) {
-                return;
-            }
-
-            if (this.isClosed) {
-                throw new IOException("Stream is closed");
-            }
-
-            // is data to send greater than buffer size
-            if (len >= buffer.length) {
-
-                // "byte" off the first chunk to write out
-                writeOut(b, off, buffer.length);
-
-                // recursively call this method with the lesser amount
-                write(b, off + buffer.length, len - buffer.length);
-            }
-            else {
-                writeOut(b, off, len);
-            }
-        }
-
-        public synchronized void write(byte[] b) throws IOException {
-            write(b, 0, b.length);
-        }
-
-        /**
-         * Fills the buffer with the given data and sends it over the XMPP stream if the buffers
-         * capacity has been reached. This method is only called from this class so it is assured
-         * that the amount of data to send is <= buffer capacity
-         * 
-         * @param b the data
-         * @param off the data
-         * @param len the number of bytes to write
-         * @throws IOException if an I/O error occurred while sending or if the stream is closed
-         */
-        private synchronized void writeOut(byte b[], int off, int len) throws IOException {
-            if (this.isClosed) {
-                throw new IOException("Stream is closed");
-            }
-
-            // set to 0 in case the next 'if' block is not executed
-            int available = 0;
-
-            // is data to send greater that buffer space left
-            if (len > buffer.length - bufferPointer) {
-                // fill buffer to capacity and send it
-                available = buffer.length - bufferPointer;
-                System.arraycopy(b, off, buffer, bufferPointer, available);
-                bufferPointer += available;
-                flushBuffer();
-            }
-
-            // copy the data left to buffer
-            System.arraycopy(b, off + available, buffer, bufferPointer, len - available);
-            bufferPointer += len - available;
-        }
-
-        public synchronized void flush() throws IOException {
-            if (this.isClosed) {
-                throw new IOException("Stream is closed");
-            }
-            flushBuffer();
-        }
-
-        private synchronized void flushBuffer() throws IOException {
-
-            // do nothing if no data to send available
-            if (bufferPointer == 0) {
-                return;
-            }
-
-            // create data packet
-            String enc = StringUtils.encodeBase64(buffer, 0, bufferPointer, false);
-            DataPacketExtension data = new DataPacketExtension(byteStreamRequest.getSessionID(),
-                            this.seq, enc);
-
-            // write to XMPP stream
-            writeToXML(data);
-
-            // reset buffer pointer
-            bufferPointer = 0;
-
-            // increment sequence, considering sequence overflow
-            this.seq = (this.seq + 1 == 65535 ? 0 : this.seq + 1);
-
-        }
-
-        public void close() throws IOException {
-            if (isClosed) {
-                return;
-            }
-            InBandBytestreamSession.this.closeByLocal(false);
-        }
-
-        /**
-         * Sets the close flag and optionally flushes the stream.
-         * 
-         * @param flush if <code>true</code> flushes the stream
-         */
-        protected void closeInternal(boolean flush) {
-            if (this.isClosed) {
-                return;
-            }
-            this.isClosed = true;
-
-            try {
-                if (flush) {
-                    flushBuffer();
-                }
-            }
-            catch (IOException e) {
-                /*
-                 * ignore, because writeToXML() will not throw an exception if stream is already
-                 * closed
-                 */
-            }
-        }
-
-    }
-
-    /**
-     * IQIBBOutputStream class implements IBBOutputStream to be used with IQ stanzas encapsulating
-     * the data packets.
-     */
-    private class IQIBBOutputStream extends IBBOutputStream {
-
-        @Override
-        protected synchronized void writeToXML(DataPacketExtension data) throws IOException {
-            // create IQ stanza containing data packet
-            IQ iq = new Data(data);
-            iq.setTo(remoteJID);
-
-            try {
-                SyncPacketSend.getReply(connection, iq);
-            }
-            catch (XMPPException e) {
-                // close session unless it is already closed
-                if (!this.isClosed) {
-                    InBandBytestreamSession.this.close();
-                    throw new IOException("Error while sending Data: " + e.getMessage());
-                }
-            }
-
-        }
-
-    }
-
-    /**
-     * MessageIBBOutputStream class implements IBBOutputStream to be used with message stanzas
-     * encapsulating the data packets.
-     */
-    private class MessageIBBOutputStream extends IBBOutputStream {
-
-        @Override
-        protected synchronized void writeToXML(DataPacketExtension data) {
-            // create message stanza containing data packet
-            Message message = new Message(remoteJID);
-            message.addExtension(data);
-
-            connection.sendPacket(message);
-
-        }
-
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.ibb;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.SocketTimeoutException;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.PacketListener;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.filter.AndFilter;
+import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.filter.PacketTypeFilter;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Message;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.packet.XMPPError;
+import org.jivesoftware.smack.util.StringUtils;
+import org.jivesoftware.smack.util.SyncPacketSend;
+import org.jivesoftware.smackx.bytestreams.BytestreamSession;
+import org.jivesoftware.smackx.bytestreams.ibb.packet.Close;
+import org.jivesoftware.smackx.bytestreams.ibb.packet.Data;
+import org.jivesoftware.smackx.bytestreams.ibb.packet.DataPacketExtension;
+import org.jivesoftware.smackx.bytestreams.ibb.packet.Open;
+
+/**
+ * InBandBytestreamSession class represents an In-Band Bytestream session.
+ * <p>
+ * In-band bytestreams are bidirectional and this session encapsulates the streams for both
+ * directions.
+ * <p>
+ * Note that closing the In-Band Bytestream session will close both streams. If both streams are
+ * closed individually the session will be closed automatically once the second stream is closed.
+ * Use the {@link #setCloseBothStreamsEnabled(boolean)} method if both streams should be closed
+ * automatically if one of them is closed.
+ * 
+ * @author Henning Staib
+ */
+public class InBandBytestreamSession implements BytestreamSession {
+
+    /* XMPP connection */
+    private final Connection connection;
+
+    /* the In-Band Bytestream open request for this session */
+    private final Open byteStreamRequest;
+
+    /*
+     * the input stream for this session (either IQIBBInputStream or MessageIBBInputStream)
+     */
+    private IBBInputStream inputStream;
+
+    /*
+     * the output stream for this session (either IQIBBOutputStream or MessageIBBOutputStream)
+     */
+    private IBBOutputStream outputStream;
+
+    /* JID of the remote peer */
+    private String remoteJID;
+
+    /* flag to close both streams if one of them is closed */
+    private boolean closeBothStreamsEnabled = false;
+
+    /* flag to indicate if session is closed */
+    private boolean isClosed = false;
+
+    /**
+     * Constructor.
+     * 
+     * @param connection the XMPP connection
+     * @param byteStreamRequest the In-Band Bytestream open request for this session
+     * @param remoteJID JID of the remote peer
+     */
+    protected InBandBytestreamSession(Connection connection, Open byteStreamRequest,
+                    String remoteJID) {
+        this.connection = connection;
+        this.byteStreamRequest = byteStreamRequest;
+        this.remoteJID = remoteJID;
+
+        // initialize streams dependent to the uses stanza type
+        switch (byteStreamRequest.getStanza()) {
+        case IQ:
+            this.inputStream = new IQIBBInputStream();
+            this.outputStream = new IQIBBOutputStream();
+            break;
+        case MESSAGE:
+            this.inputStream = new MessageIBBInputStream();
+            this.outputStream = new MessageIBBOutputStream();
+            break;
+        }
+
+    }
+
+    public InputStream getInputStream() {
+        return this.inputStream;
+    }
+
+    public OutputStream getOutputStream() {
+        return this.outputStream;
+    }
+
+    public int getReadTimeout() {
+        return this.inputStream.readTimeout;
+    }
+
+    public void setReadTimeout(int timeout) {
+        if (timeout < 0) {
+            throw new IllegalArgumentException("Timeout must be >= 0");
+        }
+        this.inputStream.readTimeout = timeout;
+    }
+
+    /**
+     * Returns whether both streams should be closed automatically if one of the streams is closed.
+     * Default is <code>false</code>.
+     * 
+     * @return <code>true</code> if both streams will be closed if one of the streams is closed,
+     *         <code>false</code> if both streams can be closed independently.
+     */
+    public boolean isCloseBothStreamsEnabled() {
+        return closeBothStreamsEnabled;
+    }
+
+    /**
+     * Sets whether both streams should be closed automatically if one of the streams is closed.
+     * Default is <code>false</code>.
+     * 
+     * @param closeBothStreamsEnabled <code>true</code> if both streams should be closed if one of
+     *        the streams is closed, <code>false</code> if both streams should be closed
+     *        independently
+     */
+    public void setCloseBothStreamsEnabled(boolean closeBothStreamsEnabled) {
+        this.closeBothStreamsEnabled = closeBothStreamsEnabled;
+    }
+
+    public void close() throws IOException {
+        closeByLocal(true); // close input stream
+        closeByLocal(false); // close output stream
+    }
+
+    /**
+     * This method is invoked if a request to close the In-Band Bytestream has been received.
+     * 
+     * @param closeRequest the close request from the remote peer
+     */
+    protected void closeByPeer(Close closeRequest) {
+
+        /*
+         * close streams without flushing them, because stream is already considered closed on the
+         * remote peers side
+         */
+        this.inputStream.closeInternal();
+        this.inputStream.cleanup();
+        this.outputStream.closeInternal(false);
+
+        // acknowledge close request
+        IQ confirmClose = IQ.createResultIQ(closeRequest);
+        this.connection.sendPacket(confirmClose);
+
+    }
+
+    /**
+     * This method is invoked if one of the streams has been closed locally, if an error occurred
+     * locally or if the whole session should be closed.
+     * 
+     * @throws IOException if an error occurs while sending the close request
+     */
+    protected synchronized void closeByLocal(boolean in) throws IOException {
+        if (this.isClosed) {
+            return;
+        }
+
+        if (this.closeBothStreamsEnabled) {
+            this.inputStream.closeInternal();
+            this.outputStream.closeInternal(true);
+        }
+        else {
+            if (in) {
+                this.inputStream.closeInternal();
+            }
+            else {
+                // close stream but try to send any data left
+                this.outputStream.closeInternal(true);
+            }
+        }
+
+        if (this.inputStream.isClosed && this.outputStream.isClosed) {
+            this.isClosed = true;
+
+            // send close request
+            Close close = new Close(this.byteStreamRequest.getSessionID());
+            close.setTo(this.remoteJID);
+            try {
+                SyncPacketSend.getReply(this.connection, close);
+            }
+            catch (XMPPException e) {
+                throw new IOException("Error while closing stream: " + e.getMessage());
+            }
+
+            this.inputStream.cleanup();
+
+            // remove session from manager
+            InBandBytestreamManager.getByteStreamManager(this.connection).getSessions().remove(this);
+        }
+
+    }
+
+    /**
+     * IBBInputStream class is the base implementation of an In-Band Bytestream input stream.
+     * Subclasses of this input stream must provide a packet listener along with a packet filter to
+     * collect the In-Band Bytestream data packets.
+     */
+    private abstract class IBBInputStream extends InputStream {
+
+        /* the data packet listener to fill the data queue */
+        private final PacketListener dataPacketListener;
+
+        /* queue containing received In-Band Bytestream data packets */
+        protected final BlockingQueue<DataPacketExtension> dataQueue = new LinkedBlockingQueue<DataPacketExtension>();
+
+        /* buffer containing the data from one data packet */
+        private byte[] buffer;
+
+        /* pointer to the next byte to read from buffer */
+        private int bufferPointer = -1;
+
+        /* data packet sequence (range from 0 to 65535) */
+        private long seq = -1;
+
+        /* flag to indicate if input stream is closed */
+        private boolean isClosed = false;
+
+        /* flag to indicate if close method was invoked */
+        private boolean closeInvoked = false;
+
+        /* timeout for read operations */
+        private int readTimeout = 0;
+
+        /**
+         * Constructor.
+         */
+        public IBBInputStream() {
+            // add data packet listener to connection
+            this.dataPacketListener = getDataPacketListener();
+            connection.addPacketListener(this.dataPacketListener, getDataPacketFilter());
+        }
+
+        /**
+         * Returns the packet listener that processes In-Band Bytestream data packets.
+         * 
+         * @return the data packet listener
+         */
+        protected abstract PacketListener getDataPacketListener();
+
+        /**
+         * Returns the packet filter that accepts In-Band Bytestream data packets.
+         * 
+         * @return the data packet filter
+         */
+        protected abstract PacketFilter getDataPacketFilter();
+
+        public synchronized int read() throws IOException {
+            checkClosed();
+
+            // if nothing read yet or whole buffer has been read fill buffer
+            if (bufferPointer == -1 || bufferPointer >= buffer.length) {
+                // if no data available and stream was closed return -1
+                if (!loadBuffer()) {
+                    return -1;
+                }
+            }
+
+            // return byte and increment buffer pointer
+            return ((int) buffer[bufferPointer++]) & 0xff;
+        }
+
+        public synchronized int read(byte[] b, int off, int len) throws IOException {
+            if (b == null) {
+                throw new NullPointerException();
+            }
+            else if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length)
+                            || ((off + len) < 0)) {
+                throw new IndexOutOfBoundsException();
+            }
+            else if (len == 0) {
+                return 0;
+            }
+
+            checkClosed();
+
+            // if nothing read yet or whole buffer has been read fill buffer
+            if (bufferPointer == -1 || bufferPointer >= buffer.length) {
+                // if no data available and stream was closed return -1
+                if (!loadBuffer()) {
+                    return -1;
+                }
+            }
+
+            // if more bytes wanted than available return all available
+            int bytesAvailable = buffer.length - bufferPointer;
+            if (len > bytesAvailable) {
+                len = bytesAvailable;
+            }
+
+            System.arraycopy(buffer, bufferPointer, b, off, len);
+            bufferPointer += len;
+            return len;
+        }
+
+        public synchronized int read(byte[] b) throws IOException {
+            return read(b, 0, b.length);
+        }
+
+        /**
+         * This method blocks until a data packet is received, the stream is closed or the current
+         * thread is interrupted.
+         * 
+         * @return <code>true</code> if data was received, otherwise <code>false</code>
+         * @throws IOException if data packets are out of sequence
+         */
+        private synchronized boolean loadBuffer() throws IOException {
+
+            // wait until data is available or stream is closed
+            DataPacketExtension data = null;
+            try {
+                if (this.readTimeout == 0) {
+                    while (data == null) {
+                        if (isClosed && this.dataQueue.isEmpty()) {
+                            return false;
+                        }
+                        data = this.dataQueue.poll(1000, TimeUnit.MILLISECONDS);
+                    }
+                }
+                else {
+                    data = this.dataQueue.poll(this.readTimeout, TimeUnit.MILLISECONDS);
+                    if (data == null) {
+                        throw new SocketTimeoutException();
+                    }
+                }
+            }
+            catch (InterruptedException e) {
+                // Restore the interrupted status
+                Thread.currentThread().interrupt();
+                return false;
+            }
+
+            // handle sequence overflow
+            if (this.seq == 65535) {
+                this.seq = -1;
+            }
+
+            // check if data packets sequence is successor of last seen sequence
+            long seq = data.getSeq();
+            if (seq - 1 != this.seq) {
+                // packets out of order; close stream/session
+                InBandBytestreamSession.this.close();
+                throw new IOException("Packets out of sequence");
+            }
+            else {
+                this.seq = seq;
+            }
+
+            // set buffer to decoded data
+            buffer = data.getDecodedData();
+            bufferPointer = 0;
+            return true;
+        }
+
+        /**
+         * Checks if this stream is closed and throws an IOException if necessary
+         * 
+         * @throws IOException if stream is closed and no data should be read anymore
+         */
+        private void checkClosed() throws IOException {
+            /* throw no exception if there is data available, but not if close method was invoked */
+            if ((isClosed && this.dataQueue.isEmpty()) || closeInvoked) {
+                // clear data queue in case additional data was received after stream was closed
+                this.dataQueue.clear();
+                throw new IOException("Stream is closed");
+            }
+        }
+
+        public boolean markSupported() {
+            return false;
+        }
+
+        public void close() throws IOException {
+            if (isClosed) {
+                return;
+            }
+
+            this.closeInvoked = true;
+
+            InBandBytestreamSession.this.closeByLocal(true);
+        }
+
+        /**
+         * This method sets the close flag and removes the data packet listener.
+         */
+        private void closeInternal() {
+            if (isClosed) {
+                return;
+            }
+            isClosed = true;
+        }
+
+        /**
+         * Invoked if the session is closed.
+         */
+        private void cleanup() {
+            connection.removePacketListener(this.dataPacketListener);
+        }
+
+    }
+
+    /**
+     * IQIBBInputStream class implements IBBInputStream to be used with IQ stanzas encapsulating the
+     * data packets.
+     */
+    private class IQIBBInputStream extends IBBInputStream {
+
+        protected PacketListener getDataPacketListener() {
+            return new PacketListener() {
+
+                private long lastSequence = -1;
+
+                public void processPacket(Packet packet) {
+                    // get data packet extension
+                    DataPacketExtension data = (DataPacketExtension) packet.getExtension(
+                                    DataPacketExtension.ELEMENT_NAME,
+                                    InBandBytestreamManager.NAMESPACE);
+
+                    /*
+                     * check if sequence was not used already (see XEP-0047 Section 2.2)
+                     */
+                    if (data.getSeq() <= this.lastSequence) {
+                        IQ unexpectedRequest = IQ.createErrorResponse((IQ) packet, new XMPPError(
+                                        XMPPError.Condition.unexpected_request));
+                        connection.sendPacket(unexpectedRequest);
+                        return;
+
+                    }
+
+                    // check if encoded data is valid (see XEP-0047 Section 2.2)
+                    if (data.getDecodedData() == null) {
+                        // data is invalid; respond with bad-request error
+                        IQ badRequest = IQ.createErrorResponse((IQ) packet, new XMPPError(
+                                        XMPPError.Condition.bad_request));
+                        connection.sendPacket(badRequest);
+                        return;
+                    }
+
+                    // data is valid; add to data queue
+                    dataQueue.offer(data);
+
+                    // confirm IQ
+                    IQ confirmData = IQ.createResultIQ((IQ) packet);
+                    connection.sendPacket(confirmData);
+
+                    // set last seen sequence
+                    this.lastSequence = data.getSeq();
+                    if (this.lastSequence == 65535) {
+                        this.lastSequence = -1;
+                    }
+
+                }
+
+            };
+        }
+
+        protected PacketFilter getDataPacketFilter() {
+            /*
+             * filter all IQ stanzas having type 'SET' (represented by Data class), containing a
+             * data packet extension, matching session ID and recipient
+             */
+            return new AndFilter(new PacketTypeFilter(Data.class), new IBBDataPacketFilter());
+        }
+
+    }
+
+    /**
+     * MessageIBBInputStream class implements IBBInputStream to be used with message stanzas
+     * encapsulating the data packets.
+     */
+    private class MessageIBBInputStream extends IBBInputStream {
+
+        protected PacketListener getDataPacketListener() {
+            return new PacketListener() {
+
+                public void processPacket(Packet packet) {
+                    // get data packet extension
+                    DataPacketExtension data = (DataPacketExtension) packet.getExtension(
+                                    DataPacketExtension.ELEMENT_NAME,
+                                    InBandBytestreamManager.NAMESPACE);
+
+                    // check if encoded data is valid
+                    if (data.getDecodedData() == null) {
+                        /*
+                         * TODO once a majority of XMPP server implementation support XEP-0079
+                         * Advanced Message Processing the invalid message could be answered with an
+                         * appropriate error. For now we just ignore the packet. Subsequent packets
+                         * with an increased sequence will cause the input stream to close the
+                         * stream/session.
+                         */
+                        return;
+                    }
+
+                    // data is valid; add to data queue
+                    dataQueue.offer(data);
+
+                    // TODO confirm packet once XMPP servers support XEP-0079
+                }
+
+            };
+        }
+
+        @Override
+        protected PacketFilter getDataPacketFilter() {
+            /*
+             * filter all message stanzas containing a data packet extension, matching session ID
+             * and recipient
+             */
+            return new AndFilter(new PacketTypeFilter(Message.class), new IBBDataPacketFilter());
+        }
+
+    }
+
+    /**
+     * IBBDataPacketFilter class filters all packets from the remote peer of this session,
+     * containing an In-Band Bytestream data packet extension whose session ID matches this sessions
+     * ID.
+     */
+    private class IBBDataPacketFilter implements PacketFilter {
+
+        public boolean accept(Packet packet) {
+            // sender equals remote peer
+            if (!packet.getFrom().equalsIgnoreCase(remoteJID)) {
+                return false;
+            }
+
+            // stanza contains data packet extension
+            PacketExtension packetExtension = packet.getExtension(DataPacketExtension.ELEMENT_NAME,
+                            InBandBytestreamManager.NAMESPACE);
+            if (packetExtension == null || !(packetExtension instanceof DataPacketExtension)) {
+                return false;
+            }
+
+            // session ID equals this session ID
+            DataPacketExtension data = (DataPacketExtension) packetExtension;
+            if (!data.getSessionID().equals(byteStreamRequest.getSessionID())) {
+                return false;
+            }
+
+            return true;
+        }
+
+    }
+
+    /**
+     * IBBOutputStream class is the base implementation of an In-Band Bytestream output stream.
+     * Subclasses of this output stream must provide a method to send data over XMPP stream.
+     */
+    private abstract class IBBOutputStream extends OutputStream {
+
+        /* buffer with the size of this sessions block size */
+        protected final byte[] buffer;
+
+        /* pointer to next byte to write to buffer */
+        protected int bufferPointer = 0;
+
+        /* data packet sequence (range from 0 to 65535) */
+        protected long seq = 0;
+
+        /* flag to indicate if output stream is closed */
+        protected boolean isClosed = false;
+
+        /**
+         * Constructor.
+         */
+        public IBBOutputStream() {
+            this.buffer = new byte[(byteStreamRequest.getBlockSize()/4)*3];
+        }
+
+        /**
+         * Writes the given data packet to the XMPP stream.
+         * 
+         * @param data the data packet
+         * @throws IOException if an I/O error occurred while sending or if the stream is closed
+         */
+        protected abstract void writeToXML(DataPacketExtension data) throws IOException;
+
+        public synchronized void write(int b) throws IOException {
+            if (this.isClosed) {
+                throw new IOException("Stream is closed");
+            }
+
+            // if buffer is full flush buffer
+            if (bufferPointer >= buffer.length) {
+                flushBuffer();
+            }
+
+            buffer[bufferPointer++] = (byte) b;
+        }
+
+        public synchronized void write(byte b[], int off, int len) throws IOException {
+            if (b == null) {
+                throw new NullPointerException();
+            }
+            else if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length)
+                            || ((off + len) < 0)) {
+                throw new IndexOutOfBoundsException();
+            }
+            else if (len == 0) {
+                return;
+            }
+
+            if (this.isClosed) {
+                throw new IOException("Stream is closed");
+            }
+
+            // is data to send greater than buffer size
+            if (len >= buffer.length) {
+
+                // "byte" off the first chunk to write out
+                writeOut(b, off, buffer.length);
+
+                // recursively call this method with the lesser amount
+                write(b, off + buffer.length, len - buffer.length);
+            }
+            else {
+                writeOut(b, off, len);
+            }
+        }
+
+        public synchronized void write(byte[] b) throws IOException {
+            write(b, 0, b.length);
+        }
+
+        /**
+         * Fills the buffer with the given data and sends it over the XMPP stream if the buffers
+         * capacity has been reached. This method is only called from this class so it is assured
+         * that the amount of data to send is <= buffer capacity
+         * 
+         * @param b the data
+         * @param off the data
+         * @param len the number of bytes to write
+         * @throws IOException if an I/O error occurred while sending or if the stream is closed
+         */
+        private synchronized void writeOut(byte b[], int off, int len) throws IOException {
+            if (this.isClosed) {
+                throw new IOException("Stream is closed");
+            }
+
+            // set to 0 in case the next 'if' block is not executed
+            int available = 0;
+
+            // is data to send greater that buffer space left
+            if (len > buffer.length - bufferPointer) {
+                // fill buffer to capacity and send it
+                available = buffer.length - bufferPointer;
+                System.arraycopy(b, off, buffer, bufferPointer, available);
+                bufferPointer += available;
+                flushBuffer();
+            }
+
+            // copy the data left to buffer
+            System.arraycopy(b, off + available, buffer, bufferPointer, len - available);
+            bufferPointer += len - available;
+        }
+
+        public synchronized void flush() throws IOException {
+            if (this.isClosed) {
+                throw new IOException("Stream is closed");
+            }
+            flushBuffer();
+        }
+
+        private synchronized void flushBuffer() throws IOException {
+
+            // do nothing if no data to send available
+            if (bufferPointer == 0) {
+                return;
+            }
+
+            // create data packet
+            String enc = StringUtils.encodeBase64(buffer, 0, bufferPointer, false);
+            DataPacketExtension data = new DataPacketExtension(byteStreamRequest.getSessionID(),
+                            this.seq, enc);
+
+            // write to XMPP stream
+            writeToXML(data);
+
+            // reset buffer pointer
+            bufferPointer = 0;
+
+            // increment sequence, considering sequence overflow
+            this.seq = (this.seq + 1 == 65535 ? 0 : this.seq + 1);
+
+        }
+
+        public void close() throws IOException {
+            if (isClosed) {
+                return;
+            }
+            InBandBytestreamSession.this.closeByLocal(false);
+        }
+
+        /**
+         * Sets the close flag and optionally flushes the stream.
+         * 
+         * @param flush if <code>true</code> flushes the stream
+         */
+        protected void closeInternal(boolean flush) {
+            if (this.isClosed) {
+                return;
+            }
+            this.isClosed = true;
+
+            try {
+                if (flush) {
+                    flushBuffer();
+                }
+            }
+            catch (IOException e) {
+                /*
+                 * ignore, because writeToXML() will not throw an exception if stream is already
+                 * closed
+                 */
+            }
+        }
+
+    }
+
+    /**
+     * IQIBBOutputStream class implements IBBOutputStream to be used with IQ stanzas encapsulating
+     * the data packets.
+     */
+    private class IQIBBOutputStream extends IBBOutputStream {
+
+        @Override
+        protected synchronized void writeToXML(DataPacketExtension data) throws IOException {
+            // create IQ stanza containing data packet
+            IQ iq = new Data(data);
+            iq.setTo(remoteJID);
+
+            try {
+                SyncPacketSend.getReply(connection, iq);
+            }
+            catch (XMPPException e) {
+                // close session unless it is already closed
+                if (!this.isClosed) {
+                    InBandBytestreamSession.this.close();
+                    throw new IOException("Error while sending Data: " + e.getMessage());
+                }
+            }
+
+        }
+
+    }
+
+    /**
+     * MessageIBBOutputStream class implements IBBOutputStream to be used with message stanzas
+     * encapsulating the data packets.
+     */
+    private class MessageIBBOutputStream extends IBBOutputStream {
+
+        @Override
+        protected synchronized void writeToXML(DataPacketExtension data) {
+            // create message stanza containing data packet
+            Message message = new Message(remoteJID);
+            message.addExtension(data);
+
+            connection.sendPacket(message);
+
+        }
+
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InitiationListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InitiationListener.java
index 0ecb081..be85032 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InitiationListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/InitiationListener.java
@@ -1,127 +1,127 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.ibb;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import org.jivesoftware.smack.PacketListener;
-import org.jivesoftware.smack.filter.AndFilter;
-import org.jivesoftware.smack.filter.IQTypeFilter;
-import org.jivesoftware.smack.filter.PacketFilter;
-import org.jivesoftware.smack.filter.PacketTypeFilter;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smackx.bytestreams.BytestreamListener;
-import org.jivesoftware.smackx.bytestreams.ibb.packet.Open;
-
-/**
- * InitiationListener handles all incoming In-Band Bytestream open requests. If there are no
- * listeners for a In-Band Bytestream request InitiationListener will always refuse the request and
- * reply with a &lt;not-acceptable/&gt; error (<a
- * href="http://xmpp.org/extensions/xep-0047.html#example-5" >XEP-0047</a> Section 2.1).
- * <p>
- * All In-Band Bytestream request having a block size greater than the maximum allowed block size
- * for this connection are rejected with an &lt;resource-constraint/&gt; error. The maximum block
- * size can be set by invoking {@link InBandBytestreamManager#setMaximumBlockSize(int)}.
- * 
- * @author Henning Staib
- */
-class InitiationListener implements PacketListener {
-
-    /* manager containing the listeners and the XMPP connection */
-    private final InBandBytestreamManager manager;
-
-    /* packet filter for all In-Band Bytestream requests */
-    private final PacketFilter initFilter = new AndFilter(new PacketTypeFilter(Open.class),
-                    new IQTypeFilter(IQ.Type.SET));
-
-    /* executor service to process incoming requests concurrently */
-    private final ExecutorService initiationListenerExecutor;
-
-    /**
-     * Constructor.
-     * 
-     * @param manager the In-Band Bytestream manager
-     */
-    protected InitiationListener(InBandBytestreamManager manager) {
-        this.manager = manager;
-        initiationListenerExecutor = Executors.newCachedThreadPool();
-    }
-
-    public void processPacket(final Packet packet) {
-        initiationListenerExecutor.execute(new Runnable() {
-
-            public void run() {
-                processRequest(packet);
-            }
-        });
-    }
-
-    private void processRequest(Packet packet) {
-        Open ibbRequest = (Open) packet;
-
-        // validate that block size is within allowed range
-        if (ibbRequest.getBlockSize() > this.manager.getMaximumBlockSize()) {
-            this.manager.replyResourceConstraintPacket(ibbRequest);
-            return;
-        }
-
-        // ignore request if in ignore list
-        if (this.manager.getIgnoredBytestreamRequests().remove(ibbRequest.getSessionID()))
-            return;
-
-        // build bytestream request from packet
-        InBandBytestreamRequest request = new InBandBytestreamRequest(this.manager, ibbRequest);
-
-        // notify listeners for bytestream initiation from a specific user
-        BytestreamListener userListener = this.manager.getUserListener(ibbRequest.getFrom());
-        if (userListener != null) {
-            userListener.incomingBytestreamRequest(request);
-
-        }
-        else if (!this.manager.getAllRequestListeners().isEmpty()) {
-            /*
-             * if there is no user specific listener inform listeners for all initiation requests
-             */
-            for (BytestreamListener listener : this.manager.getAllRequestListeners()) {
-                listener.incomingBytestreamRequest(request);
-            }
-
-        }
-        else {
-            /*
-             * if there is no listener for this initiation request, reply with reject message
-             */
-            this.manager.replyRejectPacket(ibbRequest);
-        }
-    }
-
-    /**
-     * Returns the packet filter for In-Band Bytestream open requests.
-     * 
-     * @return the packet filter for In-Band Bytestream open requests
-     */
-    protected PacketFilter getFilter() {
-        return this.initFilter;
-    }
-
-    /**
-     * Shuts down the listeners executor service.
-     */
-    protected void shutdown() {
-        this.initiationListenerExecutor.shutdownNow();
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.ibb;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.jivesoftware.smack.PacketListener;
+import org.jivesoftware.smack.filter.AndFilter;
+import org.jivesoftware.smack.filter.IQTypeFilter;
+import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.filter.PacketTypeFilter;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smackx.bytestreams.BytestreamListener;
+import org.jivesoftware.smackx.bytestreams.ibb.packet.Open;
+
+/**
+ * InitiationListener handles all incoming In-Band Bytestream open requests. If there are no
+ * listeners for a In-Band Bytestream request InitiationListener will always refuse the request and
+ * reply with a &lt;not-acceptable/&gt; error (<a
+ * href="http://xmpp.org/extensions/xep-0047.html#example-5" >XEP-0047</a> Section 2.1).
+ * <p>
+ * All In-Band Bytestream request having a block size greater than the maximum allowed block size
+ * for this connection are rejected with an &lt;resource-constraint/&gt; error. The maximum block
+ * size can be set by invoking {@link InBandBytestreamManager#setMaximumBlockSize(int)}.
+ * 
+ * @author Henning Staib
+ */
+class InitiationListener implements PacketListener {
+
+    /* manager containing the listeners and the XMPP connection */
+    private final InBandBytestreamManager manager;
+
+    /* packet filter for all In-Band Bytestream requests */
+    private final PacketFilter initFilter = new AndFilter(new PacketTypeFilter(Open.class),
+                    new IQTypeFilter(IQ.Type.SET));
+
+    /* executor service to process incoming requests concurrently */
+    private final ExecutorService initiationListenerExecutor;
+
+    /**
+     * Constructor.
+     * 
+     * @param manager the In-Band Bytestream manager
+     */
+    protected InitiationListener(InBandBytestreamManager manager) {
+        this.manager = manager;
+        initiationListenerExecutor = Executors.newCachedThreadPool();
+    }
+
+    public void processPacket(final Packet packet) {
+        initiationListenerExecutor.execute(new Runnable() {
+
+            public void run() {
+                processRequest(packet);
+            }
+        });
+    }
+
+    private void processRequest(Packet packet) {
+        Open ibbRequest = (Open) packet;
+
+        // validate that block size is within allowed range
+        if (ibbRequest.getBlockSize() > this.manager.getMaximumBlockSize()) {
+            this.manager.replyResourceConstraintPacket(ibbRequest);
+            return;
+        }
+
+        // ignore request if in ignore list
+        if (this.manager.getIgnoredBytestreamRequests().remove(ibbRequest.getSessionID()))
+            return;
+
+        // build bytestream request from packet
+        InBandBytestreamRequest request = new InBandBytestreamRequest(this.manager, ibbRequest);
+
+        // notify listeners for bytestream initiation from a specific user
+        BytestreamListener userListener = this.manager.getUserListener(ibbRequest.getFrom());
+        if (userListener != null) {
+            userListener.incomingBytestreamRequest(request);
+
+        }
+        else if (!this.manager.getAllRequestListeners().isEmpty()) {
+            /*
+             * if there is no user specific listener inform listeners for all initiation requests
+             */
+            for (BytestreamListener listener : this.manager.getAllRequestListeners()) {
+                listener.incomingBytestreamRequest(request);
+            }
+
+        }
+        else {
+            /*
+             * if there is no listener for this initiation request, reply with reject message
+             */
+            this.manager.replyRejectPacket(ibbRequest);
+        }
+    }
+
+    /**
+     * Returns the packet filter for In-Band Bytestream open requests.
+     * 
+     * @return the packet filter for In-Band Bytestream open requests
+     */
+    protected PacketFilter getFilter() {
+        return this.initFilter;
+    }
+
+    /**
+     * Shuts down the listeners executor service.
+     */
+    protected void shutdown() {
+        this.initiationListenerExecutor.shutdownNow();
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/packet/Close.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/packet/Close.java
index 9a78d73..4ef73dc 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/packet/Close.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/packet/Close.java
@@ -1,65 +1,65 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.ibb.packet;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
-
-/**
- * Represents a request to close an In-Band Bytestream.
- * 
- * @author Henning Staib
- */
-public class Close extends IQ {
-
-    /* unique session ID identifying this In-Band Bytestream */
-    private final String sessionID;
-
-    /**
-     * Creates a new In-Band Bytestream close request packet.
-     * 
-     * @param sessionID unique session ID identifying this In-Band Bytestream
-     */
-    public Close(String sessionID) {
-        if (sessionID == null || "".equals(sessionID)) {
-            throw new IllegalArgumentException("Session ID must not be null or empty");
-        }
-        this.sessionID = sessionID;
-        setType(Type.SET);
-    }
-
-    /**
-     * Returns the unique session ID identifying this In-Band Bytestream.
-     * 
-     * @return the unique session ID identifying this In-Band Bytestream
-     */
-    public String getSessionID() {
-        return sessionID;
-    }
-
-    @Override
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<close ");
-        buf.append("xmlns=\"");
-        buf.append(InBandBytestreamManager.NAMESPACE);
-        buf.append("\" ");
-        buf.append("sid=\"");
-        buf.append(sessionID);
-        buf.append("\"");
-        buf.append("/>");
-        return buf.toString();
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.ibb.packet;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
+
+/**
+ * Represents a request to close an In-Band Bytestream.
+ * 
+ * @author Henning Staib
+ */
+public class Close extends IQ {
+
+    /* unique session ID identifying this In-Band Bytestream */
+    private final String sessionID;
+
+    /**
+     * Creates a new In-Band Bytestream close request packet.
+     * 
+     * @param sessionID unique session ID identifying this In-Band Bytestream
+     */
+    public Close(String sessionID) {
+        if (sessionID == null || "".equals(sessionID)) {
+            throw new IllegalArgumentException("Session ID must not be null or empty");
+        }
+        this.sessionID = sessionID;
+        setType(Type.SET);
+    }
+
+    /**
+     * Returns the unique session ID identifying this In-Band Bytestream.
+     * 
+     * @return the unique session ID identifying this In-Band Bytestream
+     */
+    public String getSessionID() {
+        return sessionID;
+    }
+
+    @Override
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("<close ");
+        buf.append("xmlns=\"");
+        buf.append(InBandBytestreamManager.NAMESPACE);
+        buf.append("\" ");
+        buf.append("sid=\"");
+        buf.append(sessionID);
+        buf.append("\"");
+        buf.append("/>");
+        return buf.toString();
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/packet/Data.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/packet/Data.java
index 696fa75..d38d7e2 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/packet/Data.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/packet/Data.java
@@ -1,64 +1,64 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.ibb.packet;
-
-import org.jivesoftware.smack.packet.IQ;
-
-/**
- * Represents a chunk of data sent over an In-Band Bytestream encapsulated in an
- * IQ stanza.
- * 
- * @author Henning Staib
- */
-public class Data extends IQ {
-
-    /* the data packet extension */
-    private final DataPacketExtension dataPacketExtension;
-
-    /**
-     * Constructor.
-     * 
-     * @param data data packet extension containing the encoded data
-     */
-    public Data(DataPacketExtension data) {
-        if (data == null) {
-            throw new IllegalArgumentException("Data must not be null");
-        }
-        this.dataPacketExtension = data;
-
-        /*
-         * also set as packet extension so that data packet extension can be
-         * retrieved from IQ stanza and message stanza in the same way
-         */
-        addExtension(data);
-        setType(IQ.Type.SET);
-    }
-
-    /**
-     * Returns the data packet extension.
-     * <p>
-     * Convenience method for <code>packet.getExtension("data",
-     * "http://jabber.org/protocol/ibb")</code>.
-     * 
-     * @return the data packet extension
-     */
-    public DataPacketExtension getDataPacketExtension() {
-        return this.dataPacketExtension;
-    }
-
-    public String getChildElementXML() {
-        return this.dataPacketExtension.toXML();
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.ibb.packet;
+
+import org.jivesoftware.smack.packet.IQ;
+
+/**
+ * Represents a chunk of data sent over an In-Band Bytestream encapsulated in an
+ * IQ stanza.
+ * 
+ * @author Henning Staib
+ */
+public class Data extends IQ {
+
+    /* the data packet extension */
+    private final DataPacketExtension dataPacketExtension;
+
+    /**
+     * Constructor.
+     * 
+     * @param data data packet extension containing the encoded data
+     */
+    public Data(DataPacketExtension data) {
+        if (data == null) {
+            throw new IllegalArgumentException("Data must not be null");
+        }
+        this.dataPacketExtension = data;
+
+        /*
+         * also set as packet extension so that data packet extension can be
+         * retrieved from IQ stanza and message stanza in the same way
+         */
+        addExtension(data);
+        setType(IQ.Type.SET);
+    }
+
+    /**
+     * Returns the data packet extension.
+     * <p>
+     * Convenience method for <code>packet.getExtension("data",
+     * "http://jabber.org/protocol/ibb")</code>.
+     * 
+     * @return the data packet extension
+     */
+    public DataPacketExtension getDataPacketExtension() {
+        return this.dataPacketExtension;
+    }
+
+    public String getChildElementXML() {
+        return this.dataPacketExtension.toXML();
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/packet/DataPacketExtension.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/packet/DataPacketExtension.java
index 80ed1e1..dce010f 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/packet/DataPacketExtension.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/packet/DataPacketExtension.java
@@ -1,149 +1,149 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.ibb.packet;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.util.StringUtils;
-import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
-
-/**
- * Represents a chunk of data of an In-Band Bytestream within an IQ stanza or a
- * message stanza
- * 
- * @author Henning Staib
- */
-public class DataPacketExtension implements PacketExtension {
-
-    /**
-     * The element name of the data packet extension.
-     */
-    public final static String ELEMENT_NAME = "data";
-
-    /* unique session ID identifying this In-Band Bytestream */
-    private final String sessionID;
-
-    /* sequence of this packet in regard to the other data packets */
-    private final long seq;
-
-    /* the data contained in this packet */
-    private final String data;
-
-    private byte[] decodedData;
-
-    /**
-     * Creates a new In-Band Bytestream data packet.
-     * 
-     * @param sessionID unique session ID identifying this In-Band Bytestream
-     * @param seq sequence of this packet in regard to the other data packets
-     * @param data the base64 encoded data contained in this packet
-     */
-    public DataPacketExtension(String sessionID, long seq, String data) {
-        if (sessionID == null || "".equals(sessionID)) {
-            throw new IllegalArgumentException("Session ID must not be null or empty");
-        }
-        if (seq < 0 || seq > 65535) {
-            throw new IllegalArgumentException("Sequence must not be between 0 and 65535");
-        }
-        if (data == null) {
-            throw new IllegalArgumentException("Data must not be null");
-        }
-        this.sessionID = sessionID;
-        this.seq = seq;
-        this.data = data;
-    }
-
-    /**
-     * Returns the unique session ID identifying this In-Band Bytestream.
-     * 
-     * @return the unique session ID identifying this In-Band Bytestream
-     */
-    public String getSessionID() {
-        return sessionID;
-    }
-
-    /**
-     * Returns the sequence of this packet in regard to the other data packets.
-     * 
-     * @return the sequence of this packet in regard to the other data packets.
-     */
-    public long getSeq() {
-        return seq;
-    }
-
-    /**
-     * Returns the data contained in this packet.
-     * 
-     * @return the data contained in this packet.
-     */
-    public String getData() {
-        return data;
-    }
-
-    /**
-     * Returns the decoded data or null if data could not be decoded.
-     * <p>
-     * The encoded data is invalid if it contains bad Base64 input characters or
-     * if it contains the pad ('=') character on a position other than the last
-     * character(s) of the data. See <a
-     * href="http://xmpp.org/extensions/xep-0047.html#sec">XEP-0047</a> Section
-     * 6.
-     * 
-     * @return the decoded data
-     */
-    public byte[] getDecodedData() {
-        // return cached decoded data
-        if (this.decodedData != null) {
-            return this.decodedData;
-        }
-
-        // data must not contain the pad (=) other than end of data
-        if (data.matches(".*={1,2}+.+")) {
-            return null;
-        }
-
-        // decodeBase64 will return null if bad characters are included
-        this.decodedData = StringUtils.decodeBase64(data);
-        return this.decodedData;
-    }
-
-    public String getElementName() {
-        return ELEMENT_NAME;
-    }
-
-    public String getNamespace() {
-        return InBandBytestreamManager.NAMESPACE;
-    }
-
-    public String toXML() {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<");
-        buf.append(getElementName());
-        buf.append(" ");
-        buf.append("xmlns=\"");
-        buf.append(InBandBytestreamManager.NAMESPACE);
-        buf.append("\" ");
-        buf.append("seq=\"");
-        buf.append(seq);
-        buf.append("\" ");
-        buf.append("sid=\"");
-        buf.append(sessionID);
-        buf.append("\">");
-        buf.append(data);
-        buf.append("</");
-        buf.append(getElementName());
-        buf.append(">");
-        return buf.toString();
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.ibb.packet;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.util.StringUtils;
+import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
+
+/**
+ * Represents a chunk of data of an In-Band Bytestream within an IQ stanza or a
+ * message stanza
+ * 
+ * @author Henning Staib
+ */
+public class DataPacketExtension implements PacketExtension {
+
+    /**
+     * The element name of the data packet extension.
+     */
+    public final static String ELEMENT_NAME = "data";
+
+    /* unique session ID identifying this In-Band Bytestream */
+    private final String sessionID;
+
+    /* sequence of this packet in regard to the other data packets */
+    private final long seq;
+
+    /* the data contained in this packet */
+    private final String data;
+
+    private byte[] decodedData;
+
+    /**
+     * Creates a new In-Band Bytestream data packet.
+     * 
+     * @param sessionID unique session ID identifying this In-Band Bytestream
+     * @param seq sequence of this packet in regard to the other data packets
+     * @param data the base64 encoded data contained in this packet
+     */
+    public DataPacketExtension(String sessionID, long seq, String data) {
+        if (sessionID == null || "".equals(sessionID)) {
+            throw new IllegalArgumentException("Session ID must not be null or empty");
+        }
+        if (seq < 0 || seq > 65535) {
+            throw new IllegalArgumentException("Sequence must not be between 0 and 65535");
+        }
+        if (data == null) {
+            throw new IllegalArgumentException("Data must not be null");
+        }
+        this.sessionID = sessionID;
+        this.seq = seq;
+        this.data = data;
+    }
+
+    /**
+     * Returns the unique session ID identifying this In-Band Bytestream.
+     * 
+     * @return the unique session ID identifying this In-Band Bytestream
+     */
+    public String getSessionID() {
+        return sessionID;
+    }
+
+    /**
+     * Returns the sequence of this packet in regard to the other data packets.
+     * 
+     * @return the sequence of this packet in regard to the other data packets.
+     */
+    public long getSeq() {
+        return seq;
+    }
+
+    /**
+     * Returns the data contained in this packet.
+     * 
+     * @return the data contained in this packet.
+     */
+    public String getData() {
+        return data;
+    }
+
+    /**
+     * Returns the decoded data or null if data could not be decoded.
+     * <p>
+     * The encoded data is invalid if it contains bad Base64 input characters or
+     * if it contains the pad ('=') character on a position other than the last
+     * character(s) of the data. See <a
+     * href="http://xmpp.org/extensions/xep-0047.html#sec">XEP-0047</a> Section
+     * 6.
+     * 
+     * @return the decoded data
+     */
+    public byte[] getDecodedData() {
+        // return cached decoded data
+        if (this.decodedData != null) {
+            return this.decodedData;
+        }
+
+        // data must not contain the pad (=) other than end of data
+        if (data.matches(".*={1,2}+.+")) {
+            return null;
+        }
+
+        // decodeBase64 will return null if bad characters are included
+        this.decodedData = StringUtils.decodeBase64(data);
+        return this.decodedData;
+    }
+
+    public String getElementName() {
+        return ELEMENT_NAME;
+    }
+
+    public String getNamespace() {
+        return InBandBytestreamManager.NAMESPACE;
+    }
+
+    public String toXML() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("<");
+        buf.append(getElementName());
+        buf.append(" ");
+        buf.append("xmlns=\"");
+        buf.append(InBandBytestreamManager.NAMESPACE);
+        buf.append("\" ");
+        buf.append("seq=\"");
+        buf.append(seq);
+        buf.append("\" ");
+        buf.append("sid=\"");
+        buf.append(sessionID);
+        buf.append("\">");
+        buf.append(data);
+        buf.append("</");
+        buf.append(getElementName());
+        buf.append(">");
+        return buf.toString();
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/packet/Open.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/packet/Open.java
index 94a7a9b..66e9248 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/packet/Open.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/packet/Open.java
@@ -1,126 +1,126 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.ibb.packet;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
-import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager.StanzaType;
-
-/**
- * Represents a request to open an In-Band Bytestream.
- * 
- * @author Henning Staib
- */
-public class Open extends IQ {
-
-    /* unique session ID identifying this In-Band Bytestream */
-    private final String sessionID;
-
-    /* block size in which the data will be fragmented */
-    private final int blockSize;
-
-    /* stanza type used to encapsulate the data */
-    private final StanzaType stanza;
-
-    /**
-     * Creates a new In-Band Bytestream open request packet.
-     * <p>
-     * The data sent over this In-Band Bytestream will be fragmented in blocks
-     * with the given block size. The block size should not be greater than
-     * 65535. A recommended default value is 4096.
-     * <p>
-     * The data can be sent using IQ stanzas or message stanzas.
-     * 
-     * @param sessionID unique session ID identifying this In-Band Bytestream
-     * @param blockSize block size in which the data will be fragmented
-     * @param stanza stanza type used to encapsulate the data
-     */
-    public Open(String sessionID, int blockSize, StanzaType stanza) {
-        if (sessionID == null || "".equals(sessionID)) {
-            throw new IllegalArgumentException("Session ID must not be null or empty");
-        }
-        if (blockSize <= 0) {
-            throw new IllegalArgumentException("Block size must be greater than zero");
-        }
-
-        this.sessionID = sessionID;
-        this.blockSize = blockSize;
-        this.stanza = stanza;
-        setType(Type.SET);
-    }
-
-    /**
-     * Creates a new In-Band Bytestream open request packet.
-     * <p>
-     * The data sent over this In-Band Bytestream will be fragmented in blocks
-     * with the given block size. The block size should not be greater than
-     * 65535. A recommended default value is 4096.
-     * <p>
-     * The data will be sent using IQ stanzas.
-     * 
-     * @param sessionID unique session ID identifying this In-Band Bytestream
-     * @param blockSize block size in which the data will be fragmented
-     */
-    public Open(String sessionID, int blockSize) {
-        this(sessionID, blockSize, StanzaType.IQ);
-    }
-
-    /**
-     * Returns the unique session ID identifying this In-Band Bytestream.
-     * 
-     * @return the unique session ID identifying this In-Band Bytestream
-     */
-    public String getSessionID() {
-        return sessionID;
-    }
-
-    /**
-     * Returns the block size in which the data will be fragmented.
-     * 
-     * @return the block size in which the data will be fragmented
-     */
-    public int getBlockSize() {
-        return blockSize;
-    }
-
-    /**
-     * Returns the stanza type used to encapsulate the data.
-     * 
-     * @return the stanza type used to encapsulate the data
-     */
-    public StanzaType getStanza() {
-        return stanza;
-    }
-
-    @Override
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<open ");
-        buf.append("xmlns=\"");
-        buf.append(InBandBytestreamManager.NAMESPACE);
-        buf.append("\" ");
-        buf.append("block-size=\"");
-        buf.append(blockSize);
-        buf.append("\" ");
-        buf.append("sid=\"");
-        buf.append(sessionID);
-        buf.append("\" ");
-        buf.append("stanza=\"");
-        buf.append(stanza.toString().toLowerCase());
-        buf.append("\"");
-        buf.append("/>");
-        return buf.toString();
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.ibb.packet;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
+import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager.StanzaType;
+
+/**
+ * Represents a request to open an In-Band Bytestream.
+ * 
+ * @author Henning Staib
+ */
+public class Open extends IQ {
+
+    /* unique session ID identifying this In-Band Bytestream */
+    private final String sessionID;
+
+    /* block size in which the data will be fragmented */
+    private final int blockSize;
+
+    /* stanza type used to encapsulate the data */
+    private final StanzaType stanza;
+
+    /**
+     * Creates a new In-Band Bytestream open request packet.
+     * <p>
+     * The data sent over this In-Band Bytestream will be fragmented in blocks
+     * with the given block size. The block size should not be greater than
+     * 65535. A recommended default value is 4096.
+     * <p>
+     * The data can be sent using IQ stanzas or message stanzas.
+     * 
+     * @param sessionID unique session ID identifying this In-Band Bytestream
+     * @param blockSize block size in which the data will be fragmented
+     * @param stanza stanza type used to encapsulate the data
+     */
+    public Open(String sessionID, int blockSize, StanzaType stanza) {
+        if (sessionID == null || "".equals(sessionID)) {
+            throw new IllegalArgumentException("Session ID must not be null or empty");
+        }
+        if (blockSize <= 0) {
+            throw new IllegalArgumentException("Block size must be greater than zero");
+        }
+
+        this.sessionID = sessionID;
+        this.blockSize = blockSize;
+        this.stanza = stanza;
+        setType(Type.SET);
+    }
+
+    /**
+     * Creates a new In-Band Bytestream open request packet.
+     * <p>
+     * The data sent over this In-Band Bytestream will be fragmented in blocks
+     * with the given block size. The block size should not be greater than
+     * 65535. A recommended default value is 4096.
+     * <p>
+     * The data will be sent using IQ stanzas.
+     * 
+     * @param sessionID unique session ID identifying this In-Band Bytestream
+     * @param blockSize block size in which the data will be fragmented
+     */
+    public Open(String sessionID, int blockSize) {
+        this(sessionID, blockSize, StanzaType.IQ);
+    }
+
+    /**
+     * Returns the unique session ID identifying this In-Band Bytestream.
+     * 
+     * @return the unique session ID identifying this In-Band Bytestream
+     */
+    public String getSessionID() {
+        return sessionID;
+    }
+
+    /**
+     * Returns the block size in which the data will be fragmented.
+     * 
+     * @return the block size in which the data will be fragmented
+     */
+    public int getBlockSize() {
+        return blockSize;
+    }
+
+    /**
+     * Returns the stanza type used to encapsulate the data.
+     * 
+     * @return the stanza type used to encapsulate the data
+     */
+    public StanzaType getStanza() {
+        return stanza;
+    }
+
+    @Override
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("<open ");
+        buf.append("xmlns=\"");
+        buf.append(InBandBytestreamManager.NAMESPACE);
+        buf.append("\" ");
+        buf.append("block-size=\"");
+        buf.append(blockSize);
+        buf.append("\" ");
+        buf.append("sid=\"");
+        buf.append(sessionID);
+        buf.append("\" ");
+        buf.append("stanza=\"");
+        buf.append(stanza.toString().toLowerCase());
+        buf.append("\"");
+        buf.append("/>");
+        return buf.toString();
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/provider/CloseIQProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/provider/CloseIQProvider.java
index 566724c..5065819 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/provider/CloseIQProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/provider/CloseIQProvider.java
@@ -1,33 +1,33 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.ibb.provider;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.jivesoftware.smackx.bytestreams.ibb.packet.Close;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * Parses a close In-Band Bytestream packet.
- * 
- * @author Henning Staib
- */
-public class CloseIQProvider implements IQProvider {
-
-    public IQ parseIQ(XmlPullParser parser) throws Exception {
-        String sid = parser.getAttributeValue("", "sid");
-        return new Close(sid);
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.ibb.provider;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.jivesoftware.smackx.bytestreams.ibb.packet.Close;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * Parses a close In-Band Bytestream packet.
+ * 
+ * @author Henning Staib
+ */
+public class CloseIQProvider implements IQProvider {
+
+    public IQ parseIQ(XmlPullParser parser) throws Exception {
+        String sid = parser.getAttributeValue("", "sid");
+        return new Close(sid);
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/provider/DataPacketProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/provider/DataPacketProvider.java
index 5abed08..7c78d69 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/provider/DataPacketProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/provider/DataPacketProvider.java
@@ -1,45 +1,45 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.ibb.provider;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.jivesoftware.smackx.bytestreams.ibb.packet.Data;
-import org.jivesoftware.smackx.bytestreams.ibb.packet.DataPacketExtension;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * Parses an In-Band Bytestream data packet which can be a packet extension of
- * either an IQ stanza or a message stanza.
- * 
- * @author Henning Staib
- */
-public class DataPacketProvider implements PacketExtensionProvider, IQProvider {
-
-    public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
-        String sessionID = parser.getAttributeValue("", "sid");
-        long seq = Long.parseLong(parser.getAttributeValue("", "seq"));
-        String data = parser.nextText();
-        return new DataPacketExtension(sessionID, seq, data);
-    }
-
-    public IQ parseIQ(XmlPullParser parser) throws Exception {
-        DataPacketExtension data = (DataPacketExtension) parseExtension(parser);
-        IQ iq = new Data(data);
-        return iq;
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.ibb.provider;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.jivesoftware.smackx.bytestreams.ibb.packet.Data;
+import org.jivesoftware.smackx.bytestreams.ibb.packet.DataPacketExtension;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * Parses an In-Band Bytestream data packet which can be a packet extension of
+ * either an IQ stanza or a message stanza.
+ * 
+ * @author Henning Staib
+ */
+public class DataPacketProvider implements PacketExtensionProvider, IQProvider {
+
+    public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
+        String sessionID = parser.getAttributeValue("", "sid");
+        long seq = Long.parseLong(parser.getAttributeValue("", "seq"));
+        String data = parser.nextText();
+        return new DataPacketExtension(sessionID, seq, data);
+    }
+
+    public IQ parseIQ(XmlPullParser parser) throws Exception {
+        DataPacketExtension data = (DataPacketExtension) parseExtension(parser);
+        IQ iq = new Data(data);
+        return iq;
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/provider/OpenIQProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/provider/OpenIQProvider.java
index 3cc725a..4ff81e8 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/provider/OpenIQProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/ibb/provider/OpenIQProvider.java
@@ -1,45 +1,45 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.ibb.provider;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager.StanzaType;
-import org.jivesoftware.smackx.bytestreams.ibb.packet.Open;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * Parses an In-Band Bytestream open packet.
- * 
- * @author Henning Staib
- */
-public class OpenIQProvider implements IQProvider {
-
-    public IQ parseIQ(XmlPullParser parser) throws Exception {
-        String sessionID = parser.getAttributeValue("", "sid");
-        int blockSize = Integer.parseInt(parser.getAttributeValue("", "block-size"));
-
-        String stanzaValue = parser.getAttributeValue("", "stanza");
-        StanzaType stanza = null;
-        if (stanzaValue == null) {
-            stanza = StanzaType.IQ;
-        }
-        else {
-            stanza = StanzaType.valueOf(stanzaValue.toUpperCase());
-        }
-
-        return new Open(sessionID, blockSize, stanza);
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.ibb.provider;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager.StanzaType;
+import org.jivesoftware.smackx.bytestreams.ibb.packet.Open;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * Parses an In-Band Bytestream open packet.
+ * 
+ * @author Henning Staib
+ */
+public class OpenIQProvider implements IQProvider {
+
+    public IQ parseIQ(XmlPullParser parser) throws Exception {
+        String sessionID = parser.getAttributeValue("", "sid");
+        int blockSize = Integer.parseInt(parser.getAttributeValue("", "block-size"));
+
+        String stanzaValue = parser.getAttributeValue("", "stanza");
+        StanzaType stanza = null;
+        if (stanzaValue == null) {
+            stanza = StanzaType.IQ;
+        }
+        else {
+            stanza = StanzaType.valueOf(stanzaValue.toUpperCase());
+        }
+
+        return new Open(sessionID, blockSize, stanza);
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/InitiationListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/InitiationListener.java
index 2a78250..a5a8825 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/InitiationListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/InitiationListener.java
@@ -1,119 +1,119 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.socks5;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import org.jivesoftware.smack.PacketListener;
-import org.jivesoftware.smack.filter.AndFilter;
-import org.jivesoftware.smack.filter.IQTypeFilter;
-import org.jivesoftware.smack.filter.PacketFilter;
-import org.jivesoftware.smack.filter.PacketTypeFilter;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smackx.bytestreams.BytestreamListener;
-import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
-
-/**
- * InitiationListener handles all incoming SOCKS5 Bytestream initiation requests. If there are no
- * listeners for a SOCKS5 bytestream request InitiationListener will always refuse the request and
- * reply with a &lt;not-acceptable/&gt; error (<a
- * href="http://xmpp.org/extensions/xep-0065.html#usecase-alternate">XEP-0065</a> Section 5.2.A2).
- * 
- * @author Henning Staib
- */
-final class InitiationListener implements PacketListener {
-
-    /* manager containing the listeners and the XMPP connection */
-    private final Socks5BytestreamManager manager;
-
-    /* packet filter for all SOCKS5 Bytestream requests */
-    private final PacketFilter initFilter = new AndFilter(new PacketTypeFilter(Bytestream.class),
-                    new IQTypeFilter(IQ.Type.SET));
-
-    /* executor service to process incoming requests concurrently */
-    private final ExecutorService initiationListenerExecutor;
-
-    /**
-     * Constructor
-     * 
-     * @param manager the SOCKS5 Bytestream manager
-     */
-    protected InitiationListener(Socks5BytestreamManager manager) {
-        this.manager = manager;
-        initiationListenerExecutor = Executors.newCachedThreadPool();
-    }
-
-    public void processPacket(final Packet packet) {
-        initiationListenerExecutor.execute(new Runnable() {
-
-            public void run() {
-                processRequest(packet);
-            }
-        });
-    }
-
-    private void processRequest(Packet packet) {
-        Bytestream byteStreamRequest = (Bytestream) packet;
-
-        // ignore request if in ignore list
-        if (this.manager.getIgnoredBytestreamRequests().remove(byteStreamRequest.getSessionID())) {
-            return;
-        }
-
-        // build bytestream request from packet
-        Socks5BytestreamRequest request = new Socks5BytestreamRequest(this.manager,
-                        byteStreamRequest);
-
-        // notify listeners for bytestream initiation from a specific user
-        BytestreamListener userListener = this.manager.getUserListener(byteStreamRequest.getFrom());
-        if (userListener != null) {
-            userListener.incomingBytestreamRequest(request);
-
-        }
-        else if (!this.manager.getAllRequestListeners().isEmpty()) {
-            /*
-             * if there is no user specific listener inform listeners for all initiation requests
-             */
-            for (BytestreamListener listener : this.manager.getAllRequestListeners()) {
-                listener.incomingBytestreamRequest(request);
-            }
-
-        }
-        else {
-            /*
-             * if there is no listener for this initiation request, reply with reject message
-             */
-            this.manager.replyRejectPacket(byteStreamRequest);
-        }
-    }
-
-    /**
-     * Returns the packet filter for SOCKS5 Bytestream initialization requests.
-     * 
-     * @return the packet filter for SOCKS5 Bytestream initialization requests
-     */
-    protected PacketFilter getFilter() {
-        return this.initFilter;
-    }
-
-    /**
-     * Shuts down the listeners executor service.
-     */
-    protected void shutdown() {
-        this.initiationListenerExecutor.shutdownNow();
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.socks5;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.jivesoftware.smack.PacketListener;
+import org.jivesoftware.smack.filter.AndFilter;
+import org.jivesoftware.smack.filter.IQTypeFilter;
+import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.filter.PacketTypeFilter;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smackx.bytestreams.BytestreamListener;
+import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
+
+/**
+ * InitiationListener handles all incoming SOCKS5 Bytestream initiation requests. If there are no
+ * listeners for a SOCKS5 bytestream request InitiationListener will always refuse the request and
+ * reply with a &lt;not-acceptable/&gt; error (<a
+ * href="http://xmpp.org/extensions/xep-0065.html#usecase-alternate">XEP-0065</a> Section 5.2.A2).
+ * 
+ * @author Henning Staib
+ */
+final class InitiationListener implements PacketListener {
+
+    /* manager containing the listeners and the XMPP connection */
+    private final Socks5BytestreamManager manager;
+
+    /* packet filter for all SOCKS5 Bytestream requests */
+    private final PacketFilter initFilter = new AndFilter(new PacketTypeFilter(Bytestream.class),
+                    new IQTypeFilter(IQ.Type.SET));
+
+    /* executor service to process incoming requests concurrently */
+    private final ExecutorService initiationListenerExecutor;
+
+    /**
+     * Constructor
+     * 
+     * @param manager the SOCKS5 Bytestream manager
+     */
+    protected InitiationListener(Socks5BytestreamManager manager) {
+        this.manager = manager;
+        initiationListenerExecutor = Executors.newCachedThreadPool();
+    }
+
+    public void processPacket(final Packet packet) {
+        initiationListenerExecutor.execute(new Runnable() {
+
+            public void run() {
+                processRequest(packet);
+            }
+        });
+    }
+
+    private void processRequest(Packet packet) {
+        Bytestream byteStreamRequest = (Bytestream) packet;
+
+        // ignore request if in ignore list
+        if (this.manager.getIgnoredBytestreamRequests().remove(byteStreamRequest.getSessionID())) {
+            return;
+        }
+
+        // build bytestream request from packet
+        Socks5BytestreamRequest request = new Socks5BytestreamRequest(this.manager,
+                        byteStreamRequest);
+
+        // notify listeners for bytestream initiation from a specific user
+        BytestreamListener userListener = this.manager.getUserListener(byteStreamRequest.getFrom());
+        if (userListener != null) {
+            userListener.incomingBytestreamRequest(request);
+
+        }
+        else if (!this.manager.getAllRequestListeners().isEmpty()) {
+            /*
+             * if there is no user specific listener inform listeners for all initiation requests
+             */
+            for (BytestreamListener listener : this.manager.getAllRequestListeners()) {
+                listener.incomingBytestreamRequest(request);
+            }
+
+        }
+        else {
+            /*
+             * if there is no listener for this initiation request, reply with reject message
+             */
+            this.manager.replyRejectPacket(byteStreamRequest);
+        }
+    }
+
+    /**
+     * Returns the packet filter for SOCKS5 Bytestream initialization requests.
+     * 
+     * @return the packet filter for SOCKS5 Bytestream initialization requests
+     */
+    protected PacketFilter getFilter() {
+        return this.initFilter;
+    }
+
+    /**
+     * Shuts down the listeners executor service.
+     */
+    protected void shutdown() {
+        this.initiationListenerExecutor.shutdownNow();
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamListener.java
index 1430b1d..39c8d33 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamListener.java
@@ -1,43 +1,43 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.socks5;
-
-import org.jivesoftware.smackx.bytestreams.BytestreamListener;
-import org.jivesoftware.smackx.bytestreams.BytestreamRequest;
-
-/**
- * Socks5BytestreamListener are informed if a remote user wants to initiate a SOCKS5 Bytestream.
- * Implement this interface to handle incoming SOCKS5 Bytestream requests.
- * <p>
- * There are two ways to add this listener. See
- * {@link Socks5BytestreamManager#addIncomingBytestreamListener(BytestreamListener)} and
- * {@link Socks5BytestreamManager#addIncomingBytestreamListener(BytestreamListener, String)} for
- * further details.
- * 
- * @author Henning Staib
- */
-public abstract class Socks5BytestreamListener implements BytestreamListener {
-
-    public void incomingBytestreamRequest(BytestreamRequest request) {
-        incomingBytestreamRequest((Socks5BytestreamRequest) request);
-    }
-
-    /**
-     * This listener is notified if a SOCKS5 Bytestream request from another user has been received.
-     * 
-     * @param request the incoming SOCKS5 Bytestream request
-     */
-    public abstract void incomingBytestreamRequest(Socks5BytestreamRequest request);
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.socks5;
+
+import org.jivesoftware.smackx.bytestreams.BytestreamListener;
+import org.jivesoftware.smackx.bytestreams.BytestreamRequest;
+
+/**
+ * Socks5BytestreamListener are informed if a remote user wants to initiate a SOCKS5 Bytestream.
+ * Implement this interface to handle incoming SOCKS5 Bytestream requests.
+ * <p>
+ * There are two ways to add this listener. See
+ * {@link Socks5BytestreamManager#addIncomingBytestreamListener(BytestreamListener)} and
+ * {@link Socks5BytestreamManager#addIncomingBytestreamListener(BytestreamListener, String)} for
+ * further details.
+ * 
+ * @author Henning Staib
+ */
+public abstract class Socks5BytestreamListener implements BytestreamListener {
+
+    public void incomingBytestreamRequest(BytestreamRequest request) {
+        incomingBytestreamRequest((Socks5BytestreamRequest) request);
+    }
+
+    /**
+     * This listener is notified if a SOCKS5 Bytestream request from another user has been received.
+     * 
+     * @param request the incoming SOCKS5 Bytestream request
+     */
+    public abstract void incomingBytestreamRequest(Socks5BytestreamRequest request);
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java
index 2860415..d78d5d1 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java
@@ -1,768 +1,768 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.socks5;
-
-import java.io.IOException;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeoutException;
-
-import org.jivesoftware.smack.AbstractConnectionListener;
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.ConnectionCreationListener;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smack.packet.XMPPError;
-import org.jivesoftware.smack.util.SyncPacketSend;
-import org.jivesoftware.smackx.ServiceDiscoveryManager;
-import org.jivesoftware.smackx.bytestreams.BytestreamListener;
-import org.jivesoftware.smackx.bytestreams.BytestreamManager;
-import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
-import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost;
-import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHostUsed;
-import org.jivesoftware.smackx.filetransfer.FileTransferManager;
-import org.jivesoftware.smackx.packet.DiscoverInfo;
-import org.jivesoftware.smackx.packet.DiscoverItems;
-import org.jivesoftware.smackx.packet.DiscoverInfo.Identity;
-import org.jivesoftware.smackx.packet.DiscoverItems.Item;
-
-/**
- * The Socks5BytestreamManager class handles establishing SOCKS5 Bytestreams as specified in the <a
- * href="http://xmpp.org/extensions/xep-0065.html">XEP-0065</a>.
- * <p>
- * A SOCKS5 Bytestream is negotiated partly over the XMPP XML stream and partly over a separate
- * socket. The actual transfer though takes place over a separately created socket.
- * <p>
- * A SOCKS5 Bytestream generally has three parties, the initiator, the target, and the stream host.
- * The stream host is a specialized SOCKS5 proxy setup on a server, or, the initiator can act as the
- * stream host.
- * <p>
- * To establish a SOCKS5 Bytestream invoke the {@link #establishSession(String)} method. This will
- * negotiate a SOCKS5 Bytestream with the given target JID and return a socket.
- * <p>
- * If a session ID for the SOCKS5 Bytestream was already negotiated (e.g. while negotiating a file
- * transfer) invoke {@link #establishSession(String, String)}.
- * <p>
- * To handle incoming SOCKS5 Bytestream requests add an {@link Socks5BytestreamListener} to the
- * manager. There are two ways to add this listener. If you want to be informed about incoming
- * SOCKS5 Bytestreams from a specific user add the listener by invoking
- * {@link #addIncomingBytestreamListener(BytestreamListener, String)}. If the listener should
- * respond to all SOCKS5 Bytestream requests invoke
- * {@link #addIncomingBytestreamListener(BytestreamListener)}.
- * <p>
- * Note that the registered {@link Socks5BytestreamListener} will NOT be notified on incoming Socks5
- * bytestream requests sent in the context of <a
- * href="http://xmpp.org/extensions/xep-0096.html">XEP-0096</a> file transfer. (See
- * {@link FileTransferManager})
- * <p>
- * If no {@link Socks5BytestreamListener}s are registered, all incoming SOCKS5 Bytestream requests
- * will be rejected by returning a &lt;not-acceptable/&gt; error to the initiator.
- * 
- * @author Henning Staib
- */
-public final class Socks5BytestreamManager implements BytestreamManager {
-
-    /*
-     * create a new Socks5BytestreamManager and register a shutdown listener on every established
-     * connection
-     */
-    static {
-        Connection.addConnectionCreationListener(new ConnectionCreationListener() {
-
-            public void connectionCreated(Connection connection) {
-                final Socks5BytestreamManager manager;
-                manager = Socks5BytestreamManager.getBytestreamManager(connection);
-
-                // register shutdown listener
-                connection.addConnectionListener(new AbstractConnectionListener() {
-
-                    public void connectionClosed() {
-                        manager.disableService();
-                    }
-
-                });
-            }
-
-        });
-    }
-
-    /**
-     * The XMPP namespace of the SOCKS5 Bytestream
-     */
-    public static final String NAMESPACE = "http://jabber.org/protocol/bytestreams";
-
-    /* prefix used to generate session IDs */
-    private static final String SESSION_ID_PREFIX = "js5_";
-
-    /* random generator to create session IDs */
-    private final static Random randomGenerator = new Random();
-
-    /* stores one Socks5BytestreamManager for each XMPP connection */
-    private final static Map<Connection, Socks5BytestreamManager> managers = new HashMap<Connection, Socks5BytestreamManager>();
-
-    /* XMPP connection */
-    private final Connection connection;
-
-    /*
-     * assigns a user to a listener that is informed if a bytestream request for this user is
-     * received
-     */
-    private final Map<String, BytestreamListener> userListeners = new ConcurrentHashMap<String, BytestreamListener>();
-
-    /*
-     * list of listeners that respond to all bytestream requests if there are not user specific
-     * listeners for that request
-     */
-    private final List<BytestreamListener> allRequestListeners = Collections.synchronizedList(new LinkedList<BytestreamListener>());
-
-    /* listener that handles all incoming bytestream requests */
-    private final InitiationListener initiationListener;
-
-    /* timeout to wait for the response to the SOCKS5 Bytestream initialization request */
-    private int targetResponseTimeout = 10000;
-
-    /* timeout for connecting to the SOCKS5 proxy selected by the target */
-    private int proxyConnectionTimeout = 10000;
-
-    /* blacklist of errornous SOCKS5 proxies */
-    private final List<String> proxyBlacklist = Collections.synchronizedList(new LinkedList<String>());
-
-    /* remember the last proxy that worked to prioritize it */
-    private String lastWorkingProxy = null;
-
-    /* flag to enable/disable prioritization of last working proxy */
-    private boolean proxyPrioritizationEnabled = true;
-
-    /*
-     * list containing session IDs of SOCKS5 Bytestream initialization packets that should be
-     * ignored by the InitiationListener
-     */
-    private List<String> ignoredBytestreamRequests = Collections.synchronizedList(new LinkedList<String>());
-
-    /**
-     * Returns the Socks5BytestreamManager to handle SOCKS5 Bytestreams for a given
-     * {@link Connection}.
-     * <p>
-     * If no manager exists a new is created and initialized.
-     * 
-     * @param connection the XMPP connection or <code>null</code> if given connection is
-     *        <code>null</code>
-     * @return the Socks5BytestreamManager for the given XMPP connection
-     */
-    public static synchronized Socks5BytestreamManager getBytestreamManager(Connection connection) {
-        if (connection == null) {
-            return null;
-        }
-        Socks5BytestreamManager manager = managers.get(connection);
-        if (manager == null) {
-            manager = new Socks5BytestreamManager(connection);
-            managers.put(connection, manager);
-            manager.activate();
-        }
-        return manager;
-    }
-
-    /**
-     * Private constructor.
-     * 
-     * @param connection the XMPP connection
-     */
-    private Socks5BytestreamManager(Connection connection) {
-        this.connection = connection;
-        this.initiationListener = new InitiationListener(this);
-    }
-
-    /**
-     * Adds BytestreamListener that is called for every incoming SOCKS5 Bytestream request unless
-     * there is a user specific BytestreamListener registered.
-     * <p>
-     * If no listeners are registered all SOCKS5 Bytestream request are rejected with a
-     * &lt;not-acceptable/&gt; error.
-     * <p>
-     * Note that the registered {@link BytestreamListener} will NOT be notified on incoming Socks5
-     * bytestream requests sent in the context of <a
-     * href="http://xmpp.org/extensions/xep-0096.html">XEP-0096</a> file transfer. (See
-     * {@link FileTransferManager})
-     * 
-     * @param listener the listener to register
-     */
-    public void addIncomingBytestreamListener(BytestreamListener listener) {
-        this.allRequestListeners.add(listener);
-    }
-
-    /**
-     * Removes the given listener from the list of listeners for all incoming SOCKS5 Bytestream
-     * requests.
-     * 
-     * @param listener the listener to remove
-     */
-    public void removeIncomingBytestreamListener(BytestreamListener listener) {
-        this.allRequestListeners.remove(listener);
-    }
-
-    /**
-     * Adds BytestreamListener that is called for every incoming SOCKS5 Bytestream request from the
-     * given user.
-     * <p>
-     * Use this method if you are awaiting an incoming SOCKS5 Bytestream request from a specific
-     * user.
-     * <p>
-     * If no listeners are registered all SOCKS5 Bytestream request are rejected with a
-     * &lt;not-acceptable/&gt; error.
-     * <p>
-     * Note that the registered {@link BytestreamListener} will NOT be notified on incoming Socks5
-     * bytestream requests sent in the context of <a
-     * href="http://xmpp.org/extensions/xep-0096.html">XEP-0096</a> file transfer. (See
-     * {@link FileTransferManager})
-     * 
-     * @param listener the listener to register
-     * @param initiatorJID the JID of the user that wants to establish a SOCKS5 Bytestream
-     */
-    public void addIncomingBytestreamListener(BytestreamListener listener, String initiatorJID) {
-        this.userListeners.put(initiatorJID, listener);
-    }
-
-    /**
-     * Removes the listener for the given user.
-     * 
-     * @param initiatorJID the JID of the user the listener should be removed
-     */
-    public void removeIncomingBytestreamListener(String initiatorJID) {
-        this.userListeners.remove(initiatorJID);
-    }
-
-    /**
-     * Use this method to ignore the next incoming SOCKS5 Bytestream request containing the given
-     * session ID. No listeners will be notified for this request and and no error will be returned
-     * to the initiator.
-     * <p>
-     * This method should be used if you are awaiting a SOCKS5 Bytestream request as a reply to
-     * another packet (e.g. file transfer).
-     * 
-     * @param sessionID to be ignored
-     */
-    public void ignoreBytestreamRequestOnce(String sessionID) {
-        this.ignoredBytestreamRequests.add(sessionID);
-    }
-
-    /**
-     * Disables the SOCKS5 Bytestream manager by removing the SOCKS5 Bytestream feature from the
-     * service discovery, disabling the listener for SOCKS5 Bytestream initiation requests and
-     * resetting its internal state.
-     * <p>
-     * To re-enable the SOCKS5 Bytestream feature invoke {@link #getBytestreamManager(Connection)}.
-     * Using the file transfer API will automatically re-enable the SOCKS5 Bytestream feature.
-     */
-    public synchronized void disableService() {
-
-        // remove initiation packet listener
-        this.connection.removePacketListener(this.initiationListener);
-
-        // shutdown threads
-        this.initiationListener.shutdown();
-
-        // clear listeners
-        this.allRequestListeners.clear();
-        this.userListeners.clear();
-
-        // reset internal state
-        this.lastWorkingProxy = null;
-        this.proxyBlacklist.clear();
-        this.ignoredBytestreamRequests.clear();
-
-        // remove manager from static managers map
-        managers.remove(this.connection);
-
-        // shutdown local SOCKS5 proxy if there are no more managers for other connections
-        if (managers.size() == 0) {
-            Socks5Proxy.getSocks5Proxy().stop();
-        }
-
-        // remove feature from service discovery
-        ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(this.connection);
-
-        // check if service discovery is not already disposed by connection shutdown
-        if (serviceDiscoveryManager != null) {
-            serviceDiscoveryManager.removeFeature(NAMESPACE);
-        }
-
-    }
-
-    /**
-     * Returns the timeout to wait for the response to the SOCKS5 Bytestream initialization request.
-     * Default is 10000ms.
-     * 
-     * @return the timeout to wait for the response to the SOCKS5 Bytestream initialization request
-     */
-    public int getTargetResponseTimeout() {
-        if (this.targetResponseTimeout <= 0) {
-            this.targetResponseTimeout = 10000;
-        }
-        return targetResponseTimeout;
-    }
-
-    /**
-     * Sets the timeout to wait for the response to the SOCKS5 Bytestream initialization request.
-     * Default is 10000ms.
-     * 
-     * @param targetResponseTimeout the timeout to set
-     */
-    public void setTargetResponseTimeout(int targetResponseTimeout) {
-        this.targetResponseTimeout = targetResponseTimeout;
-    }
-
-    /**
-     * Returns the timeout for connecting to the SOCKS5 proxy selected by the target. Default is
-     * 10000ms.
-     * 
-     * @return the timeout for connecting to the SOCKS5 proxy selected by the target
-     */
-    public int getProxyConnectionTimeout() {
-        if (this.proxyConnectionTimeout <= 0) {
-            this.proxyConnectionTimeout = 10000;
-        }
-        return proxyConnectionTimeout;
-    }
-
-    /**
-     * Sets the timeout for connecting to the SOCKS5 proxy selected by the target. Default is
-     * 10000ms.
-     * 
-     * @param proxyConnectionTimeout the timeout to set
-     */
-    public void setProxyConnectionTimeout(int proxyConnectionTimeout) {
-        this.proxyConnectionTimeout = proxyConnectionTimeout;
-    }
-
-    /**
-     * Returns if the prioritization of the last working SOCKS5 proxy on successive SOCKS5
-     * Bytestream connections is enabled. Default is <code>true</code>.
-     * 
-     * @return <code>true</code> if prioritization is enabled, <code>false</code> otherwise
-     */
-    public boolean isProxyPrioritizationEnabled() {
-        return proxyPrioritizationEnabled;
-    }
-
-    /**
-     * Enable/disable the prioritization of the last working SOCKS5 proxy on successive SOCKS5
-     * Bytestream connections.
-     * 
-     * @param proxyPrioritizationEnabled enable/disable the prioritization of the last working
-     *        SOCKS5 proxy
-     */
-    public void setProxyPrioritizationEnabled(boolean proxyPrioritizationEnabled) {
-        this.proxyPrioritizationEnabled = proxyPrioritizationEnabled;
-    }
-
-    /**
-     * Establishes a SOCKS5 Bytestream with the given user and returns the Socket to send/receive
-     * data to/from the user.
-     * <p>
-     * Use this method to establish SOCKS5 Bytestreams to users accepting all incoming Socks5
-     * bytestream requests since this method doesn't provide a way to tell the user something about
-     * the data to be sent.
-     * <p>
-     * To establish a SOCKS5 Bytestream after negotiation the kind of data to be sent (e.g. file
-     * transfer) use {@link #establishSession(String, String)}.
-     * 
-     * @param targetJID the JID of the user a SOCKS5 Bytestream should be established
-     * @return the Socket to send/receive data to/from the user
-     * @throws XMPPException if the user doesn't support or accept SOCKS5 Bytestreams, if no Socks5
-     *         Proxy could be found, if the user couldn't connect to any of the SOCKS5 Proxies
-     * @throws IOException if the bytestream could not be established
-     * @throws InterruptedException if the current thread was interrupted while waiting
-     */
-    public Socks5BytestreamSession establishSession(String targetJID) throws XMPPException,
-                    IOException, InterruptedException {
-        String sessionID = getNextSessionID();
-        return establishSession(targetJID, sessionID);
-    }
-
-    /**
-     * Establishes a SOCKS5 Bytestream with the given user using the given session ID and returns
-     * the Socket to send/receive data to/from the user.
-     * 
-     * @param targetJID the JID of the user a SOCKS5 Bytestream should be established
-     * @param sessionID the session ID for the SOCKS5 Bytestream request
-     * @return the Socket to send/receive data to/from the user
-     * @throws XMPPException if the user doesn't support or accept SOCKS5 Bytestreams, if no Socks5
-     *         Proxy could be found, if the user couldn't connect to any of the SOCKS5 Proxies
-     * @throws IOException if the bytestream could not be established
-     * @throws InterruptedException if the current thread was interrupted while waiting
-     */
-    public Socks5BytestreamSession establishSession(String targetJID, String sessionID)
-                    throws XMPPException, IOException, InterruptedException {
-
-        XMPPException discoveryException = null;
-        // check if target supports SOCKS5 Bytestream
-        if (!supportsSocks5(targetJID)) {
-            throw new XMPPException(targetJID + " doesn't support SOCKS5 Bytestream");
-        }
-
-        List<String> proxies = new ArrayList<String>();
-        // determine SOCKS5 proxies from XMPP-server
-        try {
-            proxies.addAll(determineProxies());
-        } catch (XMPPException e) {
-            // don't abort here, just remember the exception thrown by determineProxies()
-            // determineStreamHostInfos() will at least add the local Socks5 proxy (if enabled)
-            discoveryException = e;
-        }
-
-        // determine address and port of each proxy
-        List<StreamHost> streamHosts = determineStreamHostInfos(proxies);
-
-        if (streamHosts.isEmpty()) {
-            throw discoveryException != null ? discoveryException : new XMPPException("no SOCKS5 proxies available");
-        }
-
-        // compute digest
-        String digest = Socks5Utils.createDigest(sessionID, this.connection.getUser(), targetJID);
-
-        // prioritize last working SOCKS5 proxy if exists
-        if (this.proxyPrioritizationEnabled && this.lastWorkingProxy != null) {
-            StreamHost selectedStreamHost = null;
-            for (StreamHost streamHost : streamHosts) {
-                if (streamHost.getJID().equals(this.lastWorkingProxy)) {
-                    selectedStreamHost = streamHost;
-                    break;
-                }
-            }
-            if (selectedStreamHost != null) {
-                streamHosts.remove(selectedStreamHost);
-                streamHosts.add(0, selectedStreamHost);
-            }
-
-        }
-
-        Socks5Proxy socks5Proxy = Socks5Proxy.getSocks5Proxy();
-        try {
-
-            // add transfer digest to local proxy to make transfer valid
-            socks5Proxy.addTransfer(digest);
-
-            // create initiation packet
-            Bytestream initiation = createBytestreamInitiation(sessionID, targetJID, streamHosts);
-
-            // send initiation packet
-            Packet response = SyncPacketSend.getReply(this.connection, initiation,
-                            getTargetResponseTimeout());
-
-            // extract used stream host from response
-            StreamHostUsed streamHostUsed = ((Bytestream) response).getUsedHost();
-            StreamHost usedStreamHost = initiation.getStreamHost(streamHostUsed.getJID());
-
-            if (usedStreamHost == null) {
-                throw new XMPPException("Remote user responded with unknown host");
-            }
-
-            // build SOCKS5 client
-            Socks5Client socks5Client = new Socks5ClientForInitiator(usedStreamHost, digest,
-                            this.connection, sessionID, targetJID);
-
-            // establish connection to proxy
-            Socket socket = socks5Client.getSocket(getProxyConnectionTimeout());
-
-            // remember last working SOCKS5 proxy to prioritize it for next request
-            this.lastWorkingProxy = usedStreamHost.getJID();
-
-            // negotiation successful, return the output stream
-            return new Socks5BytestreamSession(socket, usedStreamHost.getJID().equals(
-                            this.connection.getUser()));
-
-        }
-        catch (TimeoutException e) {
-            throw new IOException("Timeout while connecting to SOCKS5 proxy");
-        }
-        finally {
-
-            // remove transfer digest if output stream is returned or an exception
-            // occurred
-            socks5Proxy.removeTransfer(digest);
-
-        }
-    }
-
-    /**
-     * Returns <code>true</code> if the given target JID supports feature SOCKS5 Bytestream.
-     * 
-     * @param targetJID the target JID
-     * @return <code>true</code> if the given target JID supports feature SOCKS5 Bytestream
-     *         otherwise <code>false</code>
-     * @throws XMPPException if there was an error querying target for supported features
-     */
-    private boolean supportsSocks5(String targetJID) throws XMPPException {
-        ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(this.connection);
-        DiscoverInfo discoverInfo = serviceDiscoveryManager.discoverInfo(targetJID);
-        return discoverInfo.containsFeature(NAMESPACE);
-    }
-
-    /**
-     * Returns a list of JIDs of SOCKS5 proxies by querying the XMPP server. The SOCKS5 proxies are
-     * in the same order as returned by the XMPP server.
-     * 
-     * @return list of JIDs of SOCKS5 proxies
-     * @throws XMPPException if there was an error querying the XMPP server for SOCKS5 proxies
-     */
-    private List<String> determineProxies() throws XMPPException {
-        ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(this.connection);
-
-        List<String> proxies = new ArrayList<String>();
-
-        // get all items form XMPP server
-        DiscoverItems discoverItems = serviceDiscoveryManager.discoverItems(this.connection.getServiceName());
-        Iterator<Item> itemIterator = discoverItems.getItems();
-
-        // query all items if they are SOCKS5 proxies
-        while (itemIterator.hasNext()) {
-            Item item = itemIterator.next();
-
-            // skip blacklisted servers
-            if (this.proxyBlacklist.contains(item.getEntityID())) {
-                continue;
-            }
-
-            try {
-                DiscoverInfo proxyInfo;
-                proxyInfo = serviceDiscoveryManager.discoverInfo(item.getEntityID());
-                Iterator<Identity> identities = proxyInfo.getIdentities();
-
-                // item must have category "proxy" and type "bytestream"
-                while (identities.hasNext()) {
-                    Identity identity = identities.next();
-
-                    if ("proxy".equalsIgnoreCase(identity.getCategory())
-                                    && "bytestreams".equalsIgnoreCase(identity.getType())) {
-                        proxies.add(item.getEntityID());
-                        break;
-                    }
-
-                    /*
-                     * server is not a SOCKS5 proxy, blacklist server to skip next time a Socks5
-                     * bytestream should be established
-                     */
-                    this.proxyBlacklist.add(item.getEntityID());
-
-                }
-            }
-            catch (XMPPException e) {
-                // blacklist errornous server
-                this.proxyBlacklist.add(item.getEntityID());
-            }
-        }
-
-        return proxies;
-    }
-
-    /**
-     * Returns a list of stream hosts containing the IP address an the port for the given list of
-     * SOCKS5 proxy JIDs. The order of the returned list is the same as the given list of JIDs
-     * excluding all SOCKS5 proxies who's network settings could not be determined. If a local
-     * SOCKS5 proxy is running it will be the first item in the list returned.
-     * 
-     * @param proxies a list of SOCKS5 proxy JIDs
-     * @return a list of stream hosts containing the IP address an the port
-     */
-    private List<StreamHost> determineStreamHostInfos(List<String> proxies) {
-        List<StreamHost> streamHosts = new ArrayList<StreamHost>();
-
-        // add local proxy on first position if exists
-        List<StreamHost> localProxies = getLocalStreamHost();
-        if (localProxies != null) {
-            streamHosts.addAll(localProxies);
-        }
-
-        // query SOCKS5 proxies for network settings
-        for (String proxy : proxies) {
-            Bytestream streamHostRequest = createStreamHostRequest(proxy);
-            try {
-                Bytestream response = (Bytestream) SyncPacketSend.getReply(this.connection,
-                                streamHostRequest);
-                streamHosts.addAll(response.getStreamHosts());
-            }
-            catch (XMPPException e) {
-                // blacklist errornous proxies
-                this.proxyBlacklist.add(proxy);
-            }
-        }
-
-        return streamHosts;
-    }
-
-    /**
-     * Returns a IQ packet to query a SOCKS5 proxy its network settings.
-     * 
-     * @param proxy the proxy to query
-     * @return IQ packet to query a SOCKS5 proxy its network settings
-     */
-    private Bytestream createStreamHostRequest(String proxy) {
-        Bytestream request = new Bytestream();
-        request.setType(IQ.Type.GET);
-        request.setTo(proxy);
-        return request;
-    }
-
-    /**
-     * Returns the stream host information of the local SOCKS5 proxy containing the IP address and
-     * the port or null if local SOCKS5 proxy is not running.
-     * 
-     * @return the stream host information of the local SOCKS5 proxy or null if local SOCKS5 proxy
-     *         is not running
-     */
-    private List<StreamHost> getLocalStreamHost() {
-
-        // get local proxy singleton
-        Socks5Proxy socks5Server = Socks5Proxy.getSocks5Proxy();
-
-        if (socks5Server.isRunning()) {
-            List<String> addresses = socks5Server.getLocalAddresses();
-            int port = socks5Server.getPort();
-
-            if (addresses.size() >= 1) {
-                List<StreamHost> streamHosts = new ArrayList<StreamHost>();
-                for (String address : addresses) {
-                    StreamHost streamHost = new StreamHost(this.connection.getUser(), address);
-                    streamHost.setPort(port);
-                    streamHosts.add(streamHost);
-                }
-                return streamHosts;
-            }
-
-        }
-
-        // server is not running or local address could not be determined
-        return null;
-    }
-
-    /**
-     * Returns a SOCKS5 Bytestream initialization request packet with the given session ID
-     * containing the given stream hosts for the given target JID.
-     * 
-     * @param sessionID the session ID for the SOCKS5 Bytestream
-     * @param targetJID the target JID of SOCKS5 Bytestream request
-     * @param streamHosts a list of SOCKS5 proxies the target should connect to
-     * @return a SOCKS5 Bytestream initialization request packet
-     */
-    private Bytestream createBytestreamInitiation(String sessionID, String targetJID,
-                    List<StreamHost> streamHosts) {
-        Bytestream initiation = new Bytestream(sessionID);
-
-        // add all stream hosts
-        for (StreamHost streamHost : streamHosts) {
-            initiation.addStreamHost(streamHost);
-        }
-
-        initiation.setType(IQ.Type.SET);
-        initiation.setTo(targetJID);
-
-        return initiation;
-    }
-
-    /**
-     * Responses to the given packet's sender with a XMPP error that a SOCKS5 Bytestream is not
-     * accepted.
-     * 
-     * @param packet Packet that should be answered with a not-acceptable error
-     */
-    protected void replyRejectPacket(IQ packet) {
-        XMPPError xmppError = new XMPPError(XMPPError.Condition.no_acceptable);
-        IQ errorIQ = IQ.createErrorResponse(packet, xmppError);
-        this.connection.sendPacket(errorIQ);
-    }
-
-    /**
-     * Activates the Socks5BytestreamManager by registering the SOCKS5 Bytestream initialization
-     * listener and enabling the SOCKS5 Bytestream feature.
-     */
-    private void activate() {
-        // register bytestream initiation packet listener
-        this.connection.addPacketListener(this.initiationListener,
-                        this.initiationListener.getFilter());
-
-        // enable SOCKS5 feature
-        enableService();
-    }
-
-    /**
-     * Adds the SOCKS5 Bytestream feature to the service discovery.
-     */
-    private void enableService() {
-        ServiceDiscoveryManager manager = ServiceDiscoveryManager.getInstanceFor(this.connection);
-        if (!manager.includesFeature(NAMESPACE)) {
-            manager.addFeature(NAMESPACE);
-        }
-    }
-
-    /**
-     * Returns a new unique session ID.
-     * 
-     * @return a new unique session ID
-     */
-    private String getNextSessionID() {
-        StringBuilder buffer = new StringBuilder();
-        buffer.append(SESSION_ID_PREFIX);
-        buffer.append(Math.abs(randomGenerator.nextLong()));
-        return buffer.toString();
-    }
-
-    /**
-     * Returns the XMPP connection.
-     * 
-     * @return the XMPP connection
-     */
-    protected Connection getConnection() {
-        return this.connection;
-    }
-
-    /**
-     * Returns the {@link BytestreamListener} that should be informed if a SOCKS5 Bytestream request
-     * from the given initiator JID is received.
-     * 
-     * @param initiator the initiator's JID
-     * @return the listener
-     */
-    protected BytestreamListener getUserListener(String initiator) {
-        return this.userListeners.get(initiator);
-    }
-
-    /**
-     * Returns a list of {@link BytestreamListener} that are informed if there are no listeners for
-     * a specific initiator.
-     * 
-     * @return list of listeners
-     */
-    protected List<BytestreamListener> getAllRequestListeners() {
-        return this.allRequestListeners;
-    }
-
-    /**
-     * Returns the list of session IDs that should be ignored by the InitialtionListener
-     * 
-     * @return list of session IDs
-     */
-    protected List<String> getIgnoredBytestreamRequests() {
-        return ignoredBytestreamRequests;
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.socks5;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeoutException;
+
+import org.jivesoftware.smack.AbstractConnectionListener;
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.ConnectionCreationListener;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.packet.XMPPError;
+import org.jivesoftware.smack.util.SyncPacketSend;
+import org.jivesoftware.smackx.ServiceDiscoveryManager;
+import org.jivesoftware.smackx.bytestreams.BytestreamListener;
+import org.jivesoftware.smackx.bytestreams.BytestreamManager;
+import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
+import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost;
+import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHostUsed;
+import org.jivesoftware.smackx.filetransfer.FileTransferManager;
+import org.jivesoftware.smackx.packet.DiscoverInfo;
+import org.jivesoftware.smackx.packet.DiscoverItems;
+import org.jivesoftware.smackx.packet.DiscoverInfo.Identity;
+import org.jivesoftware.smackx.packet.DiscoverItems.Item;
+
+/**
+ * The Socks5BytestreamManager class handles establishing SOCKS5 Bytestreams as specified in the <a
+ * href="http://xmpp.org/extensions/xep-0065.html">XEP-0065</a>.
+ * <p>
+ * A SOCKS5 Bytestream is negotiated partly over the XMPP XML stream and partly over a separate
+ * socket. The actual transfer though takes place over a separately created socket.
+ * <p>
+ * A SOCKS5 Bytestream generally has three parties, the initiator, the target, and the stream host.
+ * The stream host is a specialized SOCKS5 proxy setup on a server, or, the initiator can act as the
+ * stream host.
+ * <p>
+ * To establish a SOCKS5 Bytestream invoke the {@link #establishSession(String)} method. This will
+ * negotiate a SOCKS5 Bytestream with the given target JID and return a socket.
+ * <p>
+ * If a session ID for the SOCKS5 Bytestream was already negotiated (e.g. while negotiating a file
+ * transfer) invoke {@link #establishSession(String, String)}.
+ * <p>
+ * To handle incoming SOCKS5 Bytestream requests add an {@link Socks5BytestreamListener} to the
+ * manager. There are two ways to add this listener. If you want to be informed about incoming
+ * SOCKS5 Bytestreams from a specific user add the listener by invoking
+ * {@link #addIncomingBytestreamListener(BytestreamListener, String)}. If the listener should
+ * respond to all SOCKS5 Bytestream requests invoke
+ * {@link #addIncomingBytestreamListener(BytestreamListener)}.
+ * <p>
+ * Note that the registered {@link Socks5BytestreamListener} will NOT be notified on incoming Socks5
+ * bytestream requests sent in the context of <a
+ * href="http://xmpp.org/extensions/xep-0096.html">XEP-0096</a> file transfer. (See
+ * {@link FileTransferManager})
+ * <p>
+ * If no {@link Socks5BytestreamListener}s are registered, all incoming SOCKS5 Bytestream requests
+ * will be rejected by returning a &lt;not-acceptable/&gt; error to the initiator.
+ * 
+ * @author Henning Staib
+ */
+public final class Socks5BytestreamManager implements BytestreamManager {
+
+    /*
+     * create a new Socks5BytestreamManager and register a shutdown listener on every established
+     * connection
+     */
+    static {
+        Connection.addConnectionCreationListener(new ConnectionCreationListener() {
+
+            public void connectionCreated(Connection connection) {
+                final Socks5BytestreamManager manager;
+                manager = Socks5BytestreamManager.getBytestreamManager(connection);
+
+                // register shutdown listener
+                connection.addConnectionListener(new AbstractConnectionListener() {
+
+                    public void connectionClosed() {
+                        manager.disableService();
+                    }
+
+                });
+            }
+
+        });
+    }
+
+    /**
+     * The XMPP namespace of the SOCKS5 Bytestream
+     */
+    public static final String NAMESPACE = "http://jabber.org/protocol/bytestreams";
+
+    /* prefix used to generate session IDs */
+    private static final String SESSION_ID_PREFIX = "js5_";
+
+    /* random generator to create session IDs */
+    private final static Random randomGenerator = new Random();
+
+    /* stores one Socks5BytestreamManager for each XMPP connection */
+    private final static Map<Connection, Socks5BytestreamManager> managers = new HashMap<Connection, Socks5BytestreamManager>();
+
+    /* XMPP connection */
+    private final Connection connection;
+
+    /*
+     * assigns a user to a listener that is informed if a bytestream request for this user is
+     * received
+     */
+    private final Map<String, BytestreamListener> userListeners = new ConcurrentHashMap<String, BytestreamListener>();
+
+    /*
+     * list of listeners that respond to all bytestream requests if there are not user specific
+     * listeners for that request
+     */
+    private final List<BytestreamListener> allRequestListeners = Collections.synchronizedList(new LinkedList<BytestreamListener>());
+
+    /* listener that handles all incoming bytestream requests */
+    private final InitiationListener initiationListener;
+
+    /* timeout to wait for the response to the SOCKS5 Bytestream initialization request */
+    private int targetResponseTimeout = 10000;
+
+    /* timeout for connecting to the SOCKS5 proxy selected by the target */
+    private int proxyConnectionTimeout = 10000;
+
+    /* blacklist of errornous SOCKS5 proxies */
+    private final List<String> proxyBlacklist = Collections.synchronizedList(new LinkedList<String>());
+
+    /* remember the last proxy that worked to prioritize it */
+    private String lastWorkingProxy = null;
+
+    /* flag to enable/disable prioritization of last working proxy */
+    private boolean proxyPrioritizationEnabled = true;
+
+    /*
+     * list containing session IDs of SOCKS5 Bytestream initialization packets that should be
+     * ignored by the InitiationListener
+     */
+    private List<String> ignoredBytestreamRequests = Collections.synchronizedList(new LinkedList<String>());
+
+    /**
+     * Returns the Socks5BytestreamManager to handle SOCKS5 Bytestreams for a given
+     * {@link Connection}.
+     * <p>
+     * If no manager exists a new is created and initialized.
+     * 
+     * @param connection the XMPP connection or <code>null</code> if given connection is
+     *        <code>null</code>
+     * @return the Socks5BytestreamManager for the given XMPP connection
+     */
+    public static synchronized Socks5BytestreamManager getBytestreamManager(Connection connection) {
+        if (connection == null) {
+            return null;
+        }
+        Socks5BytestreamManager manager = managers.get(connection);
+        if (manager == null) {
+            manager = new Socks5BytestreamManager(connection);
+            managers.put(connection, manager);
+            manager.activate();
+        }
+        return manager;
+    }
+
+    /**
+     * Private constructor.
+     * 
+     * @param connection the XMPP connection
+     */
+    private Socks5BytestreamManager(Connection connection) {
+        this.connection = connection;
+        this.initiationListener = new InitiationListener(this);
+    }
+
+    /**
+     * Adds BytestreamListener that is called for every incoming SOCKS5 Bytestream request unless
+     * there is a user specific BytestreamListener registered.
+     * <p>
+     * If no listeners are registered all SOCKS5 Bytestream request are rejected with a
+     * &lt;not-acceptable/&gt; error.
+     * <p>
+     * Note that the registered {@link BytestreamListener} will NOT be notified on incoming Socks5
+     * bytestream requests sent in the context of <a
+     * href="http://xmpp.org/extensions/xep-0096.html">XEP-0096</a> file transfer. (See
+     * {@link FileTransferManager})
+     * 
+     * @param listener the listener to register
+     */
+    public void addIncomingBytestreamListener(BytestreamListener listener) {
+        this.allRequestListeners.add(listener);
+    }
+
+    /**
+     * Removes the given listener from the list of listeners for all incoming SOCKS5 Bytestream
+     * requests.
+     * 
+     * @param listener the listener to remove
+     */
+    public void removeIncomingBytestreamListener(BytestreamListener listener) {
+        this.allRequestListeners.remove(listener);
+    }
+
+    /**
+     * Adds BytestreamListener that is called for every incoming SOCKS5 Bytestream request from the
+     * given user.
+     * <p>
+     * Use this method if you are awaiting an incoming SOCKS5 Bytestream request from a specific
+     * user.
+     * <p>
+     * If no listeners are registered all SOCKS5 Bytestream request are rejected with a
+     * &lt;not-acceptable/&gt; error.
+     * <p>
+     * Note that the registered {@link BytestreamListener} will NOT be notified on incoming Socks5
+     * bytestream requests sent in the context of <a
+     * href="http://xmpp.org/extensions/xep-0096.html">XEP-0096</a> file transfer. (See
+     * {@link FileTransferManager})
+     * 
+     * @param listener the listener to register
+     * @param initiatorJID the JID of the user that wants to establish a SOCKS5 Bytestream
+     */
+    public void addIncomingBytestreamListener(BytestreamListener listener, String initiatorJID) {
+        this.userListeners.put(initiatorJID, listener);
+    }
+
+    /**
+     * Removes the listener for the given user.
+     * 
+     * @param initiatorJID the JID of the user the listener should be removed
+     */
+    public void removeIncomingBytestreamListener(String initiatorJID) {
+        this.userListeners.remove(initiatorJID);
+    }
+
+    /**
+     * Use this method to ignore the next incoming SOCKS5 Bytestream request containing the given
+     * session ID. No listeners will be notified for this request and and no error will be returned
+     * to the initiator.
+     * <p>
+     * This method should be used if you are awaiting a SOCKS5 Bytestream request as a reply to
+     * another packet (e.g. file transfer).
+     * 
+     * @param sessionID to be ignored
+     */
+    public void ignoreBytestreamRequestOnce(String sessionID) {
+        this.ignoredBytestreamRequests.add(sessionID);
+    }
+
+    /**
+     * Disables the SOCKS5 Bytestream manager by removing the SOCKS5 Bytestream feature from the
+     * service discovery, disabling the listener for SOCKS5 Bytestream initiation requests and
+     * resetting its internal state.
+     * <p>
+     * To re-enable the SOCKS5 Bytestream feature invoke {@link #getBytestreamManager(Connection)}.
+     * Using the file transfer API will automatically re-enable the SOCKS5 Bytestream feature.
+     */
+    public synchronized void disableService() {
+
+        // remove initiation packet listener
+        this.connection.removePacketListener(this.initiationListener);
+
+        // shutdown threads
+        this.initiationListener.shutdown();
+
+        // clear listeners
+        this.allRequestListeners.clear();
+        this.userListeners.clear();
+
+        // reset internal state
+        this.lastWorkingProxy = null;
+        this.proxyBlacklist.clear();
+        this.ignoredBytestreamRequests.clear();
+
+        // remove manager from static managers map
+        managers.remove(this.connection);
+
+        // shutdown local SOCKS5 proxy if there are no more managers for other connections
+        if (managers.size() == 0) {
+            Socks5Proxy.getSocks5Proxy().stop();
+        }
+
+        // remove feature from service discovery
+        ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(this.connection);
+
+        // check if service discovery is not already disposed by connection shutdown
+        if (serviceDiscoveryManager != null) {
+            serviceDiscoveryManager.removeFeature(NAMESPACE);
+        }
+
+    }
+
+    /**
+     * Returns the timeout to wait for the response to the SOCKS5 Bytestream initialization request.
+     * Default is 10000ms.
+     * 
+     * @return the timeout to wait for the response to the SOCKS5 Bytestream initialization request
+     */
+    public int getTargetResponseTimeout() {
+        if (this.targetResponseTimeout <= 0) {
+            this.targetResponseTimeout = 10000;
+        }
+        return targetResponseTimeout;
+    }
+
+    /**
+     * Sets the timeout to wait for the response to the SOCKS5 Bytestream initialization request.
+     * Default is 10000ms.
+     * 
+     * @param targetResponseTimeout the timeout to set
+     */
+    public void setTargetResponseTimeout(int targetResponseTimeout) {
+        this.targetResponseTimeout = targetResponseTimeout;
+    }
+
+    /**
+     * Returns the timeout for connecting to the SOCKS5 proxy selected by the target. Default is
+     * 10000ms.
+     * 
+     * @return the timeout for connecting to the SOCKS5 proxy selected by the target
+     */
+    public int getProxyConnectionTimeout() {
+        if (this.proxyConnectionTimeout <= 0) {
+            this.proxyConnectionTimeout = 10000;
+        }
+        return proxyConnectionTimeout;
+    }
+
+    /**
+     * Sets the timeout for connecting to the SOCKS5 proxy selected by the target. Default is
+     * 10000ms.
+     * 
+     * @param proxyConnectionTimeout the timeout to set
+     */
+    public void setProxyConnectionTimeout(int proxyConnectionTimeout) {
+        this.proxyConnectionTimeout = proxyConnectionTimeout;
+    }
+
+    /**
+     * Returns if the prioritization of the last working SOCKS5 proxy on successive SOCKS5
+     * Bytestream connections is enabled. Default is <code>true</code>.
+     * 
+     * @return <code>true</code> if prioritization is enabled, <code>false</code> otherwise
+     */
+    public boolean isProxyPrioritizationEnabled() {
+        return proxyPrioritizationEnabled;
+    }
+
+    /**
+     * Enable/disable the prioritization of the last working SOCKS5 proxy on successive SOCKS5
+     * Bytestream connections.
+     * 
+     * @param proxyPrioritizationEnabled enable/disable the prioritization of the last working
+     *        SOCKS5 proxy
+     */
+    public void setProxyPrioritizationEnabled(boolean proxyPrioritizationEnabled) {
+        this.proxyPrioritizationEnabled = proxyPrioritizationEnabled;
+    }
+
+    /**
+     * Establishes a SOCKS5 Bytestream with the given user and returns the Socket to send/receive
+     * data to/from the user.
+     * <p>
+     * Use this method to establish SOCKS5 Bytestreams to users accepting all incoming Socks5
+     * bytestream requests since this method doesn't provide a way to tell the user something about
+     * the data to be sent.
+     * <p>
+     * To establish a SOCKS5 Bytestream after negotiation the kind of data to be sent (e.g. file
+     * transfer) use {@link #establishSession(String, String)}.
+     * 
+     * @param targetJID the JID of the user a SOCKS5 Bytestream should be established
+     * @return the Socket to send/receive data to/from the user
+     * @throws XMPPException if the user doesn't support or accept SOCKS5 Bytestreams, if no Socks5
+     *         Proxy could be found, if the user couldn't connect to any of the SOCKS5 Proxies
+     * @throws IOException if the bytestream could not be established
+     * @throws InterruptedException if the current thread was interrupted while waiting
+     */
+    public Socks5BytestreamSession establishSession(String targetJID) throws XMPPException,
+                    IOException, InterruptedException {
+        String sessionID = getNextSessionID();
+        return establishSession(targetJID, sessionID);
+    }
+
+    /**
+     * Establishes a SOCKS5 Bytestream with the given user using the given session ID and returns
+     * the Socket to send/receive data to/from the user.
+     * 
+     * @param targetJID the JID of the user a SOCKS5 Bytestream should be established
+     * @param sessionID the session ID for the SOCKS5 Bytestream request
+     * @return the Socket to send/receive data to/from the user
+     * @throws XMPPException if the user doesn't support or accept SOCKS5 Bytestreams, if no Socks5
+     *         Proxy could be found, if the user couldn't connect to any of the SOCKS5 Proxies
+     * @throws IOException if the bytestream could not be established
+     * @throws InterruptedException if the current thread was interrupted while waiting
+     */
+    public Socks5BytestreamSession establishSession(String targetJID, String sessionID)
+                    throws XMPPException, IOException, InterruptedException {
+
+        XMPPException discoveryException = null;
+        // check if target supports SOCKS5 Bytestream
+        if (!supportsSocks5(targetJID)) {
+            throw new XMPPException(targetJID + " doesn't support SOCKS5 Bytestream");
+        }
+
+        List<String> proxies = new ArrayList<String>();
+        // determine SOCKS5 proxies from XMPP-server
+        try {
+            proxies.addAll(determineProxies());
+        } catch (XMPPException e) {
+            // don't abort here, just remember the exception thrown by determineProxies()
+            // determineStreamHostInfos() will at least add the local Socks5 proxy (if enabled)
+            discoveryException = e;
+        }
+
+        // determine address and port of each proxy
+        List<StreamHost> streamHosts = determineStreamHostInfos(proxies);
+
+        if (streamHosts.isEmpty()) {
+            throw discoveryException != null ? discoveryException : new XMPPException("no SOCKS5 proxies available");
+        }
+
+        // compute digest
+        String digest = Socks5Utils.createDigest(sessionID, this.connection.getUser(), targetJID);
+
+        // prioritize last working SOCKS5 proxy if exists
+        if (this.proxyPrioritizationEnabled && this.lastWorkingProxy != null) {
+            StreamHost selectedStreamHost = null;
+            for (StreamHost streamHost : streamHosts) {
+                if (streamHost.getJID().equals(this.lastWorkingProxy)) {
+                    selectedStreamHost = streamHost;
+                    break;
+                }
+            }
+            if (selectedStreamHost != null) {
+                streamHosts.remove(selectedStreamHost);
+                streamHosts.add(0, selectedStreamHost);
+            }
+
+        }
+
+        Socks5Proxy socks5Proxy = Socks5Proxy.getSocks5Proxy();
+        try {
+
+            // add transfer digest to local proxy to make transfer valid
+            socks5Proxy.addTransfer(digest);
+
+            // create initiation packet
+            Bytestream initiation = createBytestreamInitiation(sessionID, targetJID, streamHosts);
+
+            // send initiation packet
+            Packet response = SyncPacketSend.getReply(this.connection, initiation,
+                            getTargetResponseTimeout());
+
+            // extract used stream host from response
+            StreamHostUsed streamHostUsed = ((Bytestream) response).getUsedHost();
+            StreamHost usedStreamHost = initiation.getStreamHost(streamHostUsed.getJID());
+
+            if (usedStreamHost == null) {
+                throw new XMPPException("Remote user responded with unknown host");
+            }
+
+            // build SOCKS5 client
+            Socks5Client socks5Client = new Socks5ClientForInitiator(usedStreamHost, digest,
+                            this.connection, sessionID, targetJID);
+
+            // establish connection to proxy
+            Socket socket = socks5Client.getSocket(getProxyConnectionTimeout());
+
+            // remember last working SOCKS5 proxy to prioritize it for next request
+            this.lastWorkingProxy = usedStreamHost.getJID();
+
+            // negotiation successful, return the output stream
+            return new Socks5BytestreamSession(socket, usedStreamHost.getJID().equals(
+                            this.connection.getUser()));
+
+        }
+        catch (TimeoutException e) {
+            throw new IOException("Timeout while connecting to SOCKS5 proxy");
+        }
+        finally {
+
+            // remove transfer digest if output stream is returned or an exception
+            // occurred
+            socks5Proxy.removeTransfer(digest);
+
+        }
+    }
+
+    /**
+     * Returns <code>true</code> if the given target JID supports feature SOCKS5 Bytestream.
+     * 
+     * @param targetJID the target JID
+     * @return <code>true</code> if the given target JID supports feature SOCKS5 Bytestream
+     *         otherwise <code>false</code>
+     * @throws XMPPException if there was an error querying target for supported features
+     */
+    private boolean supportsSocks5(String targetJID) throws XMPPException {
+        ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(this.connection);
+        DiscoverInfo discoverInfo = serviceDiscoveryManager.discoverInfo(targetJID);
+        return discoverInfo.containsFeature(NAMESPACE);
+    }
+
+    /**
+     * Returns a list of JIDs of SOCKS5 proxies by querying the XMPP server. The SOCKS5 proxies are
+     * in the same order as returned by the XMPP server.
+     * 
+     * @return list of JIDs of SOCKS5 proxies
+     * @throws XMPPException if there was an error querying the XMPP server for SOCKS5 proxies
+     */
+    private List<String> determineProxies() throws XMPPException {
+        ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(this.connection);
+
+        List<String> proxies = new ArrayList<String>();
+
+        // get all items form XMPP server
+        DiscoverItems discoverItems = serviceDiscoveryManager.discoverItems(this.connection.getServiceName());
+        Iterator<Item> itemIterator = discoverItems.getItems();
+
+        // query all items if they are SOCKS5 proxies
+        while (itemIterator.hasNext()) {
+            Item item = itemIterator.next();
+
+            // skip blacklisted servers
+            if (this.proxyBlacklist.contains(item.getEntityID())) {
+                continue;
+            }
+
+            try {
+                DiscoverInfo proxyInfo;
+                proxyInfo = serviceDiscoveryManager.discoverInfo(item.getEntityID());
+                Iterator<Identity> identities = proxyInfo.getIdentities();
+
+                // item must have category "proxy" and type "bytestream"
+                while (identities.hasNext()) {
+                    Identity identity = identities.next();
+
+                    if ("proxy".equalsIgnoreCase(identity.getCategory())
+                                    && "bytestreams".equalsIgnoreCase(identity.getType())) {
+                        proxies.add(item.getEntityID());
+                        break;
+                    }
+
+                    /*
+                     * server is not a SOCKS5 proxy, blacklist server to skip next time a Socks5
+                     * bytestream should be established
+                     */
+                    this.proxyBlacklist.add(item.getEntityID());
+
+                }
+            }
+            catch (XMPPException e) {
+                // blacklist errornous server
+                this.proxyBlacklist.add(item.getEntityID());
+            }
+        }
+
+        return proxies;
+    }
+
+    /**
+     * Returns a list of stream hosts containing the IP address an the port for the given list of
+     * SOCKS5 proxy JIDs. The order of the returned list is the same as the given list of JIDs
+     * excluding all SOCKS5 proxies who's network settings could not be determined. If a local
+     * SOCKS5 proxy is running it will be the first item in the list returned.
+     * 
+     * @param proxies a list of SOCKS5 proxy JIDs
+     * @return a list of stream hosts containing the IP address an the port
+     */
+    private List<StreamHost> determineStreamHostInfos(List<String> proxies) {
+        List<StreamHost> streamHosts = new ArrayList<StreamHost>();
+
+        // add local proxy on first position if exists
+        List<StreamHost> localProxies = getLocalStreamHost();
+        if (localProxies != null) {
+            streamHosts.addAll(localProxies);
+        }
+
+        // query SOCKS5 proxies for network settings
+        for (String proxy : proxies) {
+            Bytestream streamHostRequest = createStreamHostRequest(proxy);
+            try {
+                Bytestream response = (Bytestream) SyncPacketSend.getReply(this.connection,
+                                streamHostRequest);
+                streamHosts.addAll(response.getStreamHosts());
+            }
+            catch (XMPPException e) {
+                // blacklist errornous proxies
+                this.proxyBlacklist.add(proxy);
+            }
+        }
+
+        return streamHosts;
+    }
+
+    /**
+     * Returns a IQ packet to query a SOCKS5 proxy its network settings.
+     * 
+     * @param proxy the proxy to query
+     * @return IQ packet to query a SOCKS5 proxy its network settings
+     */
+    private Bytestream createStreamHostRequest(String proxy) {
+        Bytestream request = new Bytestream();
+        request.setType(IQ.Type.GET);
+        request.setTo(proxy);
+        return request;
+    }
+
+    /**
+     * Returns the stream host information of the local SOCKS5 proxy containing the IP address and
+     * the port or null if local SOCKS5 proxy is not running.
+     * 
+     * @return the stream host information of the local SOCKS5 proxy or null if local SOCKS5 proxy
+     *         is not running
+     */
+    private List<StreamHost> getLocalStreamHost() {
+
+        // get local proxy singleton
+        Socks5Proxy socks5Server = Socks5Proxy.getSocks5Proxy();
+
+        if (socks5Server.isRunning()) {
+            List<String> addresses = socks5Server.getLocalAddresses();
+            int port = socks5Server.getPort();
+
+            if (addresses.size() >= 1) {
+                List<StreamHost> streamHosts = new ArrayList<StreamHost>();
+                for (String address : addresses) {
+                    StreamHost streamHost = new StreamHost(this.connection.getUser(), address);
+                    streamHost.setPort(port);
+                    streamHosts.add(streamHost);
+                }
+                return streamHosts;
+            }
+
+        }
+
+        // server is not running or local address could not be determined
+        return null;
+    }
+
+    /**
+     * Returns a SOCKS5 Bytestream initialization request packet with the given session ID
+     * containing the given stream hosts for the given target JID.
+     * 
+     * @param sessionID the session ID for the SOCKS5 Bytestream
+     * @param targetJID the target JID of SOCKS5 Bytestream request
+     * @param streamHosts a list of SOCKS5 proxies the target should connect to
+     * @return a SOCKS5 Bytestream initialization request packet
+     */
+    private Bytestream createBytestreamInitiation(String sessionID, String targetJID,
+                    List<StreamHost> streamHosts) {
+        Bytestream initiation = new Bytestream(sessionID);
+
+        // add all stream hosts
+        for (StreamHost streamHost : streamHosts) {
+            initiation.addStreamHost(streamHost);
+        }
+
+        initiation.setType(IQ.Type.SET);
+        initiation.setTo(targetJID);
+
+        return initiation;
+    }
+
+    /**
+     * Responses to the given packet's sender with a XMPP error that a SOCKS5 Bytestream is not
+     * accepted.
+     * 
+     * @param packet Packet that should be answered with a not-acceptable error
+     */
+    protected void replyRejectPacket(IQ packet) {
+        XMPPError xmppError = new XMPPError(XMPPError.Condition.no_acceptable);
+        IQ errorIQ = IQ.createErrorResponse(packet, xmppError);
+        this.connection.sendPacket(errorIQ);
+    }
+
+    /**
+     * Activates the Socks5BytestreamManager by registering the SOCKS5 Bytestream initialization
+     * listener and enabling the SOCKS5 Bytestream feature.
+     */
+    private void activate() {
+        // register bytestream initiation packet listener
+        this.connection.addPacketListener(this.initiationListener,
+                        this.initiationListener.getFilter());
+
+        // enable SOCKS5 feature
+        enableService();
+    }
+
+    /**
+     * Adds the SOCKS5 Bytestream feature to the service discovery.
+     */
+    private void enableService() {
+        ServiceDiscoveryManager manager = ServiceDiscoveryManager.getInstanceFor(this.connection);
+        if (!manager.includesFeature(NAMESPACE)) {
+            manager.addFeature(NAMESPACE);
+        }
+    }
+
+    /**
+     * Returns a new unique session ID.
+     * 
+     * @return a new unique session ID
+     */
+    private String getNextSessionID() {
+        StringBuilder buffer = new StringBuilder();
+        buffer.append(SESSION_ID_PREFIX);
+        buffer.append(Math.abs(randomGenerator.nextLong()));
+        return buffer.toString();
+    }
+
+    /**
+     * Returns the XMPP connection.
+     * 
+     * @return the XMPP connection
+     */
+    protected Connection getConnection() {
+        return this.connection;
+    }
+
+    /**
+     * Returns the {@link BytestreamListener} that should be informed if a SOCKS5 Bytestream request
+     * from the given initiator JID is received.
+     * 
+     * @param initiator the initiator's JID
+     * @return the listener
+     */
+    protected BytestreamListener getUserListener(String initiator) {
+        return this.userListeners.get(initiator);
+    }
+
+    /**
+     * Returns a list of {@link BytestreamListener} that are informed if there are no listeners for
+     * a specific initiator.
+     * 
+     * @return list of listeners
+     */
+    protected List<BytestreamListener> getAllRequestListeners() {
+        return this.allRequestListeners;
+    }
+
+    /**
+     * Returns the list of session IDs that should be ignored by the InitialtionListener
+     * 
+     * @return list of session IDs
+     */
+    protected List<String> getIgnoredBytestreamRequests() {
+        return ignoredBytestreamRequests;
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamRequest.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamRequest.java
index 0b2fdeb..5d8f002 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamRequest.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamRequest.java
@@ -1,316 +1,316 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.socks5;
-
-import java.io.IOException;
-import java.net.Socket;
-import java.util.Collection;
-import java.util.concurrent.TimeoutException;
-
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.XMPPError;
-import org.jivesoftware.smack.util.Cache;
-import org.jivesoftware.smackx.bytestreams.BytestreamRequest;
-import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
-import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost;
-
-/**
- * Socks5BytestreamRequest class handles incoming SOCKS5 Bytestream requests.
- * 
- * @author Henning Staib
- */
-public class Socks5BytestreamRequest implements BytestreamRequest {
-
-    /* lifetime of an Item in the blacklist */
-    private static final long BLACKLIST_LIFETIME = 60 * 1000 * 120;
-
-    /* size of the blacklist */
-    private static final int BLACKLIST_MAX_SIZE = 100;
-
-    /* blacklist of addresses of SOCKS5 proxies */
-    private static final Cache<String, Integer> ADDRESS_BLACKLIST = new Cache<String, Integer>(
-                    BLACKLIST_MAX_SIZE, BLACKLIST_LIFETIME);
-
-    /*
-     * The number of connection failures it takes for a particular SOCKS5 proxy to be blacklisted.
-     * When a proxy is blacklisted no more connection attempts will be made to it for a period of 2
-     * hours.
-     */
-    private static int CONNECTION_FAILURE_THRESHOLD = 2;
-
-    /* the bytestream initialization request */
-    private Bytestream bytestreamRequest;
-
-    /* SOCKS5 Bytestream manager containing the XMPP connection and helper methods */
-    private Socks5BytestreamManager manager;
-
-    /* timeout to connect to all SOCKS5 proxies */
-    private int totalConnectTimeout = 10000;
-
-    /* minimum timeout to connect to one SOCKS5 proxy */
-    private int minimumConnectTimeout = 2000;
-
-    /**
-     * Returns the number of connection failures it takes for a particular SOCKS5 proxy to be
-     * blacklisted. When a proxy is blacklisted no more connection attempts will be made to it for a
-     * period of 2 hours. Default is 2.
-     * 
-     * @return the number of connection failures it takes for a particular SOCKS5 proxy to be
-     *         blacklisted
-     */
-    public static int getConnectFailureThreshold() {
-        return CONNECTION_FAILURE_THRESHOLD;
-    }
-
-    /**
-     * Sets the number of connection failures it takes for a particular SOCKS5 proxy to be
-     * blacklisted. When a proxy is blacklisted no more connection attempts will be made to it for a
-     * period of 2 hours. Default is 2.
-     * <p>
-     * Setting the connection failure threshold to zero disables the blacklisting.
-     * 
-     * @param connectFailureThreshold the number of connection failures it takes for a particular
-     *        SOCKS5 proxy to be blacklisted
-     */
-    public static void setConnectFailureThreshold(int connectFailureThreshold) {
-        CONNECTION_FAILURE_THRESHOLD = connectFailureThreshold;
-    }
-
-    /**
-     * Creates a new Socks5BytestreamRequest.
-     * 
-     * @param manager the SOCKS5 Bytestream manager
-     * @param bytestreamRequest the SOCKS5 Bytestream initialization packet
-     */
-    protected Socks5BytestreamRequest(Socks5BytestreamManager manager, Bytestream bytestreamRequest) {
-        this.manager = manager;
-        this.bytestreamRequest = bytestreamRequest;
-    }
-
-    /**
-     * Returns the maximum timeout to connect to SOCKS5 proxies. Default is 10000ms.
-     * <p>
-     * When accepting a SOCKS5 Bytestream request Smack tries to connect to all SOCKS5 proxies given
-     * by the initiator until a connection is established. This timeout divided by the number of
-     * SOCKS5 proxies determines the timeout for every connection attempt.
-     * <p>
-     * You can set the minimum timeout for establishing a connection to one SOCKS5 proxy by invoking
-     * {@link #setMinimumConnectTimeout(int)}.
-     * 
-     * @return the maximum timeout to connect to SOCKS5 proxies
-     */
-    public int getTotalConnectTimeout() {
-        if (this.totalConnectTimeout <= 0) {
-            return 10000;
-        }
-        return this.totalConnectTimeout;
-    }
-
-    /**
-     * Sets the maximum timeout to connect to SOCKS5 proxies. Default is 10000ms.
-     * <p>
-     * When accepting a SOCKS5 Bytestream request Smack tries to connect to all SOCKS5 proxies given
-     * by the initiator until a connection is established. This timeout divided by the number of
-     * SOCKS5 proxies determines the timeout for every connection attempt.
-     * <p>
-     * You can set the minimum timeout for establishing a connection to one SOCKS5 proxy by invoking
-     * {@link #setMinimumConnectTimeout(int)}.
-     * 
-     * @param totalConnectTimeout the maximum timeout to connect to SOCKS5 proxies
-     */
-    public void setTotalConnectTimeout(int totalConnectTimeout) {
-        this.totalConnectTimeout = totalConnectTimeout;
-    }
-
-    /**
-     * Returns the timeout to connect to one SOCKS5 proxy while accepting the SOCKS5 Bytestream
-     * request. Default is 2000ms.
-     * 
-     * @return the timeout to connect to one SOCKS5 proxy
-     */
-    public int getMinimumConnectTimeout() {
-        if (this.minimumConnectTimeout <= 0) {
-            return 2000;
-        }
-        return this.minimumConnectTimeout;
-    }
-
-    /**
-     * Sets the timeout to connect to one SOCKS5 proxy while accepting the SOCKS5 Bytestream
-     * request. Default is 2000ms.
-     * 
-     * @param minimumConnectTimeout the timeout to connect to one SOCKS5 proxy
-     */
-    public void setMinimumConnectTimeout(int minimumConnectTimeout) {
-        this.minimumConnectTimeout = minimumConnectTimeout;
-    }
-
-    /**
-     * Returns the sender of the SOCKS5 Bytestream initialization request.
-     * 
-     * @return the sender of the SOCKS5 Bytestream initialization request.
-     */
-    public String getFrom() {
-        return this.bytestreamRequest.getFrom();
-    }
-
-    /**
-     * Returns the session ID of the SOCKS5 Bytestream initialization request.
-     * 
-     * @return the session ID of the SOCKS5 Bytestream initialization request.
-     */
-    public String getSessionID() {
-        return this.bytestreamRequest.getSessionID();
-    }
-
-    /**
-     * Accepts the SOCKS5 Bytestream initialization request and returns the socket to send/receive
-     * data.
-     * <p>
-     * Before accepting the SOCKS5 Bytestream request you can set timeouts by invoking
-     * {@link #setTotalConnectTimeout(int)} and {@link #setMinimumConnectTimeout(int)}.
-     * 
-     * @return the socket to send/receive data
-     * @throws XMPPException if connection to all SOCKS5 proxies failed or if stream is invalid.
-     * @throws InterruptedException if the current thread was interrupted while waiting
-     */
-    public Socks5BytestreamSession accept() throws XMPPException, InterruptedException {
-        Collection<StreamHost> streamHosts = this.bytestreamRequest.getStreamHosts();
-
-        // throw exceptions if request contains no stream hosts
-        if (streamHosts.size() == 0) {
-            cancelRequest();
-        }
-
-        StreamHost selectedHost = null;
-        Socket socket = null;
-
-        String digest = Socks5Utils.createDigest(this.bytestreamRequest.getSessionID(),
-                        this.bytestreamRequest.getFrom(), this.manager.getConnection().getUser());
-
-        /*
-         * determine timeout for each connection attempt; each SOCKS5 proxy has the same amount of
-         * time so that the first does not consume the whole timeout
-         */
-        int timeout = Math.max(getTotalConnectTimeout() / streamHosts.size(),
-                        getMinimumConnectTimeout());
-
-        for (StreamHost streamHost : streamHosts) {
-            String address = streamHost.getAddress() + ":" + streamHost.getPort();
-
-            // check to see if this address has been blacklisted
-            int failures = getConnectionFailures(address);
-            if (CONNECTION_FAILURE_THRESHOLD > 0 && failures >= CONNECTION_FAILURE_THRESHOLD) {
-                continue;
-            }
-
-            // establish socket
-            try {
-
-                // build SOCKS5 client
-                final Socks5Client socks5Client = new Socks5Client(streamHost, digest);
-
-                // connect to SOCKS5 proxy with a timeout
-                socket = socks5Client.getSocket(timeout);
-
-                // set selected host
-                selectedHost = streamHost;
-                break;
-
-            }
-            catch (TimeoutException e) {
-                incrementConnectionFailures(address);
-            }
-            catch (IOException e) {
-                incrementConnectionFailures(address);
-            }
-            catch (XMPPException e) {
-                incrementConnectionFailures(address);
-            }
-
-        }
-
-        // throw exception if connecting to all SOCKS5 proxies failed
-        if (selectedHost == null || socket == null) {
-            cancelRequest();
-        }
-
-        // send used-host confirmation
-        Bytestream response = createUsedHostResponse(selectedHost);
-        this.manager.getConnection().sendPacket(response);
-
-        return new Socks5BytestreamSession(socket, selectedHost.getJID().equals(
-                        this.bytestreamRequest.getFrom()));
-
-    }
-
-    /**
-     * Rejects the SOCKS5 Bytestream request by sending a reject error to the initiator.
-     */
-    public void reject() {
-        this.manager.replyRejectPacket(this.bytestreamRequest);
-    }
-
-    /**
-     * Cancels the SOCKS5 Bytestream request by sending an error to the initiator and building a
-     * XMPP exception.
-     * 
-     * @throws XMPPException XMPP exception containing the XMPP error
-     */
-    private void cancelRequest() throws XMPPException {
-        String errorMessage = "Could not establish socket with any provided host";
-        XMPPError error = new XMPPError(XMPPError.Condition.item_not_found, errorMessage);
-        IQ errorIQ = IQ.createErrorResponse(this.bytestreamRequest, error);
-        this.manager.getConnection().sendPacket(errorIQ);
-        throw new XMPPException(errorMessage, error);
-    }
-
-    /**
-     * Returns the response to the SOCKS5 Bytestream request containing the SOCKS5 proxy used.
-     * 
-     * @param selectedHost the used SOCKS5 proxy
-     * @return the response to the SOCKS5 Bytestream request
-     */
-    private Bytestream createUsedHostResponse(StreamHost selectedHost) {
-        Bytestream response = new Bytestream(this.bytestreamRequest.getSessionID());
-        response.setTo(this.bytestreamRequest.getFrom());
-        response.setType(IQ.Type.RESULT);
-        response.setPacketID(this.bytestreamRequest.getPacketID());
-        response.setUsedHost(selectedHost.getJID());
-        return response;
-    }
-
-    /**
-     * Increments the connection failure counter by one for the given address.
-     * 
-     * @param address the address the connection failure counter should be increased
-     */
-    private void incrementConnectionFailures(String address) {
-        Integer count = ADDRESS_BLACKLIST.get(address);
-        ADDRESS_BLACKLIST.put(address, count == null ? 1 : count + 1);
-    }
-
-    /**
-     * Returns how often the connection to the given address failed.
-     * 
-     * @param address the address
-     * @return number of connection failures
-     */
-    private int getConnectionFailures(String address) {
-        Integer count = ADDRESS_BLACKLIST.get(address);
-        return count != null ? count : 0;
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.socks5;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.Collection;
+import java.util.concurrent.TimeoutException;
+
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.XMPPError;
+import org.jivesoftware.smack.util.Cache;
+import org.jivesoftware.smackx.bytestreams.BytestreamRequest;
+import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
+import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost;
+
+/**
+ * Socks5BytestreamRequest class handles incoming SOCKS5 Bytestream requests.
+ * 
+ * @author Henning Staib
+ */
+public class Socks5BytestreamRequest implements BytestreamRequest {
+
+    /* lifetime of an Item in the blacklist */
+    private static final long BLACKLIST_LIFETIME = 60 * 1000 * 120;
+
+    /* size of the blacklist */
+    private static final int BLACKLIST_MAX_SIZE = 100;
+
+    /* blacklist of addresses of SOCKS5 proxies */
+    private static final Cache<String, Integer> ADDRESS_BLACKLIST = new Cache<String, Integer>(
+                    BLACKLIST_MAX_SIZE, BLACKLIST_LIFETIME);
+
+    /*
+     * The number of connection failures it takes for a particular SOCKS5 proxy to be blacklisted.
+     * When a proxy is blacklisted no more connection attempts will be made to it for a period of 2
+     * hours.
+     */
+    private static int CONNECTION_FAILURE_THRESHOLD = 2;
+
+    /* the bytestream initialization request */
+    private Bytestream bytestreamRequest;
+
+    /* SOCKS5 Bytestream manager containing the XMPP connection and helper methods */
+    private Socks5BytestreamManager manager;
+
+    /* timeout to connect to all SOCKS5 proxies */
+    private int totalConnectTimeout = 10000;
+
+    /* minimum timeout to connect to one SOCKS5 proxy */
+    private int minimumConnectTimeout = 2000;
+
+    /**
+     * Returns the number of connection failures it takes for a particular SOCKS5 proxy to be
+     * blacklisted. When a proxy is blacklisted no more connection attempts will be made to it for a
+     * period of 2 hours. Default is 2.
+     * 
+     * @return the number of connection failures it takes for a particular SOCKS5 proxy to be
+     *         blacklisted
+     */
+    public static int getConnectFailureThreshold() {
+        return CONNECTION_FAILURE_THRESHOLD;
+    }
+
+    /**
+     * Sets the number of connection failures it takes for a particular SOCKS5 proxy to be
+     * blacklisted. When a proxy is blacklisted no more connection attempts will be made to it for a
+     * period of 2 hours. Default is 2.
+     * <p>
+     * Setting the connection failure threshold to zero disables the blacklisting.
+     * 
+     * @param connectFailureThreshold the number of connection failures it takes for a particular
+     *        SOCKS5 proxy to be blacklisted
+     */
+    public static void setConnectFailureThreshold(int connectFailureThreshold) {
+        CONNECTION_FAILURE_THRESHOLD = connectFailureThreshold;
+    }
+
+    /**
+     * Creates a new Socks5BytestreamRequest.
+     * 
+     * @param manager the SOCKS5 Bytestream manager
+     * @param bytestreamRequest the SOCKS5 Bytestream initialization packet
+     */
+    protected Socks5BytestreamRequest(Socks5BytestreamManager manager, Bytestream bytestreamRequest) {
+        this.manager = manager;
+        this.bytestreamRequest = bytestreamRequest;
+    }
+
+    /**
+     * Returns the maximum timeout to connect to SOCKS5 proxies. Default is 10000ms.
+     * <p>
+     * When accepting a SOCKS5 Bytestream request Smack tries to connect to all SOCKS5 proxies given
+     * by the initiator until a connection is established. This timeout divided by the number of
+     * SOCKS5 proxies determines the timeout for every connection attempt.
+     * <p>
+     * You can set the minimum timeout for establishing a connection to one SOCKS5 proxy by invoking
+     * {@link #setMinimumConnectTimeout(int)}.
+     * 
+     * @return the maximum timeout to connect to SOCKS5 proxies
+     */
+    public int getTotalConnectTimeout() {
+        if (this.totalConnectTimeout <= 0) {
+            return 10000;
+        }
+        return this.totalConnectTimeout;
+    }
+
+    /**
+     * Sets the maximum timeout to connect to SOCKS5 proxies. Default is 10000ms.
+     * <p>
+     * When accepting a SOCKS5 Bytestream request Smack tries to connect to all SOCKS5 proxies given
+     * by the initiator until a connection is established. This timeout divided by the number of
+     * SOCKS5 proxies determines the timeout for every connection attempt.
+     * <p>
+     * You can set the minimum timeout for establishing a connection to one SOCKS5 proxy by invoking
+     * {@link #setMinimumConnectTimeout(int)}.
+     * 
+     * @param totalConnectTimeout the maximum timeout to connect to SOCKS5 proxies
+     */
+    public void setTotalConnectTimeout(int totalConnectTimeout) {
+        this.totalConnectTimeout = totalConnectTimeout;
+    }
+
+    /**
+     * Returns the timeout to connect to one SOCKS5 proxy while accepting the SOCKS5 Bytestream
+     * request. Default is 2000ms.
+     * 
+     * @return the timeout to connect to one SOCKS5 proxy
+     */
+    public int getMinimumConnectTimeout() {
+        if (this.minimumConnectTimeout <= 0) {
+            return 2000;
+        }
+        return this.minimumConnectTimeout;
+    }
+
+    /**
+     * Sets the timeout to connect to one SOCKS5 proxy while accepting the SOCKS5 Bytestream
+     * request. Default is 2000ms.
+     * 
+     * @param minimumConnectTimeout the timeout to connect to one SOCKS5 proxy
+     */
+    public void setMinimumConnectTimeout(int minimumConnectTimeout) {
+        this.minimumConnectTimeout = minimumConnectTimeout;
+    }
+
+    /**
+     * Returns the sender of the SOCKS5 Bytestream initialization request.
+     * 
+     * @return the sender of the SOCKS5 Bytestream initialization request.
+     */
+    public String getFrom() {
+        return this.bytestreamRequest.getFrom();
+    }
+
+    /**
+     * Returns the session ID of the SOCKS5 Bytestream initialization request.
+     * 
+     * @return the session ID of the SOCKS5 Bytestream initialization request.
+     */
+    public String getSessionID() {
+        return this.bytestreamRequest.getSessionID();
+    }
+
+    /**
+     * Accepts the SOCKS5 Bytestream initialization request and returns the socket to send/receive
+     * data.
+     * <p>
+     * Before accepting the SOCKS5 Bytestream request you can set timeouts by invoking
+     * {@link #setTotalConnectTimeout(int)} and {@link #setMinimumConnectTimeout(int)}.
+     * 
+     * @return the socket to send/receive data
+     * @throws XMPPException if connection to all SOCKS5 proxies failed or if stream is invalid.
+     * @throws InterruptedException if the current thread was interrupted while waiting
+     */
+    public Socks5BytestreamSession accept() throws XMPPException, InterruptedException {
+        Collection<StreamHost> streamHosts = this.bytestreamRequest.getStreamHosts();
+
+        // throw exceptions if request contains no stream hosts
+        if (streamHosts.size() == 0) {
+            cancelRequest();
+        }
+
+        StreamHost selectedHost = null;
+        Socket socket = null;
+
+        String digest = Socks5Utils.createDigest(this.bytestreamRequest.getSessionID(),
+                        this.bytestreamRequest.getFrom(), this.manager.getConnection().getUser());
+
+        /*
+         * determine timeout for each connection attempt; each SOCKS5 proxy has the same amount of
+         * time so that the first does not consume the whole timeout
+         */
+        int timeout = Math.max(getTotalConnectTimeout() / streamHosts.size(),
+                        getMinimumConnectTimeout());
+
+        for (StreamHost streamHost : streamHosts) {
+            String address = streamHost.getAddress() + ":" + streamHost.getPort();
+
+            // check to see if this address has been blacklisted
+            int failures = getConnectionFailures(address);
+            if (CONNECTION_FAILURE_THRESHOLD > 0 && failures >= CONNECTION_FAILURE_THRESHOLD) {
+                continue;
+            }
+
+            // establish socket
+            try {
+
+                // build SOCKS5 client
+                final Socks5Client socks5Client = new Socks5Client(streamHost, digest);
+
+                // connect to SOCKS5 proxy with a timeout
+                socket = socks5Client.getSocket(timeout);
+
+                // set selected host
+                selectedHost = streamHost;
+                break;
+
+            }
+            catch (TimeoutException e) {
+                incrementConnectionFailures(address);
+            }
+            catch (IOException e) {
+                incrementConnectionFailures(address);
+            }
+            catch (XMPPException e) {
+                incrementConnectionFailures(address);
+            }
+
+        }
+
+        // throw exception if connecting to all SOCKS5 proxies failed
+        if (selectedHost == null || socket == null) {
+            cancelRequest();
+        }
+
+        // send used-host confirmation
+        Bytestream response = createUsedHostResponse(selectedHost);
+        this.manager.getConnection().sendPacket(response);
+
+        return new Socks5BytestreamSession(socket, selectedHost.getJID().equals(
+                        this.bytestreamRequest.getFrom()));
+
+    }
+
+    /**
+     * Rejects the SOCKS5 Bytestream request by sending a reject error to the initiator.
+     */
+    public void reject() {
+        this.manager.replyRejectPacket(this.bytestreamRequest);
+    }
+
+    /**
+     * Cancels the SOCKS5 Bytestream request by sending an error to the initiator and building a
+     * XMPP exception.
+     * 
+     * @throws XMPPException XMPP exception containing the XMPP error
+     */
+    private void cancelRequest() throws XMPPException {
+        String errorMessage = "Could not establish socket with any provided host";
+        XMPPError error = new XMPPError(XMPPError.Condition.item_not_found, errorMessage);
+        IQ errorIQ = IQ.createErrorResponse(this.bytestreamRequest, error);
+        this.manager.getConnection().sendPacket(errorIQ);
+        throw new XMPPException(errorMessage, error);
+    }
+
+    /**
+     * Returns the response to the SOCKS5 Bytestream request containing the SOCKS5 proxy used.
+     * 
+     * @param selectedHost the used SOCKS5 proxy
+     * @return the response to the SOCKS5 Bytestream request
+     */
+    private Bytestream createUsedHostResponse(StreamHost selectedHost) {
+        Bytestream response = new Bytestream(this.bytestreamRequest.getSessionID());
+        response.setTo(this.bytestreamRequest.getFrom());
+        response.setType(IQ.Type.RESULT);
+        response.setPacketID(this.bytestreamRequest.getPacketID());
+        response.setUsedHost(selectedHost.getJID());
+        return response;
+    }
+
+    /**
+     * Increments the connection failure counter by one for the given address.
+     * 
+     * @param address the address the connection failure counter should be increased
+     */
+    private void incrementConnectionFailures(String address) {
+        Integer count = ADDRESS_BLACKLIST.get(address);
+        ADDRESS_BLACKLIST.put(address, count == null ? 1 : count + 1);
+    }
+
+    /**
+     * Returns how often the connection to the given address failed.
+     * 
+     * @param address the address
+     * @return number of connection failures
+     */
+    private int getConnectionFailures(String address) {
+        Integer count = ADDRESS_BLACKLIST.get(address);
+        return count != null ? count : 0;
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamSession.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamSession.java
index 41ab142..267dafc 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamSession.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamSession.java
@@ -15,84 +15,84 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jivesoftware.smackx.bytestreams.socks5;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-import java.net.SocketException;
-
-import org.jivesoftware.smackx.bytestreams.BytestreamSession;
-
-/**
- * Socks5BytestreamSession class represents a SOCKS5 Bytestream session.
- * 
- * @author Henning Staib
- */
-public class Socks5BytestreamSession implements BytestreamSession {
-
-    /* the underlying socket of the SOCKS5 Bytestream */
-    private final Socket socket;
-
-    /* flag to indicate if this session is a direct or mediated connection */
-    private final boolean isDirect;
-
-    protected Socks5BytestreamSession(Socket socket, boolean isDirect) {
-        this.socket = socket;
-        this.isDirect = isDirect;
-    }
-
-    /**
-     * Returns <code>true</code> if the session is established through a direct connection between
-     * the initiator and target, <code>false</code> if the session is mediated over a SOCKS proxy.
-     * 
-     * @return <code>true</code> if session is a direct connection, <code>false</code> if session is
-     *         mediated over a SOCKS5 proxy
-     */
-    public boolean isDirect() {
-        return this.isDirect;
-    }
-
-    /**
-     * Returns <code>true</code> if the session is mediated over a SOCKS proxy, <code>false</code>
-     * if this session is established through a direct connection between the initiator and target.
-     * 
-     * @return <code>true</code> if session is mediated over a SOCKS5 proxy, <code>false</code> if
-     *         session is a direct connection
-     */
-    public boolean isMediated() {
-        return !this.isDirect;
-    }
-
-    public InputStream getInputStream() throws IOException {
-        return this.socket.getInputStream();
-    }
-
-    public OutputStream getOutputStream() throws IOException {
-        return this.socket.getOutputStream();
-    }
-
-    public int getReadTimeout() throws IOException {
-        try {
-            return this.socket.getSoTimeout();
-        }
-        catch (SocketException e) {
-            throw new IOException("Error on underlying Socket");
-        }
-    }
-
-    public void setReadTimeout(int timeout) throws IOException {
-        try {
-            this.socket.setSoTimeout(timeout);
-        }
-        catch (SocketException e) {
-            throw new IOException("Error on underlying Socket");
-        }
-    }
-
-    public void close() throws IOException {
-        this.socket.close();
-    }
-
-}
+package org.jivesoftware.smackx.bytestreams.socks5;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.net.SocketException;
+
+import org.jivesoftware.smackx.bytestreams.BytestreamSession;
+
+/**
+ * Socks5BytestreamSession class represents a SOCKS5 Bytestream session.
+ * 
+ * @author Henning Staib
+ */
+public class Socks5BytestreamSession implements BytestreamSession {
+
+    /* the underlying socket of the SOCKS5 Bytestream */
+    private final Socket socket;
+
+    /* flag to indicate if this session is a direct or mediated connection */
+    private final boolean isDirect;
+
+    protected Socks5BytestreamSession(Socket socket, boolean isDirect) {
+        this.socket = socket;
+        this.isDirect = isDirect;
+    }
+
+    /**
+     * Returns <code>true</code> if the session is established through a direct connection between
+     * the initiator and target, <code>false</code> if the session is mediated over a SOCKS proxy.
+     * 
+     * @return <code>true</code> if session is a direct connection, <code>false</code> if session is
+     *         mediated over a SOCKS5 proxy
+     */
+    public boolean isDirect() {
+        return this.isDirect;
+    }
+
+    /**
+     * Returns <code>true</code> if the session is mediated over a SOCKS proxy, <code>false</code>
+     * if this session is established through a direct connection between the initiator and target.
+     * 
+     * @return <code>true</code> if session is mediated over a SOCKS5 proxy, <code>false</code> if
+     *         session is a direct connection
+     */
+    public boolean isMediated() {
+        return !this.isDirect;
+    }
+
+    public InputStream getInputStream() throws IOException {
+        return this.socket.getInputStream();
+    }
+
+    public OutputStream getOutputStream() throws IOException {
+        return this.socket.getOutputStream();
+    }
+
+    public int getReadTimeout() throws IOException {
+        try {
+            return this.socket.getSoTimeout();
+        }
+        catch (SocketException e) {
+            throw new IOException("Error on underlying Socket");
+        }
+    }
+
+    public void setReadTimeout(int timeout) throws IOException {
+        try {
+            this.socket.setSoTimeout(timeout);
+        }
+        catch (SocketException e) {
+            throw new IOException("Error on underlying Socket");
+        }
+    }
+
+    public void close() throws IOException {
+        this.socket.close();
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5Client.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5Client.java
index 664ea59..62c925a 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5Client.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5Client.java
@@ -1,204 +1,204 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.socks5;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.util.Arrays;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost;
-
-/**
- * The SOCKS5 client class handles establishing a connection to a SOCKS5 proxy. Connecting to a
- * SOCKS5 proxy requires authentication. This implementation only supports the no-authentication
- * authentication method.
- * 
- * @author Henning Staib
- */
-class Socks5Client {
-
-    /* stream host containing network settings and name of the SOCKS5 proxy */
-    protected StreamHost streamHost;
-
-    /* SHA-1 digest identifying the SOCKS5 stream */
-    protected String digest;
-
-    /**
-     * Constructor for a SOCKS5 client.
-     * 
-     * @param streamHost containing network settings of the SOCKS5 proxy
-     * @param digest identifying the SOCKS5 Bytestream
-     */
-    public Socks5Client(StreamHost streamHost, String digest) {
-        this.streamHost = streamHost;
-        this.digest = digest;
-    }
-
-    /**
-     * Returns the initialized socket that can be used to transfer data between peers via the SOCKS5
-     * proxy.
-     * 
-     * @param timeout timeout to connect to SOCKS5 proxy in milliseconds
-     * @return socket the initialized socket
-     * @throws IOException if initializing the socket failed due to a network error
-     * @throws XMPPException if establishing connection to SOCKS5 proxy failed
-     * @throws TimeoutException if connecting to SOCKS5 proxy timed out
-     * @throws InterruptedException if the current thread was interrupted while waiting
-     */
-    public Socket getSocket(int timeout) throws IOException, XMPPException, InterruptedException,
-                    TimeoutException {
-
-        // wrap connecting in future for timeout
-        FutureTask<Socket> futureTask = new FutureTask<Socket>(new Callable<Socket>() {
-
-            public Socket call() throws Exception {
-
-                // initialize socket
-                Socket socket = new Socket();
-                SocketAddress socketAddress = new InetSocketAddress(streamHost.getAddress(),
-                                streamHost.getPort());
-                socket.connect(socketAddress);
-
-                // initialize connection to SOCKS5 proxy
-                if (!establish(socket)) {
-
-                    // initialization failed, close socket
-                    socket.close();
-                    throw new XMPPException("establishing connection to SOCKS5 proxy failed");
-
-                }
-
-                return socket;
-            }
-
-        });
-        Thread executor = new Thread(futureTask);
-        executor.start();
-
-        // get connection to initiator with timeout
-        try {
-            return futureTask.get(timeout, TimeUnit.MILLISECONDS);
-        }
-        catch (ExecutionException e) {
-            Throwable cause = e.getCause();
-            if (cause != null) {
-                // case exceptions to comply with method signature
-                if (cause instanceof IOException) {
-                    throw (IOException) cause;
-                }
-                if (cause instanceof XMPPException) {
-                    throw (XMPPException) cause;
-                }
-            }
-
-            // throw generic IO exception if unexpected exception was thrown
-            throw new IOException("Error while connection to SOCKS5 proxy");
-        }
-
-    }
-
-    /**
-     * Initializes the connection to the SOCKS5 proxy by negotiating authentication method and
-     * requesting a stream for the given digest. Currently only the no-authentication method is
-     * supported by the Socks5Client.
-     * <p>
-     * Returns <code>true</code> if a stream could be established, otherwise <code>false</code>. If
-     * <code>false</code> is returned the given Socket should be closed.
-     * 
-     * @param socket connected to a SOCKS5 proxy
-     * @return <code>true</code> if if a stream could be established, otherwise <code>false</code>.
-     *         If <code>false</code> is returned the given Socket should be closed.
-     * @throws IOException if a network error occurred
-     */
-    protected boolean establish(Socket socket) throws IOException {
-
-        /*
-         * use DataInputStream/DataOutpuStream to assure read and write is completed in a single
-         * statement
-         */
-        DataInputStream in = new DataInputStream(socket.getInputStream());
-        DataOutputStream out = new DataOutputStream(socket.getOutputStream());
-
-        // authentication negotiation
-        byte[] cmd = new byte[3];
-
-        cmd[0] = (byte) 0x05; // protocol version 5
-        cmd[1] = (byte) 0x01; // number of authentication methods supported
-        cmd[2] = (byte) 0x00; // authentication method: no-authentication required
-
-        out.write(cmd);
-        out.flush();
-
-        byte[] response = new byte[2];
-        in.readFully(response);
-
-        // check if server responded with correct version and no-authentication method
-        if (response[0] != (byte) 0x05 || response[1] != (byte) 0x00) {
-            return false;
-        }
-
-        // request SOCKS5 connection with given address/digest
-        byte[] connectionRequest = createSocks5ConnectRequest();
-        out.write(connectionRequest);
-        out.flush();
-
-        // receive response
-        byte[] connectionResponse;
-        try {
-            connectionResponse = Socks5Utils.receiveSocks5Message(in);
-        }
-        catch (XMPPException e) {
-            return false; // server answered in an unsupported way
-        }
-
-        // verify response
-        connectionRequest[1] = (byte) 0x00; // set expected return status to 0
-        return Arrays.equals(connectionRequest, connectionResponse);
-    }
-
-    /**
-     * Returns a SOCKS5 connection request message. It contains the command "connect", the address
-     * type "domain" and the digest as address.
-     * <p>
-     * (see <a href="http://tools.ietf.org/html/rfc1928">RFC1928</a>)
-     * 
-     * @return SOCKS5 connection request message
-     */
-    private byte[] createSocks5ConnectRequest() {
-        byte addr[] = this.digest.getBytes();
-
-        byte[] data = new byte[7 + addr.length];
-        data[0] = (byte) 0x05; // version (SOCKS5)
-        data[1] = (byte) 0x01; // command (1 - connect)
-        data[2] = (byte) 0x00; // reserved byte (always 0)
-        data[3] = (byte) 0x03; // address type (3 - domain name)
-        data[4] = (byte) addr.length; // address length
-        System.arraycopy(addr, 0, data, 5, addr.length); // address
-        data[data.length - 2] = (byte) 0; // address port (2 bytes always 0)
-        data[data.length - 1] = (byte) 0;
-
-        return data;
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.socks5;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.util.Arrays;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost;
+
+/**
+ * The SOCKS5 client class handles establishing a connection to a SOCKS5 proxy. Connecting to a
+ * SOCKS5 proxy requires authentication. This implementation only supports the no-authentication
+ * authentication method.
+ * 
+ * @author Henning Staib
+ */
+class Socks5Client {
+
+    /* stream host containing network settings and name of the SOCKS5 proxy */
+    protected StreamHost streamHost;
+
+    /* SHA-1 digest identifying the SOCKS5 stream */
+    protected String digest;
+
+    /**
+     * Constructor for a SOCKS5 client.
+     * 
+     * @param streamHost containing network settings of the SOCKS5 proxy
+     * @param digest identifying the SOCKS5 Bytestream
+     */
+    public Socks5Client(StreamHost streamHost, String digest) {
+        this.streamHost = streamHost;
+        this.digest = digest;
+    }
+
+    /**
+     * Returns the initialized socket that can be used to transfer data between peers via the SOCKS5
+     * proxy.
+     * 
+     * @param timeout timeout to connect to SOCKS5 proxy in milliseconds
+     * @return socket the initialized socket
+     * @throws IOException if initializing the socket failed due to a network error
+     * @throws XMPPException if establishing connection to SOCKS5 proxy failed
+     * @throws TimeoutException if connecting to SOCKS5 proxy timed out
+     * @throws InterruptedException if the current thread was interrupted while waiting
+     */
+    public Socket getSocket(int timeout) throws IOException, XMPPException, InterruptedException,
+                    TimeoutException {
+
+        // wrap connecting in future for timeout
+        FutureTask<Socket> futureTask = new FutureTask<Socket>(new Callable<Socket>() {
+
+            public Socket call() throws Exception {
+
+                // initialize socket
+                Socket socket = new Socket();
+                SocketAddress socketAddress = new InetSocketAddress(streamHost.getAddress(),
+                                streamHost.getPort());
+                socket.connect(socketAddress);
+
+                // initialize connection to SOCKS5 proxy
+                if (!establish(socket)) {
+
+                    // initialization failed, close socket
+                    socket.close();
+                    throw new XMPPException("establishing connection to SOCKS5 proxy failed");
+
+                }
+
+                return socket;
+            }
+
+        });
+        Thread executor = new Thread(futureTask);
+        executor.start();
+
+        // get connection to initiator with timeout
+        try {
+            return futureTask.get(timeout, TimeUnit.MILLISECONDS);
+        }
+        catch (ExecutionException e) {
+            Throwable cause = e.getCause();
+            if (cause != null) {
+                // case exceptions to comply with method signature
+                if (cause instanceof IOException) {
+                    throw (IOException) cause;
+                }
+                if (cause instanceof XMPPException) {
+                    throw (XMPPException) cause;
+                }
+            }
+
+            // throw generic IO exception if unexpected exception was thrown
+            throw new IOException("Error while connection to SOCKS5 proxy");
+        }
+
+    }
+
+    /**
+     * Initializes the connection to the SOCKS5 proxy by negotiating authentication method and
+     * requesting a stream for the given digest. Currently only the no-authentication method is
+     * supported by the Socks5Client.
+     * <p>
+     * Returns <code>true</code> if a stream could be established, otherwise <code>false</code>. If
+     * <code>false</code> is returned the given Socket should be closed.
+     * 
+     * @param socket connected to a SOCKS5 proxy
+     * @return <code>true</code> if if a stream could be established, otherwise <code>false</code>.
+     *         If <code>false</code> is returned the given Socket should be closed.
+     * @throws IOException if a network error occurred
+     */
+    protected boolean establish(Socket socket) throws IOException {
+
+        /*
+         * use DataInputStream/DataOutpuStream to assure read and write is completed in a single
+         * statement
+         */
+        DataInputStream in = new DataInputStream(socket.getInputStream());
+        DataOutputStream out = new DataOutputStream(socket.getOutputStream());
+
+        // authentication negotiation
+        byte[] cmd = new byte[3];
+
+        cmd[0] = (byte) 0x05; // protocol version 5
+        cmd[1] = (byte) 0x01; // number of authentication methods supported
+        cmd[2] = (byte) 0x00; // authentication method: no-authentication required
+
+        out.write(cmd);
+        out.flush();
+
+        byte[] response = new byte[2];
+        in.readFully(response);
+
+        // check if server responded with correct version and no-authentication method
+        if (response[0] != (byte) 0x05 || response[1] != (byte) 0x00) {
+            return false;
+        }
+
+        // request SOCKS5 connection with given address/digest
+        byte[] connectionRequest = createSocks5ConnectRequest();
+        out.write(connectionRequest);
+        out.flush();
+
+        // receive response
+        byte[] connectionResponse;
+        try {
+            connectionResponse = Socks5Utils.receiveSocks5Message(in);
+        }
+        catch (XMPPException e) {
+            return false; // server answered in an unsupported way
+        }
+
+        // verify response
+        connectionRequest[1] = (byte) 0x00; // set expected return status to 0
+        return Arrays.equals(connectionRequest, connectionResponse);
+    }
+
+    /**
+     * Returns a SOCKS5 connection request message. It contains the command "connect", the address
+     * type "domain" and the digest as address.
+     * <p>
+     * (see <a href="http://tools.ietf.org/html/rfc1928">RFC1928</a>)
+     * 
+     * @return SOCKS5 connection request message
+     */
+    private byte[] createSocks5ConnectRequest() {
+        byte addr[] = this.digest.getBytes();
+
+        byte[] data = new byte[7 + addr.length];
+        data[0] = (byte) 0x05; // version (SOCKS5)
+        data[1] = (byte) 0x01; // command (1 - connect)
+        data[2] = (byte) 0x00; // reserved byte (always 0)
+        data[3] = (byte) 0x03; // address type (3 - domain name)
+        data[4] = (byte) addr.length; // address length
+        System.arraycopy(addr, 0, data, 5, addr.length); // address
+        data[data.length - 2] = (byte) 0; // address port (2 bytes always 0)
+        data[data.length - 1] = (byte) 0;
+
+        return data;
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiator.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiator.java
index 0d90791..94a7ac7 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiator.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiator.java
@@ -1,117 +1,117 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.socks5;
-
-import java.io.IOException;
-import java.net.Socket;
-import java.util.concurrent.TimeoutException;
-
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.util.SyncPacketSend;
-import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
-import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost;
-
-/**
- * Implementation of a SOCKS5 client used on the initiators side. This is needed because connecting
- * to the local SOCKS5 proxy differs form the regular way to connect to a SOCKS5 proxy. Additionally
- * a remote SOCKS5 proxy has to be activated by the initiator before data can be transferred between
- * the peers.
- * 
- * @author Henning Staib
- */
-class Socks5ClientForInitiator extends Socks5Client {
-
-    /* the XMPP connection used to communicate with the SOCKS5 proxy */
-    private Connection connection;
-
-    /* the session ID used to activate SOCKS5 stream */
-    private String sessionID;
-
-    /* the target JID used to activate SOCKS5 stream */
-    private String target;
-
-    /**
-     * Creates a new SOCKS5 client for the initiators side.
-     * 
-     * @param streamHost containing network settings of the SOCKS5 proxy
-     * @param digest identifying the SOCKS5 Bytestream
-     * @param connection the XMPP connection
-     * @param sessionID the session ID of the SOCKS5 Bytestream
-     * @param target the target JID of the SOCKS5 Bytestream
-     */
-    public Socks5ClientForInitiator(StreamHost streamHost, String digest, Connection connection,
-                    String sessionID, String target) {
-        super(streamHost, digest);
-        this.connection = connection;
-        this.sessionID = sessionID;
-        this.target = target;
-    }
-
-    public Socket getSocket(int timeout) throws IOException, XMPPException, InterruptedException,
-                    TimeoutException {
-        Socket socket = null;
-
-        // check if stream host is the local SOCKS5 proxy
-        if (this.streamHost.getJID().equals(this.connection.getUser())) {
-            Socks5Proxy socks5Server = Socks5Proxy.getSocks5Proxy();
-            socket = socks5Server.getSocket(this.digest);
-            if (socket == null) {
-                throw new XMPPException("target is not connected to SOCKS5 proxy");
-            }
-        }
-        else {
-            socket = super.getSocket(timeout);
-
-            try {
-                activate();
-            }
-            catch (XMPPException e) {
-                socket.close();
-                throw new XMPPException("activating SOCKS5 Bytestream failed", e);
-            }
-
-        }
-
-        return socket;
-    }
-
-    /**
-     * Activates the SOCKS5 Bytestream by sending a XMPP SOCKS5 Bytestream activation packet to the
-     * SOCKS5 proxy.
-     */
-    private void activate() throws XMPPException {
-        Bytestream activate = createStreamHostActivation();
-        // if activation fails #getReply throws an exception
-        SyncPacketSend.getReply(this.connection, activate);
-    }
-
-    /**
-     * Returns a SOCKS5 Bytestream activation packet.
-     * 
-     * @return SOCKS5 Bytestream activation packet
-     */
-    private Bytestream createStreamHostActivation() {
-        Bytestream activate = new Bytestream(this.sessionID);
-        activate.setMode(null);
-        activate.setType(IQ.Type.SET);
-        activate.setTo(this.streamHost.getJID());
-
-        activate.setToActivate(this.target);
-
-        return activate;
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.socks5;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.concurrent.TimeoutException;
+
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.util.SyncPacketSend;
+import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
+import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost;
+
+/**
+ * Implementation of a SOCKS5 client used on the initiators side. This is needed because connecting
+ * to the local SOCKS5 proxy differs form the regular way to connect to a SOCKS5 proxy. Additionally
+ * a remote SOCKS5 proxy has to be activated by the initiator before data can be transferred between
+ * the peers.
+ * 
+ * @author Henning Staib
+ */
+class Socks5ClientForInitiator extends Socks5Client {
+
+    /* the XMPP connection used to communicate with the SOCKS5 proxy */
+    private Connection connection;
+
+    /* the session ID used to activate SOCKS5 stream */
+    private String sessionID;
+
+    /* the target JID used to activate SOCKS5 stream */
+    private String target;
+
+    /**
+     * Creates a new SOCKS5 client for the initiators side.
+     * 
+     * @param streamHost containing network settings of the SOCKS5 proxy
+     * @param digest identifying the SOCKS5 Bytestream
+     * @param connection the XMPP connection
+     * @param sessionID the session ID of the SOCKS5 Bytestream
+     * @param target the target JID of the SOCKS5 Bytestream
+     */
+    public Socks5ClientForInitiator(StreamHost streamHost, String digest, Connection connection,
+                    String sessionID, String target) {
+        super(streamHost, digest);
+        this.connection = connection;
+        this.sessionID = sessionID;
+        this.target = target;
+    }
+
+    public Socket getSocket(int timeout) throws IOException, XMPPException, InterruptedException,
+                    TimeoutException {
+        Socket socket = null;
+
+        // check if stream host is the local SOCKS5 proxy
+        if (this.streamHost.getJID().equals(this.connection.getUser())) {
+            Socks5Proxy socks5Server = Socks5Proxy.getSocks5Proxy();
+            socket = socks5Server.getSocket(this.digest);
+            if (socket == null) {
+                throw new XMPPException("target is not connected to SOCKS5 proxy");
+            }
+        }
+        else {
+            socket = super.getSocket(timeout);
+
+            try {
+                activate();
+            }
+            catch (XMPPException e) {
+                socket.close();
+                throw new XMPPException("activating SOCKS5 Bytestream failed", e);
+            }
+
+        }
+
+        return socket;
+    }
+
+    /**
+     * Activates the SOCKS5 Bytestream by sending a XMPP SOCKS5 Bytestream activation packet to the
+     * SOCKS5 proxy.
+     */
+    private void activate() throws XMPPException {
+        Bytestream activate = createStreamHostActivation();
+        // if activation fails #getReply throws an exception
+        SyncPacketSend.getReply(this.connection, activate);
+    }
+
+    /**
+     * Returns a SOCKS5 Bytestream activation packet.
+     * 
+     * @return SOCKS5 Bytestream activation packet
+     */
+    private Bytestream createStreamHostActivation() {
+        Bytestream activate = new Bytestream(this.sessionID);
+        activate.setMode(null);
+        activate.setType(IQ.Type.SET);
+        activate.setTo(this.streamHost.getJID());
+
+        activate.setToActivate(this.target);
+
+        return activate;
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java
index 11ef7a9..d45dd6d 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java
@@ -1,423 +1,423 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.socks5;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.jivesoftware.smack.SmackConfiguration;
-import org.jivesoftware.smack.XMPPException;
-
-/**
- * The Socks5Proxy class represents a local SOCKS5 proxy server. It can be enabled/disabled by
- * setting the <code>localSocks5ProxyEnabled</code> flag in the <code>smack-config.xml</code> or by
- * invoking {@link SmackConfiguration#setLocalSocks5ProxyEnabled(boolean)}. The proxy is enabled by
- * default.
- * <p>
- * The port of the local SOCKS5 proxy can be configured by setting <code>localSocks5ProxyPort</code>
- * in the <code>smack-config.xml</code> or by invoking
- * {@link SmackConfiguration#setLocalSocks5ProxyPort(int)}. Default port is 7777. If you set the
- * port to a negative value Smack tries to the absolute value and all following until it finds an
- * open port.
- * <p>
- * If your application is running on a machine with multiple network interfaces or if you want to
- * provide your public address in case you are behind a NAT router, invoke
- * {@link #addLocalAddress(String)} or {@link #replaceLocalAddresses(List)} to modify the list of
- * local network addresses used for outgoing SOCKS5 Bytestream requests.
- * <p>
- * The local SOCKS5 proxy server refuses all connections except the ones that are explicitly allowed
- * in the process of establishing a SOCKS5 Bytestream (
- * {@link Socks5BytestreamManager#establishSession(String)}).
- * <p>
- * This Implementation has the following limitations:
- * <ul>
- * <li>only supports the no-authentication authentication method</li>
- * <li>only supports the <code>connect</code> command and will not answer correctly to other
- * commands</li>
- * <li>only supports requests with the domain address type and will not correctly answer to requests
- * with other address types</li>
- * </ul>
- * (see <a href="http://tools.ietf.org/html/rfc1928">RFC 1928</a>)
- * 
- * @author Henning Staib
- */
-public class Socks5Proxy {
-
-    /* SOCKS5 proxy singleton */
-    private static Socks5Proxy socks5Server;
-
-    /* reusable implementation of a SOCKS5 proxy server process */
-    private Socks5ServerProcess serverProcess;
-
-    /* thread running the SOCKS5 server process */
-    private Thread serverThread;
-
-    /* server socket to accept SOCKS5 connections */
-    private ServerSocket serverSocket;
-
-    /* assigns a connection to a digest */
-    private final Map<String, Socket> connectionMap = new ConcurrentHashMap<String, Socket>();
-
-    /* list of digests connections should be stored */
-    private final List<String> allowedConnections = Collections.synchronizedList(new LinkedList<String>());
-
-    private final Set<String> localAddresses = Collections.synchronizedSet(new LinkedHashSet<String>());
-
-    /**
-     * Private constructor.
-     */
-    private Socks5Proxy() {
-        this.serverProcess = new Socks5ServerProcess();
-
-        // add default local address
-        try {
-            this.localAddresses.add(InetAddress.getLocalHost().getHostAddress());
-        }
-        catch (UnknownHostException e) {
-            // do nothing
-        }
-
-    }
-
-    /**
-     * Returns the local SOCKS5 proxy server.
-     * 
-     * @return the local SOCKS5 proxy server
-     */
-    public static synchronized Socks5Proxy getSocks5Proxy() {
-        if (socks5Server == null) {
-            socks5Server = new Socks5Proxy();
-        }
-        if (SmackConfiguration.isLocalSocks5ProxyEnabled()) {
-            socks5Server.start();
-        }
-        return socks5Server;
-    }
-
-    /**
-     * Starts the local SOCKS5 proxy server. If it is already running, this method does nothing.
-     */
-    public synchronized void start() {
-        if (isRunning()) {
-            return;
-        }
-        try {
-            if (SmackConfiguration.getLocalSocks5ProxyPort() < 0) {
-                int port = Math.abs(SmackConfiguration.getLocalSocks5ProxyPort());
-                for (int i = 0; i < 65535 - port; i++) {
-                    try {
-                        this.serverSocket = new ServerSocket(port + i);
-                        break;
-                    }
-                    catch (IOException e) {
-                        // port is used, try next one
-                    }
-                }
-            }
-            else {
-                this.serverSocket = new ServerSocket(SmackConfiguration.getLocalSocks5ProxyPort());
-            }
-
-            if (this.serverSocket != null) {
-                this.serverThread = new Thread(this.serverProcess);
-                this.serverThread.start();
-            }
-        }
-        catch (IOException e) {
-            // couldn't setup server
-            System.err.println("couldn't setup local SOCKS5 proxy on port "
-                            + SmackConfiguration.getLocalSocks5ProxyPort() + ": " + e.getMessage());
-        }
-    }
-
-    /**
-     * Stops the local SOCKS5 proxy server. If it is not running this method does nothing.
-     */
-    public synchronized void stop() {
-        if (!isRunning()) {
-            return;
-        }
-
-        try {
-            this.serverSocket.close();
-        }
-        catch (IOException e) {
-            // do nothing
-        }
-
-        if (this.serverThread != null && this.serverThread.isAlive()) {
-            try {
-                this.serverThread.interrupt();
-                this.serverThread.join();
-            }
-            catch (InterruptedException e) {
-                // do nothing
-            }
-        }
-        this.serverThread = null;
-        this.serverSocket = null;
-
-    }
-
-    /**
-     * Adds the given address to the list of local network addresses.
-     * <p>
-     * Use this method if you want to provide multiple addresses in a SOCKS5 Bytestream request.
-     * This may be necessary if your application is running on a machine with multiple network
-     * interfaces or if you want to provide your public address in case you are behind a NAT router.
-     * <p>
-     * The order of the addresses used is determined by the order you add addresses.
-     * <p>
-     * Note that the list of addresses initially contains the address returned by
-     * <code>InetAddress.getLocalHost().getHostAddress()</code>. You can replace the list of
-     * addresses by invoking {@link #replaceLocalAddresses(List)}.
-     * 
-     * @param address the local network address to add
-     */
-    public void addLocalAddress(String address) {
-        if (address == null) {
-            throw new IllegalArgumentException("address may not be null");
-        }
-        this.localAddresses.add(address);
-    }
-
-    /**
-     * Removes the given address from the list of local network addresses. This address will then no
-     * longer be used of outgoing SOCKS5 Bytestream requests.
-     * 
-     * @param address the local network address to remove
-     */
-    public void removeLocalAddress(String address) {
-        this.localAddresses.remove(address);
-    }
-
-    /**
-     * Returns an unmodifiable list of the local network addresses that will be used for streamhost
-     * candidates of outgoing SOCKS5 Bytestream requests.
-     * 
-     * @return unmodifiable list of the local network addresses
-     */
-    public List<String> getLocalAddresses() {
-        return Collections.unmodifiableList(new ArrayList<String>(this.localAddresses));
-    }
-
-    /**
-     * Replaces the list of local network addresses.
-     * <p>
-     * Use this method if you want to provide multiple addresses in a SOCKS5 Bytestream request and
-     * want to define their order. This may be necessary if your application is running on a machine
-     * with multiple network interfaces or if you want to provide your public address in case you
-     * are behind a NAT router.
-     * 
-     * @param addresses the new list of local network addresses
-     */
-    public void replaceLocalAddresses(List<String> addresses) {
-        if (addresses == null) {
-            throw new IllegalArgumentException("list must not be null");
-        }
-        this.localAddresses.clear();
-        this.localAddresses.addAll(addresses);
-
-    }
-
-    /**
-     * Returns the port of the local SOCKS5 proxy server. If it is not running -1 will be returned.
-     * 
-     * @return the port of the local SOCKS5 proxy server or -1 if proxy is not running
-     */
-    public int getPort() {
-        if (!isRunning()) {
-            return -1;
-        }
-        return this.serverSocket.getLocalPort();
-    }
-
-    /**
-     * Returns the socket for the given digest. A socket will be returned if the given digest has
-     * been in the list of allowed transfers (see {@link #addTransfer(String)}) while the peer
-     * connected to the SOCKS5 proxy.
-     * 
-     * @param digest identifying the connection
-     * @return socket or null if there is no socket for the given digest
-     */
-    protected Socket getSocket(String digest) {
-        return this.connectionMap.get(digest);
-    }
-
-    /**
-     * Add the given digest to the list of allowed transfers. Only connections for allowed transfers
-     * are stored and can be retrieved by invoking {@link #getSocket(String)}. All connections to
-     * the local SOCKS5 proxy that don't contain an allowed digest are discarded.
-     * 
-     * @param digest to be added to the list of allowed transfers
-     */
-    protected void addTransfer(String digest) {
-        this.allowedConnections.add(digest);
-    }
-
-    /**
-     * Removes the given digest from the list of allowed transfers. After invoking this method
-     * already stored connections with the given digest will be removed.
-     * <p>
-     * The digest should be removed after establishing the SOCKS5 Bytestream is finished, an error
-     * occurred while establishing the connection or if the connection is not allowed anymore.
-     * 
-     * @param digest to be removed from the list of allowed transfers
-     */
-    protected void removeTransfer(String digest) {
-        this.allowedConnections.remove(digest);
-        this.connectionMap.remove(digest);
-    }
-
-    /**
-     * Returns <code>true</code> if the local SOCKS5 proxy server is running, otherwise
-     * <code>false</code>.
-     * 
-     * @return <code>true</code> if the local SOCKS5 proxy server is running, otherwise
-     *         <code>false</code>
-     */
-    public boolean isRunning() {
-        return this.serverSocket != null;
-    }
-
-    /**
-     * Implementation of a simplified SOCKS5 proxy server.
-     */
-    private class Socks5ServerProcess implements Runnable {
-
-        public void run() {
-            while (true) {
-                Socket socket = null;
-
-                try {
-
-                    if (Socks5Proxy.this.serverSocket.isClosed()
-                                    || Thread.currentThread().isInterrupted()) {
-                        return;
-                    }
-
-                    // accept connection
-                    socket = Socks5Proxy.this.serverSocket.accept();
-
-                    // initialize connection
-                    establishConnection(socket);
-
-                }
-                catch (SocketException e) {
-                    /*
-                     * do nothing, if caused by closing the server socket, thread will terminate in
-                     * next loop
-                     */
-                }
-                catch (Exception e) {
-                    try {
-                        if (socket != null) {
-                            socket.close();
-                        }
-                    }
-                    catch (IOException e1) {
-                        /* do nothing */
-                    }
-                }
-            }
-
-        }
-
-        /**
-         * Negotiates a SOCKS5 connection and stores it on success.
-         * 
-         * @param socket connection to the client
-         * @throws XMPPException if client requests a connection in an unsupported way
-         * @throws IOException if a network error occurred
-         */
-        private void establishConnection(Socket socket) throws XMPPException, IOException {
-            DataOutputStream out = new DataOutputStream(socket.getOutputStream());
-            DataInputStream in = new DataInputStream(socket.getInputStream());
-
-            // first byte is version should be 5
-            int b = in.read();
-            if (b != 5) {
-                throw new XMPPException("Only SOCKS5 supported");
-            }
-
-            // second byte number of authentication methods supported
-            b = in.read();
-
-            // read list of supported authentication methods
-            byte[] auth = new byte[b];
-            in.readFully(auth);
-
-            byte[] authMethodSelectionResponse = new byte[2];
-            authMethodSelectionResponse[0] = (byte) 0x05; // protocol version
-
-            // only authentication method 0, no authentication, supported
-            boolean noAuthMethodFound = false;
-            for (int i = 0; i < auth.length; i++) {
-                if (auth[i] == (byte) 0x00) {
-                    noAuthMethodFound = true;
-                    break;
-                }
-            }
-
-            if (!noAuthMethodFound) {
-                authMethodSelectionResponse[1] = (byte) 0xFF; // no acceptable methods
-                out.write(authMethodSelectionResponse);
-                out.flush();
-                throw new XMPPException("Authentication method not supported");
-            }
-
-            authMethodSelectionResponse[1] = (byte) 0x00; // no-authentication method
-            out.write(authMethodSelectionResponse);
-            out.flush();
-
-            // receive connection request
-            byte[] connectionRequest = Socks5Utils.receiveSocks5Message(in);
-
-            // extract digest
-            String responseDigest = new String(connectionRequest, 5, connectionRequest[4]);
-
-            // return error if digest is not allowed
-            if (!Socks5Proxy.this.allowedConnections.contains(responseDigest)) {
-                connectionRequest[1] = (byte) 0x05; // set return status to 5 (connection refused)
-                out.write(connectionRequest);
-                out.flush();
-
-                throw new XMPPException("Connection is not allowed");
-            }
-
-            connectionRequest[1] = (byte) 0x00; // set return status to 0 (success)
-            out.write(connectionRequest);
-            out.flush();
-
-            // store connection
-            Socks5Proxy.this.connectionMap.put(responseDigest, socket);
-        }
-
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.socks5;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.jivesoftware.smack.SmackConfiguration;
+import org.jivesoftware.smack.XMPPException;
+
+/**
+ * The Socks5Proxy class represents a local SOCKS5 proxy server. It can be enabled/disabled by
+ * setting the <code>localSocks5ProxyEnabled</code> flag in the <code>smack-config.xml</code> or by
+ * invoking {@link SmackConfiguration#setLocalSocks5ProxyEnabled(boolean)}. The proxy is enabled by
+ * default.
+ * <p>
+ * The port of the local SOCKS5 proxy can be configured by setting <code>localSocks5ProxyPort</code>
+ * in the <code>smack-config.xml</code> or by invoking
+ * {@link SmackConfiguration#setLocalSocks5ProxyPort(int)}. Default port is 7777. If you set the
+ * port to a negative value Smack tries to the absolute value and all following until it finds an
+ * open port.
+ * <p>
+ * If your application is running on a machine with multiple network interfaces or if you want to
+ * provide your public address in case you are behind a NAT router, invoke
+ * {@link #addLocalAddress(String)} or {@link #replaceLocalAddresses(List)} to modify the list of
+ * local network addresses used for outgoing SOCKS5 Bytestream requests.
+ * <p>
+ * The local SOCKS5 proxy server refuses all connections except the ones that are explicitly allowed
+ * in the process of establishing a SOCKS5 Bytestream (
+ * {@link Socks5BytestreamManager#establishSession(String)}).
+ * <p>
+ * This Implementation has the following limitations:
+ * <ul>
+ * <li>only supports the no-authentication authentication method</li>
+ * <li>only supports the <code>connect</code> command and will not answer correctly to other
+ * commands</li>
+ * <li>only supports requests with the domain address type and will not correctly answer to requests
+ * with other address types</li>
+ * </ul>
+ * (see <a href="http://tools.ietf.org/html/rfc1928">RFC 1928</a>)
+ * 
+ * @author Henning Staib
+ */
+public class Socks5Proxy {
+
+    /* SOCKS5 proxy singleton */
+    private static Socks5Proxy socks5Server;
+
+    /* reusable implementation of a SOCKS5 proxy server process */
+    private Socks5ServerProcess serverProcess;
+
+    /* thread running the SOCKS5 server process */
+    private Thread serverThread;
+
+    /* server socket to accept SOCKS5 connections */
+    private ServerSocket serverSocket;
+
+    /* assigns a connection to a digest */
+    private final Map<String, Socket> connectionMap = new ConcurrentHashMap<String, Socket>();
+
+    /* list of digests connections should be stored */
+    private final List<String> allowedConnections = Collections.synchronizedList(new LinkedList<String>());
+
+    private final Set<String> localAddresses = Collections.synchronizedSet(new LinkedHashSet<String>());
+
+    /**
+     * Private constructor.
+     */
+    private Socks5Proxy() {
+        this.serverProcess = new Socks5ServerProcess();
+
+        // add default local address
+        try {
+            this.localAddresses.add(InetAddress.getLocalHost().getHostAddress());
+        }
+        catch (UnknownHostException e) {
+            // do nothing
+        }
+
+    }
+
+    /**
+     * Returns the local SOCKS5 proxy server.
+     * 
+     * @return the local SOCKS5 proxy server
+     */
+    public static synchronized Socks5Proxy getSocks5Proxy() {
+        if (socks5Server == null) {
+            socks5Server = new Socks5Proxy();
+        }
+        if (SmackConfiguration.isLocalSocks5ProxyEnabled()) {
+            socks5Server.start();
+        }
+        return socks5Server;
+    }
+
+    /**
+     * Starts the local SOCKS5 proxy server. If it is already running, this method does nothing.
+     */
+    public synchronized void start() {
+        if (isRunning()) {
+            return;
+        }
+        try {
+            if (SmackConfiguration.getLocalSocks5ProxyPort() < 0) {
+                int port = Math.abs(SmackConfiguration.getLocalSocks5ProxyPort());
+                for (int i = 0; i < 65535 - port; i++) {
+                    try {
+                        this.serverSocket = new ServerSocket(port + i);
+                        break;
+                    }
+                    catch (IOException e) {
+                        // port is used, try next one
+                    }
+                }
+            }
+            else {
+                this.serverSocket = new ServerSocket(SmackConfiguration.getLocalSocks5ProxyPort());
+            }
+
+            if (this.serverSocket != null) {
+                this.serverThread = new Thread(this.serverProcess);
+                this.serverThread.start();
+            }
+        }
+        catch (IOException e) {
+            // couldn't setup server
+            System.err.println("couldn't setup local SOCKS5 proxy on port "
+                            + SmackConfiguration.getLocalSocks5ProxyPort() + ": " + e.getMessage());
+        }
+    }
+
+    /**
+     * Stops the local SOCKS5 proxy server. If it is not running this method does nothing.
+     */
+    public synchronized void stop() {
+        if (!isRunning()) {
+            return;
+        }
+
+        try {
+            this.serverSocket.close();
+        }
+        catch (IOException e) {
+            // do nothing
+        }
+
+        if (this.serverThread != null && this.serverThread.isAlive()) {
+            try {
+                this.serverThread.interrupt();
+                this.serverThread.join();
+            }
+            catch (InterruptedException e) {
+                // do nothing
+            }
+        }
+        this.serverThread = null;
+        this.serverSocket = null;
+
+    }
+
+    /**
+     * Adds the given address to the list of local network addresses.
+     * <p>
+     * Use this method if you want to provide multiple addresses in a SOCKS5 Bytestream request.
+     * This may be necessary if your application is running on a machine with multiple network
+     * interfaces or if you want to provide your public address in case you are behind a NAT router.
+     * <p>
+     * The order of the addresses used is determined by the order you add addresses.
+     * <p>
+     * Note that the list of addresses initially contains the address returned by
+     * <code>InetAddress.getLocalHost().getHostAddress()</code>. You can replace the list of
+     * addresses by invoking {@link #replaceLocalAddresses(List)}.
+     * 
+     * @param address the local network address to add
+     */
+    public void addLocalAddress(String address) {
+        if (address == null) {
+            throw new IllegalArgumentException("address may not be null");
+        }
+        this.localAddresses.add(address);
+    }
+
+    /**
+     * Removes the given address from the list of local network addresses. This address will then no
+     * longer be used of outgoing SOCKS5 Bytestream requests.
+     * 
+     * @param address the local network address to remove
+     */
+    public void removeLocalAddress(String address) {
+        this.localAddresses.remove(address);
+    }
+
+    /**
+     * Returns an unmodifiable list of the local network addresses that will be used for streamhost
+     * candidates of outgoing SOCKS5 Bytestream requests.
+     * 
+     * @return unmodifiable list of the local network addresses
+     */
+    public List<String> getLocalAddresses() {
+        return Collections.unmodifiableList(new ArrayList<String>(this.localAddresses));
+    }
+
+    /**
+     * Replaces the list of local network addresses.
+     * <p>
+     * Use this method if you want to provide multiple addresses in a SOCKS5 Bytestream request and
+     * want to define their order. This may be necessary if your application is running on a machine
+     * with multiple network interfaces or if you want to provide your public address in case you
+     * are behind a NAT router.
+     * 
+     * @param addresses the new list of local network addresses
+     */
+    public void replaceLocalAddresses(List<String> addresses) {
+        if (addresses == null) {
+            throw new IllegalArgumentException("list must not be null");
+        }
+        this.localAddresses.clear();
+        this.localAddresses.addAll(addresses);
+
+    }
+
+    /**
+     * Returns the port of the local SOCKS5 proxy server. If it is not running -1 will be returned.
+     * 
+     * @return the port of the local SOCKS5 proxy server or -1 if proxy is not running
+     */
+    public int getPort() {
+        if (!isRunning()) {
+            return -1;
+        }
+        return this.serverSocket.getLocalPort();
+    }
+
+    /**
+     * Returns the socket for the given digest. A socket will be returned if the given digest has
+     * been in the list of allowed transfers (see {@link #addTransfer(String)}) while the peer
+     * connected to the SOCKS5 proxy.
+     * 
+     * @param digest identifying the connection
+     * @return socket or null if there is no socket for the given digest
+     */
+    protected Socket getSocket(String digest) {
+        return this.connectionMap.get(digest);
+    }
+
+    /**
+     * Add the given digest to the list of allowed transfers. Only connections for allowed transfers
+     * are stored and can be retrieved by invoking {@link #getSocket(String)}. All connections to
+     * the local SOCKS5 proxy that don't contain an allowed digest are discarded.
+     * 
+     * @param digest to be added to the list of allowed transfers
+     */
+    protected void addTransfer(String digest) {
+        this.allowedConnections.add(digest);
+    }
+
+    /**
+     * Removes the given digest from the list of allowed transfers. After invoking this method
+     * already stored connections with the given digest will be removed.
+     * <p>
+     * The digest should be removed after establishing the SOCKS5 Bytestream is finished, an error
+     * occurred while establishing the connection or if the connection is not allowed anymore.
+     * 
+     * @param digest to be removed from the list of allowed transfers
+     */
+    protected void removeTransfer(String digest) {
+        this.allowedConnections.remove(digest);
+        this.connectionMap.remove(digest);
+    }
+
+    /**
+     * Returns <code>true</code> if the local SOCKS5 proxy server is running, otherwise
+     * <code>false</code>.
+     * 
+     * @return <code>true</code> if the local SOCKS5 proxy server is running, otherwise
+     *         <code>false</code>
+     */
+    public boolean isRunning() {
+        return this.serverSocket != null;
+    }
+
+    /**
+     * Implementation of a simplified SOCKS5 proxy server.
+     */
+    private class Socks5ServerProcess implements Runnable {
+
+        public void run() {
+            while (true) {
+                Socket socket = null;
+
+                try {
+
+                    if (Socks5Proxy.this.serverSocket.isClosed()
+                                    || Thread.currentThread().isInterrupted()) {
+                        return;
+                    }
+
+                    // accept connection
+                    socket = Socks5Proxy.this.serverSocket.accept();
+
+                    // initialize connection
+                    establishConnection(socket);
+
+                }
+                catch (SocketException e) {
+                    /*
+                     * do nothing, if caused by closing the server socket, thread will terminate in
+                     * next loop
+                     */
+                }
+                catch (Exception e) {
+                    try {
+                        if (socket != null) {
+                            socket.close();
+                        }
+                    }
+                    catch (IOException e1) {
+                        /* do nothing */
+                    }
+                }
+            }
+
+        }
+
+        /**
+         * Negotiates a SOCKS5 connection and stores it on success.
+         * 
+         * @param socket connection to the client
+         * @throws XMPPException if client requests a connection in an unsupported way
+         * @throws IOException if a network error occurred
+         */
+        private void establishConnection(Socket socket) throws XMPPException, IOException {
+            DataOutputStream out = new DataOutputStream(socket.getOutputStream());
+            DataInputStream in = new DataInputStream(socket.getInputStream());
+
+            // first byte is version should be 5
+            int b = in.read();
+            if (b != 5) {
+                throw new XMPPException("Only SOCKS5 supported");
+            }
+
+            // second byte number of authentication methods supported
+            b = in.read();
+
+            // read list of supported authentication methods
+            byte[] auth = new byte[b];
+            in.readFully(auth);
+
+            byte[] authMethodSelectionResponse = new byte[2];
+            authMethodSelectionResponse[0] = (byte) 0x05; // protocol version
+
+            // only authentication method 0, no authentication, supported
+            boolean noAuthMethodFound = false;
+            for (int i = 0; i < auth.length; i++) {
+                if (auth[i] == (byte) 0x00) {
+                    noAuthMethodFound = true;
+                    break;
+                }
+            }
+
+            if (!noAuthMethodFound) {
+                authMethodSelectionResponse[1] = (byte) 0xFF; // no acceptable methods
+                out.write(authMethodSelectionResponse);
+                out.flush();
+                throw new XMPPException("Authentication method not supported");
+            }
+
+            authMethodSelectionResponse[1] = (byte) 0x00; // no-authentication method
+            out.write(authMethodSelectionResponse);
+            out.flush();
+
+            // receive connection request
+            byte[] connectionRequest = Socks5Utils.receiveSocks5Message(in);
+
+            // extract digest
+            String responseDigest = new String(connectionRequest, 5, connectionRequest[4]);
+
+            // return error if digest is not allowed
+            if (!Socks5Proxy.this.allowedConnections.contains(responseDigest)) {
+                connectionRequest[1] = (byte) 0x05; // set return status to 5 (connection refused)
+                out.write(connectionRequest);
+                out.flush();
+
+                throw new XMPPException("Connection is not allowed");
+            }
+
+            connectionRequest[1] = (byte) 0x00; // set return status to 0 (success)
+            out.write(connectionRequest);
+            out.flush();
+
+            // store connection
+            Socks5Proxy.this.connectionMap.put(responseDigest, socket);
+        }
+
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5Utils.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5Utils.java
index 9c92563..73402a5 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5Utils.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/Socks5Utils.java
@@ -1,73 +1,73 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.socks5;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.util.StringUtils;
-
-/**
- * A collection of utility methods for SOcKS5 messages.
- * 
- * @author Henning Staib
- */
-class Socks5Utils {
-
-    /**
-     * Returns a SHA-1 digest of the given parameters as specified in <a
-     * href="http://xmpp.org/extensions/xep-0065.html#impl-socks5">XEP-0065</a>.
-     * 
-     * @param sessionID for the SOCKS5 Bytestream
-     * @param initiatorJID JID of the initiator of a SOCKS5 Bytestream
-     * @param targetJID JID of the target of a SOCKS5 Bytestream
-     * @return SHA-1 digest of the given parameters
-     */
-    public static String createDigest(String sessionID, String initiatorJID, String targetJID) {
-        StringBuilder b = new StringBuilder();
-        b.append(sessionID).append(initiatorJID).append(targetJID);
-        return StringUtils.hash(b.toString());
-    }
-
-    /**
-     * Reads a SOCKS5 message from the given InputStream. The message can either be a SOCKS5 request
-     * message or a SOCKS5 response message.
-     * <p>
-     * (see <a href="http://tools.ietf.org/html/rfc1928">RFC1928</a>)
-     * 
-     * @param in the DataInputStream to read the message from
-     * @return the SOCKS5 message
-     * @throws IOException if a network error occurred
-     * @throws XMPPException if the SOCKS5 message contains an unsupported address type
-     */
-    public static byte[] receiveSocks5Message(DataInputStream in) throws IOException, XMPPException {
-        byte[] header = new byte[5];
-        in.readFully(header, 0, 5);
-
-        if (header[3] != (byte) 0x03) {
-            throw new XMPPException("Unsupported SOCKS5 address type");
-        }
-
-        int addressLength = header[4];
-
-        byte[] response = new byte[7 + addressLength];
-        System.arraycopy(header, 0, response, 0, header.length);
-
-        in.readFully(response, header.length, addressLength + 2);
-
-        return response;
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.socks5;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.util.StringUtils;
+
+/**
+ * A collection of utility methods for SOcKS5 messages.
+ * 
+ * @author Henning Staib
+ */
+class Socks5Utils {
+
+    /**
+     * Returns a SHA-1 digest of the given parameters as specified in <a
+     * href="http://xmpp.org/extensions/xep-0065.html#impl-socks5">XEP-0065</a>.
+     * 
+     * @param sessionID for the SOCKS5 Bytestream
+     * @param initiatorJID JID of the initiator of a SOCKS5 Bytestream
+     * @param targetJID JID of the target of a SOCKS5 Bytestream
+     * @return SHA-1 digest of the given parameters
+     */
+    public static String createDigest(String sessionID, String initiatorJID, String targetJID) {
+        StringBuilder b = new StringBuilder();
+        b.append(sessionID).append(initiatorJID).append(targetJID);
+        return StringUtils.hash(b.toString());
+    }
+
+    /**
+     * Reads a SOCKS5 message from the given InputStream. The message can either be a SOCKS5 request
+     * message or a SOCKS5 response message.
+     * <p>
+     * (see <a href="http://tools.ietf.org/html/rfc1928">RFC1928</a>)
+     * 
+     * @param in the DataInputStream to read the message from
+     * @return the SOCKS5 message
+     * @throws IOException if a network error occurred
+     * @throws XMPPException if the SOCKS5 message contains an unsupported address type
+     */
+    public static byte[] receiveSocks5Message(DataInputStream in) throws IOException, XMPPException {
+        byte[] header = new byte[5];
+        in.readFully(header, 0, 5);
+
+        if (header[3] != (byte) 0x03) {
+            throw new XMPPException("Unsupported SOCKS5 address type");
+        }
+
+        int addressLength = header[4];
+
+        byte[] response = new byte[7 + addressLength];
+        System.arraycopy(header, 0, response, 0, header.length);
+
+        in.readFully(response, header.length, addressLength + 2);
+
+        return response;
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/packet/Bytestream.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/packet/Bytestream.java
index 9e07fc3..303d5b8 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/packet/Bytestream.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/packet/Bytestream.java
@@ -1,474 +1,474 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.socks5.packet;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.PacketExtension;
-
-/**
- * A packet representing part of a SOCKS5 Bytestream negotiation.
- * 
- * @author Alexander Wenckus
- */
-public class Bytestream extends IQ {
-
-    private String sessionID;
-
-    private Mode mode = Mode.tcp;
-
-    private final List<StreamHost> streamHosts = new ArrayList<StreamHost>();
-
-    private StreamHostUsed usedHost;
-
-    private Activate toActivate;
-
-    /**
-     * The default constructor
-     */
-    public Bytestream() {
-        super();
-    }
-
-    /**
-     * A constructor where the session ID can be specified.
-     * 
-     * @param SID The session ID related to the negotiation.
-     * @see #setSessionID(String)
-     */
-    public Bytestream(final String SID) {
-        super();
-        setSessionID(SID);
-    }
-
-    /**
-     * Set the session ID related to the bytestream. The session ID is a unique identifier used to
-     * differentiate between stream negotiations.
-     * 
-     * @param sessionID the unique session ID that identifies the transfer.
-     */
-    public void setSessionID(final String sessionID) {
-        this.sessionID = sessionID;
-    }
-
-    /**
-     * Returns the session ID related to the bytestream negotiation.
-     * 
-     * @return Returns the session ID related to the bytestream negotiation.
-     * @see #setSessionID(String)
-     */
-    public String getSessionID() {
-        return sessionID;
-    }
-
-    /**
-     * Set the transport mode. This should be put in the initiation of the interaction.
-     * 
-     * @param mode the transport mode, either UDP or TCP
-     * @see Mode
-     */
-    public void setMode(final Mode mode) {
-        this.mode = mode;
-    }
-
-    /**
-     * Returns the transport mode.
-     * 
-     * @return Returns the transport mode.
-     * @see #setMode(Mode)
-     */
-    public Mode getMode() {
-        return mode;
-    }
-
-    /**
-     * Adds a potential stream host that the remote user can connect to to receive the file.
-     * 
-     * @param JID The JID of the stream host.
-     * @param address The internet address of the stream host.
-     * @return The added stream host.
-     */
-    public StreamHost addStreamHost(final String JID, final String address) {
-        return addStreamHost(JID, address, 0);
-    }
-
-    /**
-     * Adds a potential stream host that the remote user can connect to to receive the file.
-     * 
-     * @param JID The JID of the stream host.
-     * @param address The internet address of the stream host.
-     * @param port The port on which the remote host is seeking connections.
-     * @return The added stream host.
-     */
-    public StreamHost addStreamHost(final String JID, final String address, final int port) {
-        StreamHost host = new StreamHost(JID, address);
-        host.setPort(port);
-        addStreamHost(host);
-
-        return host;
-    }
-
-    /**
-     * Adds a potential stream host that the remote user can transfer the file through.
-     * 
-     * @param host The potential stream host.
-     */
-    public void addStreamHost(final StreamHost host) {
-        streamHosts.add(host);
-    }
-
-    /**
-     * Returns the list of stream hosts contained in the packet.
-     * 
-     * @return Returns the list of stream hosts contained in the packet.
-     */
-    public Collection<StreamHost> getStreamHosts() {
-        return Collections.unmodifiableCollection(streamHosts);
-    }
-
-    /**
-     * Returns the stream host related to the given JID, or null if there is none.
-     * 
-     * @param JID The JID of the desired stream host.
-     * @return Returns the stream host related to the given JID, or null if there is none.
-     */
-    public StreamHost getStreamHost(final String JID) {
-        if (JID == null) {
-            return null;
-        }
-        for (StreamHost host : streamHosts) {
-            if (host.getJID().equals(JID)) {
-                return host;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the count of stream hosts contained in this packet.
-     * 
-     * @return Returns the count of stream hosts contained in this packet.
-     */
-    public int countStreamHosts() {
-        return streamHosts.size();
-    }
-
-    /**
-     * Upon connecting to the stream host the target of the stream replies to the initiator with the
-     * JID of the SOCKS5 host that they used.
-     * 
-     * @param JID The JID of the used host.
-     */
-    public void setUsedHost(final String JID) {
-        this.usedHost = new StreamHostUsed(JID);
-    }
-
-    /**
-     * Returns the SOCKS5 host connected to by the remote user.
-     * 
-     * @return Returns the SOCKS5 host connected to by the remote user.
-     */
-    public StreamHostUsed getUsedHost() {
-        return usedHost;
-    }
-
-    /**
-     * Returns the activate element of the packet sent to the proxy host to verify the identity of
-     * the initiator and match them to the appropriate stream.
-     * 
-     * @return Returns the activate element of the packet sent to the proxy host to verify the
-     *         identity of the initiator and match them to the appropriate stream.
-     */
-    public Activate getToActivate() {
-        return toActivate;
-    }
-
-    /**
-     * Upon the response from the target of the used host the activate packet is sent to the SOCKS5
-     * proxy. The proxy will activate the stream or return an error after verifying the identity of
-     * the initiator, using the activate packet.
-     * 
-     * @param targetID The JID of the target of the file transfer.
-     */
-    public void setToActivate(final String targetID) {
-        this.toActivate = new Activate(targetID);
-    }
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<query xmlns=\"http://jabber.org/protocol/bytestreams\"");
-        if (this.getType().equals(IQ.Type.SET)) {
-            if (getSessionID() != null) {
-                buf.append(" sid=\"").append(getSessionID()).append("\"");
-            }
-            if (getMode() != null) {
-                buf.append(" mode = \"").append(getMode()).append("\"");
-            }
-            buf.append(">");
-            if (getToActivate() == null) {
-                for (StreamHost streamHost : getStreamHosts()) {
-                    buf.append(streamHost.toXML());
-                }
-            }
-            else {
-                buf.append(getToActivate().toXML());
-            }
-        }
-        else if (this.getType().equals(IQ.Type.RESULT)) {
-            buf.append(">");
-            if (getUsedHost() != null) {
-                buf.append(getUsedHost().toXML());
-            }
-            // A result from the server can also contain stream hosts
-            else if (countStreamHosts() > 0) {
-                for (StreamHost host : streamHosts) {
-                    buf.append(host.toXML());
-                }
-            }
-        }
-        else if (this.getType().equals(IQ.Type.GET)) {
-            return buf.append("/>").toString();
-        }
-        else {
-            return null;
-        }
-        buf.append("</query>");
-
-        return buf.toString();
-    }
-
-    /**
-     * Packet extension that represents a potential SOCKS5 proxy for the file transfer. Stream hosts
-     * are forwarded to the target of the file transfer who then chooses and connects to one.
-     * 
-     * @author Alexander Wenckus
-     */
-    public static class StreamHost implements PacketExtension {
-
-        public static String NAMESPACE = "";
-
-        public static String ELEMENTNAME = "streamhost";
-
-        private final String JID;
-
-        private final String addy;
-
-        private int port = 0;
-
-        /**
-         * Default constructor.
-         * 
-         * @param JID The JID of the stream host.
-         * @param address The internet address of the stream host.
-         */
-        public StreamHost(final String JID, final String address) {
-            this.JID = JID;
-            this.addy = address;
-        }
-
-        /**
-         * Returns the JID of the stream host.
-         * 
-         * @return Returns the JID of the stream host.
-         */
-        public String getJID() {
-            return JID;
-        }
-
-        /**
-         * Returns the internet address of the stream host.
-         * 
-         * @return Returns the internet address of the stream host.
-         */
-        public String getAddress() {
-            return addy;
-        }
-
-        /**
-         * Sets the port of the stream host.
-         * 
-         * @param port The port on which the potential stream host would accept the connection.
-         */
-        public void setPort(final int port) {
-            this.port = port;
-        }
-
-        /**
-         * Returns the port on which the potential stream host would accept the connection.
-         * 
-         * @return Returns the port on which the potential stream host would accept the connection.
-         */
-        public int getPort() {
-            return port;
-        }
-
-        public String getNamespace() {
-            return NAMESPACE;
-        }
-
-        public String getElementName() {
-            return ELEMENTNAME;
-        }
-
-        public String toXML() {
-            StringBuilder buf = new StringBuilder();
-
-            buf.append("<").append(getElementName()).append(" ");
-            buf.append("jid=\"").append(getJID()).append("\" ");
-            buf.append("host=\"").append(getAddress()).append("\" ");
-            if (getPort() != 0) {
-                buf.append("port=\"").append(getPort()).append("\"");
-            }
-            else {
-                buf.append("zeroconf=\"_jabber.bytestreams\"");
-            }
-            buf.append("/>");
-
-            return buf.toString();
-        }
-    }
-
-    /**
-     * After selected a SOCKS5 stream host and successfully connecting, the target of the file
-     * transfer returns a byte stream packet with the stream host used extension.
-     * 
-     * @author Alexander Wenckus
-     */
-    public static class StreamHostUsed implements PacketExtension {
-
-        public String NAMESPACE = "";
-
-        public static String ELEMENTNAME = "streamhost-used";
-
-        private final String JID;
-
-        /**
-         * Default constructor.
-         * 
-         * @param JID The JID of the selected stream host.
-         */
-        public StreamHostUsed(final String JID) {
-            this.JID = JID;
-        }
-
-        /**
-         * Returns the JID of the selected stream host.
-         * 
-         * @return Returns the JID of the selected stream host.
-         */
-        public String getJID() {
-            return JID;
-        }
-
-        public String getNamespace() {
-            return NAMESPACE;
-        }
-
-        public String getElementName() {
-            return ELEMENTNAME;
-        }
-
-        public String toXML() {
-            StringBuilder buf = new StringBuilder();
-            buf.append("<").append(getElementName()).append(" ");
-            buf.append("jid=\"").append(getJID()).append("\" ");
-            buf.append("/>");
-            return buf.toString();
-        }
-    }
-
-    /**
-     * The packet sent by the stream initiator to the stream proxy to activate the connection.
-     * 
-     * @author Alexander Wenckus
-     */
-    public static class Activate implements PacketExtension {
-
-        public String NAMESPACE = "";
-
-        public static String ELEMENTNAME = "activate";
-
-        private final String target;
-
-        /**
-         * Default constructor specifying the target of the stream.
-         * 
-         * @param target The target of the stream.
-         */
-        public Activate(final String target) {
-            this.target = target;
-        }
-
-        /**
-         * Returns the target of the activation.
-         * 
-         * @return Returns the target of the activation.
-         */
-        public String getTarget() {
-            return target;
-        }
-
-        public String getNamespace() {
-            return NAMESPACE;
-        }
-
-        public String getElementName() {
-            return ELEMENTNAME;
-        }
-
-        public String toXML() {
-            StringBuilder buf = new StringBuilder();
-            buf.append("<").append(getElementName()).append(">");
-            buf.append(getTarget());
-            buf.append("</").append(getElementName()).append(">");
-            return buf.toString();
-        }
-    }
-
-    /**
-     * The stream can be either a TCP stream or a UDP stream.
-     * 
-     * @author Alexander Wenckus
-     */
-    public enum Mode {
-
-        /**
-         * A TCP based stream.
-         */
-        tcp,
-
-        /**
-         * A UDP based stream.
-         */
-        udp;
-
-        public static Mode fromName(String name) {
-            Mode mode;
-            try {
-                mode = Mode.valueOf(name);
-            }
-            catch (Exception ex) {
-                mode = tcp;
-            }
-
-            return mode;
-        }
-    }
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.socks5.packet;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.PacketExtension;
+
+/**
+ * A packet representing part of a SOCKS5 Bytestream negotiation.
+ * 
+ * @author Alexander Wenckus
+ */
+public class Bytestream extends IQ {
+
+    private String sessionID;
+
+    private Mode mode = Mode.tcp;
+
+    private final List<StreamHost> streamHosts = new ArrayList<StreamHost>();
+
+    private StreamHostUsed usedHost;
+
+    private Activate toActivate;
+
+    /**
+     * The default constructor
+     */
+    public Bytestream() {
+        super();
+    }
+
+    /**
+     * A constructor where the session ID can be specified.
+     * 
+     * @param SID The session ID related to the negotiation.
+     * @see #setSessionID(String)
+     */
+    public Bytestream(final String SID) {
+        super();
+        setSessionID(SID);
+    }
+
+    /**
+     * Set the session ID related to the bytestream. The session ID is a unique identifier used to
+     * differentiate between stream negotiations.
+     * 
+     * @param sessionID the unique session ID that identifies the transfer.
+     */
+    public void setSessionID(final String sessionID) {
+        this.sessionID = sessionID;
+    }
+
+    /**
+     * Returns the session ID related to the bytestream negotiation.
+     * 
+     * @return Returns the session ID related to the bytestream negotiation.
+     * @see #setSessionID(String)
+     */
+    public String getSessionID() {
+        return sessionID;
+    }
+
+    /**
+     * Set the transport mode. This should be put in the initiation of the interaction.
+     * 
+     * @param mode the transport mode, either UDP or TCP
+     * @see Mode
+     */
+    public void setMode(final Mode mode) {
+        this.mode = mode;
+    }
+
+    /**
+     * Returns the transport mode.
+     * 
+     * @return Returns the transport mode.
+     * @see #setMode(Mode)
+     */
+    public Mode getMode() {
+        return mode;
+    }
+
+    /**
+     * Adds a potential stream host that the remote user can connect to to receive the file.
+     * 
+     * @param JID The JID of the stream host.
+     * @param address The internet address of the stream host.
+     * @return The added stream host.
+     */
+    public StreamHost addStreamHost(final String JID, final String address) {
+        return addStreamHost(JID, address, 0);
+    }
+
+    /**
+     * Adds a potential stream host that the remote user can connect to to receive the file.
+     * 
+     * @param JID The JID of the stream host.
+     * @param address The internet address of the stream host.
+     * @param port The port on which the remote host is seeking connections.
+     * @return The added stream host.
+     */
+    public StreamHost addStreamHost(final String JID, final String address, final int port) {
+        StreamHost host = new StreamHost(JID, address);
+        host.setPort(port);
+        addStreamHost(host);
+
+        return host;
+    }
+
+    /**
+     * Adds a potential stream host that the remote user can transfer the file through.
+     * 
+     * @param host The potential stream host.
+     */
+    public void addStreamHost(final StreamHost host) {
+        streamHosts.add(host);
+    }
+
+    /**
+     * Returns the list of stream hosts contained in the packet.
+     * 
+     * @return Returns the list of stream hosts contained in the packet.
+     */
+    public Collection<StreamHost> getStreamHosts() {
+        return Collections.unmodifiableCollection(streamHosts);
+    }
+
+    /**
+     * Returns the stream host related to the given JID, or null if there is none.
+     * 
+     * @param JID The JID of the desired stream host.
+     * @return Returns the stream host related to the given JID, or null if there is none.
+     */
+    public StreamHost getStreamHost(final String JID) {
+        if (JID == null) {
+            return null;
+        }
+        for (StreamHost host : streamHosts) {
+            if (host.getJID().equals(JID)) {
+                return host;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the count of stream hosts contained in this packet.
+     * 
+     * @return Returns the count of stream hosts contained in this packet.
+     */
+    public int countStreamHosts() {
+        return streamHosts.size();
+    }
+
+    /**
+     * Upon connecting to the stream host the target of the stream replies to the initiator with the
+     * JID of the SOCKS5 host that they used.
+     * 
+     * @param JID The JID of the used host.
+     */
+    public void setUsedHost(final String JID) {
+        this.usedHost = new StreamHostUsed(JID);
+    }
+
+    /**
+     * Returns the SOCKS5 host connected to by the remote user.
+     * 
+     * @return Returns the SOCKS5 host connected to by the remote user.
+     */
+    public StreamHostUsed getUsedHost() {
+        return usedHost;
+    }
+
+    /**
+     * Returns the activate element of the packet sent to the proxy host to verify the identity of
+     * the initiator and match them to the appropriate stream.
+     * 
+     * @return Returns the activate element of the packet sent to the proxy host to verify the
+     *         identity of the initiator and match them to the appropriate stream.
+     */
+    public Activate getToActivate() {
+        return toActivate;
+    }
+
+    /**
+     * Upon the response from the target of the used host the activate packet is sent to the SOCKS5
+     * proxy. The proxy will activate the stream or return an error after verifying the identity of
+     * the initiator, using the activate packet.
+     * 
+     * @param targetID The JID of the target of the file transfer.
+     */
+    public void setToActivate(final String targetID) {
+        this.toActivate = new Activate(targetID);
+    }
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<query xmlns=\"http://jabber.org/protocol/bytestreams\"");
+        if (this.getType().equals(IQ.Type.SET)) {
+            if (getSessionID() != null) {
+                buf.append(" sid=\"").append(getSessionID()).append("\"");
+            }
+            if (getMode() != null) {
+                buf.append(" mode = \"").append(getMode()).append("\"");
+            }
+            buf.append(">");
+            if (getToActivate() == null) {
+                for (StreamHost streamHost : getStreamHosts()) {
+                    buf.append(streamHost.toXML());
+                }
+            }
+            else {
+                buf.append(getToActivate().toXML());
+            }
+        }
+        else if (this.getType().equals(IQ.Type.RESULT)) {
+            buf.append(">");
+            if (getUsedHost() != null) {
+                buf.append(getUsedHost().toXML());
+            }
+            // A result from the server can also contain stream hosts
+            else if (countStreamHosts() > 0) {
+                for (StreamHost host : streamHosts) {
+                    buf.append(host.toXML());
+                }
+            }
+        }
+        else if (this.getType().equals(IQ.Type.GET)) {
+            return buf.append("/>").toString();
+        }
+        else {
+            return null;
+        }
+        buf.append("</query>");
+
+        return buf.toString();
+    }
+
+    /**
+     * Packet extension that represents a potential SOCKS5 proxy for the file transfer. Stream hosts
+     * are forwarded to the target of the file transfer who then chooses and connects to one.
+     * 
+     * @author Alexander Wenckus
+     */
+    public static class StreamHost implements PacketExtension {
+
+        public static String NAMESPACE = "";
+
+        public static String ELEMENTNAME = "streamhost";
+
+        private final String JID;
+
+        private final String addy;
+
+        private int port = 0;
+
+        /**
+         * Default constructor.
+         * 
+         * @param JID The JID of the stream host.
+         * @param address The internet address of the stream host.
+         */
+        public StreamHost(final String JID, final String address) {
+            this.JID = JID;
+            this.addy = address;
+        }
+
+        /**
+         * Returns the JID of the stream host.
+         * 
+         * @return Returns the JID of the stream host.
+         */
+        public String getJID() {
+            return JID;
+        }
+
+        /**
+         * Returns the internet address of the stream host.
+         * 
+         * @return Returns the internet address of the stream host.
+         */
+        public String getAddress() {
+            return addy;
+        }
+
+        /**
+         * Sets the port of the stream host.
+         * 
+         * @param port The port on which the potential stream host would accept the connection.
+         */
+        public void setPort(final int port) {
+            this.port = port;
+        }
+
+        /**
+         * Returns the port on which the potential stream host would accept the connection.
+         * 
+         * @return Returns the port on which the potential stream host would accept the connection.
+         */
+        public int getPort() {
+            return port;
+        }
+
+        public String getNamespace() {
+            return NAMESPACE;
+        }
+
+        public String getElementName() {
+            return ELEMENTNAME;
+        }
+
+        public String toXML() {
+            StringBuilder buf = new StringBuilder();
+
+            buf.append("<").append(getElementName()).append(" ");
+            buf.append("jid=\"").append(getJID()).append("\" ");
+            buf.append("host=\"").append(getAddress()).append("\" ");
+            if (getPort() != 0) {
+                buf.append("port=\"").append(getPort()).append("\"");
+            }
+            else {
+                buf.append("zeroconf=\"_jabber.bytestreams\"");
+            }
+            buf.append("/>");
+
+            return buf.toString();
+        }
+    }
+
+    /**
+     * After selected a SOCKS5 stream host and successfully connecting, the target of the file
+     * transfer returns a byte stream packet with the stream host used extension.
+     * 
+     * @author Alexander Wenckus
+     */
+    public static class StreamHostUsed implements PacketExtension {
+
+        public String NAMESPACE = "";
+
+        public static String ELEMENTNAME = "streamhost-used";
+
+        private final String JID;
+
+        /**
+         * Default constructor.
+         * 
+         * @param JID The JID of the selected stream host.
+         */
+        public StreamHostUsed(final String JID) {
+            this.JID = JID;
+        }
+
+        /**
+         * Returns the JID of the selected stream host.
+         * 
+         * @return Returns the JID of the selected stream host.
+         */
+        public String getJID() {
+            return JID;
+        }
+
+        public String getNamespace() {
+            return NAMESPACE;
+        }
+
+        public String getElementName() {
+            return ELEMENTNAME;
+        }
+
+        public String toXML() {
+            StringBuilder buf = new StringBuilder();
+            buf.append("<").append(getElementName()).append(" ");
+            buf.append("jid=\"").append(getJID()).append("\" ");
+            buf.append("/>");
+            return buf.toString();
+        }
+    }
+
+    /**
+     * The packet sent by the stream initiator to the stream proxy to activate the connection.
+     * 
+     * @author Alexander Wenckus
+     */
+    public static class Activate implements PacketExtension {
+
+        public String NAMESPACE = "";
+
+        public static String ELEMENTNAME = "activate";
+
+        private final String target;
+
+        /**
+         * Default constructor specifying the target of the stream.
+         * 
+         * @param target The target of the stream.
+         */
+        public Activate(final String target) {
+            this.target = target;
+        }
+
+        /**
+         * Returns the target of the activation.
+         * 
+         * @return Returns the target of the activation.
+         */
+        public String getTarget() {
+            return target;
+        }
+
+        public String getNamespace() {
+            return NAMESPACE;
+        }
+
+        public String getElementName() {
+            return ELEMENTNAME;
+        }
+
+        public String toXML() {
+            StringBuilder buf = new StringBuilder();
+            buf.append("<").append(getElementName()).append(">");
+            buf.append(getTarget());
+            buf.append("</").append(getElementName()).append(">");
+            return buf.toString();
+        }
+    }
+
+    /**
+     * The stream can be either a TCP stream or a UDP stream.
+     * 
+     * @author Alexander Wenckus
+     */
+    public enum Mode {
+
+        /**
+         * A TCP based stream.
+         */
+        tcp,
+
+        /**
+         * A UDP based stream.
+         */
+        udp;
+
+        public static Mode fromName(String name) {
+            Mode mode;
+            try {
+                mode = Mode.valueOf(name);
+            }
+            catch (Exception ex) {
+                mode = tcp;
+            }
+
+            return mode;
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/provider/BytestreamsProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/provider/BytestreamsProvider.java
index 76f9b0c..fca8b27 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/provider/BytestreamsProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bytestreams/socks5/provider/BytestreamsProvider.java
@@ -1,82 +1,82 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.bytestreams.socks5.provider;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * Parses a bytestream packet.
- * 
- * @author Alexander Wenckus
- */
-public class BytestreamsProvider implements IQProvider {
-
-    public IQ parseIQ(XmlPullParser parser) throws Exception {
-        boolean done = false;
-
-        Bytestream toReturn = new Bytestream();
-
-        String id = parser.getAttributeValue("", "sid");
-        String mode = parser.getAttributeValue("", "mode");
-
-        // streamhost
-        String JID = null;
-        String host = null;
-        String port = null;
-
-        int eventType;
-        String elementName;
-        while (!done) {
-            eventType = parser.next();
-            elementName = parser.getName();
-            if (eventType == XmlPullParser.START_TAG) {
-                if (elementName.equals(Bytestream.StreamHost.ELEMENTNAME)) {
-                    JID = parser.getAttributeValue("", "jid");
-                    host = parser.getAttributeValue("", "host");
-                    port = parser.getAttributeValue("", "port");
-                }
-                else if (elementName.equals(Bytestream.StreamHostUsed.ELEMENTNAME)) {
-                    toReturn.setUsedHost(parser.getAttributeValue("", "jid"));
-                }
-                else if (elementName.equals(Bytestream.Activate.ELEMENTNAME)) {
-                    toReturn.setToActivate(parser.getAttributeValue("", "jid"));
-                }
-            }
-            else if (eventType == XmlPullParser.END_TAG) {
-                if (elementName.equals("streamhost")) {
-                    if (port == null) {
-                        toReturn.addStreamHost(JID, host);
-                    }
-                    else {
-                        toReturn.addStreamHost(JID, host, Integer.parseInt(port));
-                    }
-                    JID = null;
-                    host = null;
-                    port = null;
-                }
-                else if (elementName.equals("query")) {
-                    done = true;
-                }
-            }
-        }
-
-        toReturn.setMode((Bytestream.Mode.fromName(mode)));
-        toReturn.setSessionID(id);
-        return toReturn;
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.bytestreams.socks5.provider;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * Parses a bytestream packet.
+ * 
+ * @author Alexander Wenckus
+ */
+public class BytestreamsProvider implements IQProvider {
+
+    public IQ parseIQ(XmlPullParser parser) throws Exception {
+        boolean done = false;
+
+        Bytestream toReturn = new Bytestream();
+
+        String id = parser.getAttributeValue("", "sid");
+        String mode = parser.getAttributeValue("", "mode");
+
+        // streamhost
+        String JID = null;
+        String host = null;
+        String port = null;
+
+        int eventType;
+        String elementName;
+        while (!done) {
+            eventType = parser.next();
+            elementName = parser.getName();
+            if (eventType == XmlPullParser.START_TAG) {
+                if (elementName.equals(Bytestream.StreamHost.ELEMENTNAME)) {
+                    JID = parser.getAttributeValue("", "jid");
+                    host = parser.getAttributeValue("", "host");
+                    port = parser.getAttributeValue("", "port");
+                }
+                else if (elementName.equals(Bytestream.StreamHostUsed.ELEMENTNAME)) {
+                    toReturn.setUsedHost(parser.getAttributeValue("", "jid"));
+                }
+                else if (elementName.equals(Bytestream.Activate.ELEMENTNAME)) {
+                    toReturn.setToActivate(parser.getAttributeValue("", "jid"));
+                }
+            }
+            else if (eventType == XmlPullParser.END_TAG) {
+                if (elementName.equals("streamhost")) {
+                    if (port == null) {
+                        toReturn.addStreamHost(JID, host);
+                    }
+                    else {
+                        toReturn.addStreamHost(JID, host, Integer.parseInt(port));
+                    }
+                    JID = null;
+                    host = null;
+                    port = null;
+                }
+                else if (elementName.equals("query")) {
+                    done = true;
+                }
+            }
+        }
+
+        toReturn.setMode((Bytestream.Mode.fromName(mode)));
+        toReturn.setSessionID(id);
+        return toReturn;
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/commands/AdHocCommand.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/commands/AdHocCommand.java
index 3077d08..6aa0110 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/commands/AdHocCommand.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/commands/AdHocCommand.java
@@ -1,450 +1,450 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2005-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.commands;
-
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.packet.XMPPError;
-import org.jivesoftware.smackx.Form;
-import org.jivesoftware.smackx.packet.AdHocCommandData;
-
-import java.util.List;
-
-/**
- * An ad-hoc command is responsible for executing the provided service and
- * storing the result of the execution. Each new request will create a new
- * instance of the command, allowing information related to executions to be
- * stored in it. For example suppose that a command that retrieves the list of
- * users on a server is implemented. When the command is executed it gets that
- * list and the result is stored as a form in the command instance, i.e. the
- * <code>getForm</code> method retrieves a form with all the users.
- * <p>
- * Each command has a <tt>node</tt> that should be unique within a given JID.
- * <p>
- * Commands may have zero or more stages. Each stage is usually used for
- * gathering information required for the command execution. Users are able to
- * move forward or backward across the different stages. Commands may not be
- * cancelled while they are being executed. However, users may request the
- * "cancel" action when submitting a stage response indicating that the command
- * execution should be aborted. Thus, releasing any collected information.
- * Commands that require user interaction (i.e. have more than one stage) will
- * have to provide the data forms the user must complete in each stage and the
- * allowed actions the user might perform during each stage (e.g. go to the
- * previous stage or go to the next stage).
- * <p>
- * All the actions may throw an XMPPException if there is a problem executing
- * them. The <code>XMPPError</code> of that exception may have some specific
- * information about the problem. The possible extensions are:
- * 
- * <li><i>malformed-action</i>. Extension of a <i>bad-request</i> error.</li>
- * <li><i>bad-action</i>. Extension of a <i>bad-request</i> error.</li>
- * <li><i>bad-locale</i>. Extension of a <i>bad-request</i> error.</li>
- * <li><i>bad-payload</i>. Extension of a <i>bad-request</i> error.</li>
- * <li><i>bad-sessionid</i>. Extension of a <i>bad-request</i> error.</li>
- * <li><i>session-expired</i>. Extension of a <i>not-allowed</i> error.</li>
- * <p>
- * See the <code>SpecificErrorCondition</code> class for detailed description
- * of each one.
- * <p>
- * Use the <code>getSpecificErrorConditionFrom</code> to obtain the specific
- * information from an <code>XMPPError</code>.
- * 
- * @author Gabriel Guardincerri
- * 
- */
-public abstract class AdHocCommand {
-    // TODO: Analyze the redesign of command by having an ExecutionResponse as a
-    // TODO: result to the execution of every action. That result should have all the
-    // TODO: information related to the execution, e.g. the form to fill. Maybe this
-    // TODO: design is more intuitive and simpler than the current one that has all in
-    // TODO: one class.
-
-    private AdHocCommandData data;
-
-    public AdHocCommand() {
-        super();
-        data = new AdHocCommandData();
-    }
-
-    /**
-     * Returns the specific condition of the <code>error</code> or <tt>null</tt> if the
-     * error doesn't have any.
-     * 
-     * @param error the error the get the specific condition from.
-     * @return the specific condition of this error, or null if it doesn't have
-     *         any.
-     */
-    public static SpecificErrorCondition getSpecificErrorCondition(XMPPError error) {
-        // This method is implemented to provide an easy way of getting a packet
-        // extension of the XMPPError.
-        for (SpecificErrorCondition condition : SpecificErrorCondition.values()) {
-            if (error.getExtension(condition.toString(),
-                    AdHocCommandData.SpecificError.namespace) != null) {
-                return condition;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Set the the human readable name of the command, usually used for
-     * displaying in a UI.
-     * 
-     * @param name the name.
-     */
-    public void setName(String name) {
-        data.setName(name);
-    }
-
-    /**
-     * Returns the human readable name of the command.
-     * 
-     * @return the human readable name of the command
-     */
-    public String getName() {
-        return data.getName();
-    }
-
-    /**
-     * Sets the unique identifier of the command. This value must be unique for
-     * the <code>OwnerJID</code>.
-     * 
-     * @param node the unique identifier of the command.
-     */
-    public void setNode(String node) {
-        data.setNode(node);
-    }
-
-    /**
-     * Returns the unique identifier of the command. It is unique for the
-     * <code>OwnerJID</code>.
-     * 
-     * @return the unique identifier of the command.
-     */
-    public String getNode() {
-        return data.getNode();
-    }
-
-    /**
-     * Returns the full JID of the owner of this command. This JID is the "to" of a
-     * execution request.
-     * 
-     * @return the owner JID.
-     */
-    public abstract String getOwnerJID();
-
-    /**
-     * Returns the notes that the command has at the current stage.
-     * 
-     * @return a list of notes.
-     */
-    public List<AdHocCommandNote> getNotes() {
-        return data.getNotes();
-    }
-
-    /**
-     * Adds a note to the current stage. This should be used when setting a
-     * response to the execution of an action. All the notes added here are
-     * returned by the {@link #getNotes} method during the current stage.
-     * Once the stage changes all the notes are discarded.
-     * 
-     * @param note the note.
-     */
-    protected void addNote(AdHocCommandNote note) {
-        data.addNote(note);
-    }
-
-    public String getRaw() {
-        return data.getChildElementXML();
-    }
-
-    /**
-     * Returns the form of the current stage. Usually it is the form that must
-     * be answered to execute the next action. If that is the case it should be
-     * used by the requester to fill all the information that the executor needs
-     * to continue to the next stage. It can also be the result of the
-     * execution.
-     * 
-     * @return the form of the current stage to fill out or the result of the
-     *         execution.
-     */
-    public Form getForm() {
-        if (data.getForm() == null) {
-            return null;
-        }
-        else {
-            return new Form(data.getForm());
-        }
-    }
-
-    /**
-     * Sets the form of the current stage. This should be used when setting a
-     * response. It could be a form to fill out the information needed to go to
-     * the next stage or the result of an execution.
-     * 
-     * @param form the form of the current stage to fill out or the result of the
-     *      execution.
-     */
-    protected void setForm(Form form) {
-        data.setForm(form.getDataFormToSend());
-    }
-
-    /**
-     * Executes the command. This is invoked only on the first stage of the
-     * command. It is invoked on every command. If there is a problem executing
-     * the command it throws an XMPPException.
-     * 
-     * @throws XMPPException if there is an error executing the command.
-     */
-    public abstract void execute() throws XMPPException;
-
-    /**
-     * Executes the next action of the command with the information provided in
-     * the <code>response</code>. This form must be the answer form of the
-     * previous stage. This method will be only invoked for commands that have one
-     * or more stages. If there is a problem executing the command it throws an
-     * XMPPException.
-     * 
-     * @param response the form answer of the previous stage.
-     * @throws XMPPException if there is a problem executing the command.
-     */
-    public abstract void next(Form response) throws XMPPException;
-
-    /**
-     * Completes the command execution with the information provided in the
-     * <code>response</code>. This form must be the answer form of the
-     * previous stage. This method will be only invoked for commands that have one
-     * or more stages. If there is a problem executing the command it throws an
-     * XMPPException.
-     * 
-     * @param response the form answer of the previous stage.
-     * @throws XMPPException if there is a problem executing the command.
-     */
-    public abstract void complete(Form response) throws XMPPException;
-
-    /**
-     * Goes to the previous stage. The requester is asking to re-send the
-     * information of the previous stage. The command must change it state to
-     * the previous one. If there is a problem executing the command it throws
-     * an XMPPException.
-     * 
-     * @throws XMPPException if there is a problem executing the command.
-     */
-    public abstract void prev() throws XMPPException;
-
-    /**
-     * Cancels the execution of the command. This can be invoked on any stage of
-     * the execution. If there is a problem executing the command it throws an
-     * XMPPException.
-     * 
-     * @throws XMPPException if there is a problem executing the command.
-     */
-    public abstract void cancel() throws XMPPException;
-
-    /**
-     * Returns a collection with the allowed actions based on the current stage.
-     * Possible actions are: {@link Action#prev prev}, {@link Action#next next} and
-     * {@link Action#complete complete}. This method will be only invoked for commands that
-     * have one or more stages.
-     * 
-     * @return a collection with the allowed actions based on the current stage
-     *      as defined in the SessionData.
-     */
-    protected List<Action> getActions() {
-        return data.getActions();
-    }
-
-    /**
-     * Add an action to the current stage available actions. This should be used
-     * when creating a response.
-     * 
-     * @param action the action.
-     */
-    protected void addActionAvailable(Action action) {
-        data.addAction(action);
-    }
-
-    /**
-     * Returns the action available for the current stage which is
-     * considered the equivalent to "execute". When the requester sends his
-     * reply, if no action was defined in the command then the action will be
-     * assumed "execute" thus assuming the action returned by this method. This
-     * method will never be invoked for commands that have no stages.
-     * 
-     * @return the action available for the current stage which is considered
-     *      the equivalent to "execute".
-     */
-    protected Action getExecuteAction() {
-        return data.getExecuteAction();
-    }
-
-    /**
-     * Sets which of the actions available for the current stage is
-     * considered the equivalent to "execute". This should be used when setting
-     * a response. When the requester sends his reply, if no action was defined
-     * in the command then the action will be assumed "execute" thus assuming
-     * the action returned by this method.
-     * 
-     * @param action the action.
-     */
-    protected void setExecuteAction(Action action) {
-        data.setExecuteAction(action);
-    }
-
-    /**
-     * Returns the status of the current stage.
-     * 
-     * @return the current status.
-     */
-    public Status getStatus() {
-        return data.getStatus();
-    }
-
-    /**
-     * Sets the data of the current stage. This should not used.
-     * 
-     * @param data the data.
-     */
-    void setData(AdHocCommandData data) {
-        this.data = data;
-    }
-
-    /**
-     * Gets the data of the current stage. This should not used.
-     *
-     * @return the data.
-     */
-    AdHocCommandData getData() {
-        return data;
-    }
-
-    /**
-     * Returns true if the <code>action</code> is available in the current stage.
-     * The {@link Action#cancel cancel} action is always allowed. To define the
-     * available actions use the <code>addActionAvailable</code> method.
-     * 
-     * @param action
-     *            The action to check if it is available.
-     * @return True if the action is available for the current stage.
-     */
-    protected boolean isValidAction(Action action) {
-        return getActions().contains(action) || Action.cancel.equals(action);
-    }
-
-    /**
-     * The status of the stage in the adhoc command.
-     */
-    public enum Status {
-
-        /**
-         * The command is being executed.
-         */
-        executing,
-
-        /**
-         * The command has completed. The command session has ended.
-         */
-        completed,
-
-        /**
-         * The command has been canceled. The command session has ended.
-         */
-        canceled
-    }
-
-    public enum Action {
-
-        /**
-         * The command should be executed or continue to be executed. This is
-         * the default value.
-         */
-        execute,
-
-        /**
-         * The command should be canceled.
-         */
-        cancel,
-
-        /**
-         * The command should be digress to the previous stage of execution.
-         */
-        prev,
-
-        /**
-         * The command should progress to the next stage of execution.
-         */
-        next,
-
-        /**
-         * The command should be completed (if possible).
-         */
-        complete,
-
-        /**
-         * The action is unknow. This is used when a recieved message has an
-         * unknown action. It must not be used to send an execution request.
-         */
-        unknown
-    }
-
-    public enum SpecificErrorCondition {
-
-        /**
-         * The responding JID cannot accept the specified action.
-         */
-        badAction("bad-action"),
-
-        /**
-         * The responding JID does not understand the specified action.
-         */
-        malformedAction("malformed-action"),
-
-        /**
-         * The responding JID cannot accept the specified language/locale.
-         */
-        badLocale("bad-locale"),
-
-        /**
-         * The responding JID cannot accept the specified payload (e.g. the data
-         * form did not provide one or more required fields).
-         */
-        badPayload("bad-payload"),
-
-        /**
-         * The responding JID cannot accept the specified sessionid.
-         */
-        badSessionid("bad-sessionid"),
-
-        /**
-         * The requesting JID specified a sessionid that is no longer active
-         * (either because it was completed, canceled, or timed out).
-         */
-        sessionExpired("session-expired");
-
-        private String value;
-
-        SpecificErrorCondition(String value) {
-            this.value = value;
-        }
-
-        public String toString() {
-            return value;
-        }
-    }
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2005-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.commands;
+
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.packet.XMPPError;
+import org.jivesoftware.smackx.Form;
+import org.jivesoftware.smackx.packet.AdHocCommandData;
+
+import java.util.List;
+
+/**
+ * An ad-hoc command is responsible for executing the provided service and
+ * storing the result of the execution. Each new request will create a new
+ * instance of the command, allowing information related to executions to be
+ * stored in it. For example suppose that a command that retrieves the list of
+ * users on a server is implemented. When the command is executed it gets that
+ * list and the result is stored as a form in the command instance, i.e. the
+ * <code>getForm</code> method retrieves a form with all the users.
+ * <p>
+ * Each command has a <tt>node</tt> that should be unique within a given JID.
+ * <p>
+ * Commands may have zero or more stages. Each stage is usually used for
+ * gathering information required for the command execution. Users are able to
+ * move forward or backward across the different stages. Commands may not be
+ * cancelled while they are being executed. However, users may request the
+ * "cancel" action when submitting a stage response indicating that the command
+ * execution should be aborted. Thus, releasing any collected information.
+ * Commands that require user interaction (i.e. have more than one stage) will
+ * have to provide the data forms the user must complete in each stage and the
+ * allowed actions the user might perform during each stage (e.g. go to the
+ * previous stage or go to the next stage).
+ * <p>
+ * All the actions may throw an XMPPException if there is a problem executing
+ * them. The <code>XMPPError</code> of that exception may have some specific
+ * information about the problem. The possible extensions are:
+ * 
+ * <li><i>malformed-action</i>. Extension of a <i>bad-request</i> error.</li>
+ * <li><i>bad-action</i>. Extension of a <i>bad-request</i> error.</li>
+ * <li><i>bad-locale</i>. Extension of a <i>bad-request</i> error.</li>
+ * <li><i>bad-payload</i>. Extension of a <i>bad-request</i> error.</li>
+ * <li><i>bad-sessionid</i>. Extension of a <i>bad-request</i> error.</li>
+ * <li><i>session-expired</i>. Extension of a <i>not-allowed</i> error.</li>
+ * <p>
+ * See the <code>SpecificErrorCondition</code> class for detailed description
+ * of each one.
+ * <p>
+ * Use the <code>getSpecificErrorConditionFrom</code> to obtain the specific
+ * information from an <code>XMPPError</code>.
+ * 
+ * @author Gabriel Guardincerri
+ * 
+ */
+public abstract class AdHocCommand {
+    // TODO: Analyze the redesign of command by having an ExecutionResponse as a
+    // TODO: result to the execution of every action. That result should have all the
+    // TODO: information related to the execution, e.g. the form to fill. Maybe this
+    // TODO: design is more intuitive and simpler than the current one that has all in
+    // TODO: one class.
+
+    private AdHocCommandData data;
+
+    public AdHocCommand() {
+        super();
+        data = new AdHocCommandData();
+    }
+
+    /**
+     * Returns the specific condition of the <code>error</code> or <tt>null</tt> if the
+     * error doesn't have any.
+     * 
+     * @param error the error the get the specific condition from.
+     * @return the specific condition of this error, or null if it doesn't have
+     *         any.
+     */
+    public static SpecificErrorCondition getSpecificErrorCondition(XMPPError error) {
+        // This method is implemented to provide an easy way of getting a packet
+        // extension of the XMPPError.
+        for (SpecificErrorCondition condition : SpecificErrorCondition.values()) {
+            if (error.getExtension(condition.toString(),
+                    AdHocCommandData.SpecificError.namespace) != null) {
+                return condition;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Set the the human readable name of the command, usually used for
+     * displaying in a UI.
+     * 
+     * @param name the name.
+     */
+    public void setName(String name) {
+        data.setName(name);
+    }
+
+    /**
+     * Returns the human readable name of the command.
+     * 
+     * @return the human readable name of the command
+     */
+    public String getName() {
+        return data.getName();
+    }
+
+    /**
+     * Sets the unique identifier of the command. This value must be unique for
+     * the <code>OwnerJID</code>.
+     * 
+     * @param node the unique identifier of the command.
+     */
+    public void setNode(String node) {
+        data.setNode(node);
+    }
+
+    /**
+     * Returns the unique identifier of the command. It is unique for the
+     * <code>OwnerJID</code>.
+     * 
+     * @return the unique identifier of the command.
+     */
+    public String getNode() {
+        return data.getNode();
+    }
+
+    /**
+     * Returns the full JID of the owner of this command. This JID is the "to" of a
+     * execution request.
+     * 
+     * @return the owner JID.
+     */
+    public abstract String getOwnerJID();
+
+    /**
+     * Returns the notes that the command has at the current stage.
+     * 
+     * @return a list of notes.
+     */
+    public List<AdHocCommandNote> getNotes() {
+        return data.getNotes();
+    }
+
+    /**
+     * Adds a note to the current stage. This should be used when setting a
+     * response to the execution of an action. All the notes added here are
+     * returned by the {@link #getNotes} method during the current stage.
+     * Once the stage changes all the notes are discarded.
+     * 
+     * @param note the note.
+     */
+    protected void addNote(AdHocCommandNote note) {
+        data.addNote(note);
+    }
+
+    public String getRaw() {
+        return data.getChildElementXML();
+    }
+
+    /**
+     * Returns the form of the current stage. Usually it is the form that must
+     * be answered to execute the next action. If that is the case it should be
+     * used by the requester to fill all the information that the executor needs
+     * to continue to the next stage. It can also be the result of the
+     * execution.
+     * 
+     * @return the form of the current stage to fill out or the result of the
+     *         execution.
+     */
+    public Form getForm() {
+        if (data.getForm() == null) {
+            return null;
+        }
+        else {
+            return new Form(data.getForm());
+        }
+    }
+
+    /**
+     * Sets the form of the current stage. This should be used when setting a
+     * response. It could be a form to fill out the information needed to go to
+     * the next stage or the result of an execution.
+     * 
+     * @param form the form of the current stage to fill out or the result of the
+     *      execution.
+     */
+    protected void setForm(Form form) {
+        data.setForm(form.getDataFormToSend());
+    }
+
+    /**
+     * Executes the command. This is invoked only on the first stage of the
+     * command. It is invoked on every command. If there is a problem executing
+     * the command it throws an XMPPException.
+     * 
+     * @throws XMPPException if there is an error executing the command.
+     */
+    public abstract void execute() throws XMPPException;
+
+    /**
+     * Executes the next action of the command with the information provided in
+     * the <code>response</code>. This form must be the answer form of the
+     * previous stage. This method will be only invoked for commands that have one
+     * or more stages. If there is a problem executing the command it throws an
+     * XMPPException.
+     * 
+     * @param response the form answer of the previous stage.
+     * @throws XMPPException if there is a problem executing the command.
+     */
+    public abstract void next(Form response) throws XMPPException;
+
+    /**
+     * Completes the command execution with the information provided in the
+     * <code>response</code>. This form must be the answer form of the
+     * previous stage. This method will be only invoked for commands that have one
+     * or more stages. If there is a problem executing the command it throws an
+     * XMPPException.
+     * 
+     * @param response the form answer of the previous stage.
+     * @throws XMPPException if there is a problem executing the command.
+     */
+    public abstract void complete(Form response) throws XMPPException;
+
+    /**
+     * Goes to the previous stage. The requester is asking to re-send the
+     * information of the previous stage. The command must change it state to
+     * the previous one. If there is a problem executing the command it throws
+     * an XMPPException.
+     * 
+     * @throws XMPPException if there is a problem executing the command.
+     */
+    public abstract void prev() throws XMPPException;
+
+    /**
+     * Cancels the execution of the command. This can be invoked on any stage of
+     * the execution. If there is a problem executing the command it throws an
+     * XMPPException.
+     * 
+     * @throws XMPPException if there is a problem executing the command.
+     */
+    public abstract void cancel() throws XMPPException;
+
+    /**
+     * Returns a collection with the allowed actions based on the current stage.
+     * Possible actions are: {@link Action#prev prev}, {@link Action#next next} and
+     * {@link Action#complete complete}. This method will be only invoked for commands that
+     * have one or more stages.
+     * 
+     * @return a collection with the allowed actions based on the current stage
+     *      as defined in the SessionData.
+     */
+    protected List<Action> getActions() {
+        return data.getActions();
+    }
+
+    /**
+     * Add an action to the current stage available actions. This should be used
+     * when creating a response.
+     * 
+     * @param action the action.
+     */
+    protected void addActionAvailable(Action action) {
+        data.addAction(action);
+    }
+
+    /**
+     * Returns the action available for the current stage which is
+     * considered the equivalent to "execute". When the requester sends his
+     * reply, if no action was defined in the command then the action will be
+     * assumed "execute" thus assuming the action returned by this method. This
+     * method will never be invoked for commands that have no stages.
+     * 
+     * @return the action available for the current stage which is considered
+     *      the equivalent to "execute".
+     */
+    protected Action getExecuteAction() {
+        return data.getExecuteAction();
+    }
+
+    /**
+     * Sets which of the actions available for the current stage is
+     * considered the equivalent to "execute". This should be used when setting
+     * a response. When the requester sends his reply, if no action was defined
+     * in the command then the action will be assumed "execute" thus assuming
+     * the action returned by this method.
+     * 
+     * @param action the action.
+     */
+    protected void setExecuteAction(Action action) {
+        data.setExecuteAction(action);
+    }
+
+    /**
+     * Returns the status of the current stage.
+     * 
+     * @return the current status.
+     */
+    public Status getStatus() {
+        return data.getStatus();
+    }
+
+    /**
+     * Sets the data of the current stage. This should not used.
+     * 
+     * @param data the data.
+     */
+    void setData(AdHocCommandData data) {
+        this.data = data;
+    }
+
+    /**
+     * Gets the data of the current stage. This should not used.
+     *
+     * @return the data.
+     */
+    AdHocCommandData getData() {
+        return data;
+    }
+
+    /**
+     * Returns true if the <code>action</code> is available in the current stage.
+     * The {@link Action#cancel cancel} action is always allowed. To define the
+     * available actions use the <code>addActionAvailable</code> method.
+     * 
+     * @param action
+     *            The action to check if it is available.
+     * @return True if the action is available for the current stage.
+     */
+    protected boolean isValidAction(Action action) {
+        return getActions().contains(action) || Action.cancel.equals(action);
+    }
+
+    /**
+     * The status of the stage in the adhoc command.
+     */
+    public enum Status {
+
+        /**
+         * The command is being executed.
+         */
+        executing,
+
+        /**
+         * The command has completed. The command session has ended.
+         */
+        completed,
+
+        /**
+         * The command has been canceled. The command session has ended.
+         */
+        canceled
+    }
+
+    public enum Action {
+
+        /**
+         * The command should be executed or continue to be executed. This is
+         * the default value.
+         */
+        execute,
+
+        /**
+         * The command should be canceled.
+         */
+        cancel,
+
+        /**
+         * The command should be digress to the previous stage of execution.
+         */
+        prev,
+
+        /**
+         * The command should progress to the next stage of execution.
+         */
+        next,
+
+        /**
+         * The command should be completed (if possible).
+         */
+        complete,
+
+        /**
+         * The action is unknow. This is used when a recieved message has an
+         * unknown action. It must not be used to send an execution request.
+         */
+        unknown
+    }
+
+    public enum SpecificErrorCondition {
+
+        /**
+         * The responding JID cannot accept the specified action.
+         */
+        badAction("bad-action"),
+
+        /**
+         * The responding JID does not understand the specified action.
+         */
+        malformedAction("malformed-action"),
+
+        /**
+         * The responding JID cannot accept the specified language/locale.
+         */
+        badLocale("bad-locale"),
+
+        /**
+         * The responding JID cannot accept the specified payload (e.g. the data
+         * form did not provide one or more required fields).
+         */
+        badPayload("bad-payload"),
+
+        /**
+         * The responding JID cannot accept the specified sessionid.
+         */
+        badSessionid("bad-sessionid"),
+
+        /**
+         * The requesting JID specified a sessionid that is no longer active
+         * (either because it was completed, canceled, or timed out).
+         */
+        sessionExpired("session-expired");
+
+        private String value;
+
+        SpecificErrorCondition(String value) {
+            this.value = value;
+        }
+
+        public String toString() {
+            return value;
+        }
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/commands/AdHocCommandManager.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/commands/AdHocCommandManager.java
index 8f4eb65..737a204 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/commands/AdHocCommandManager.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/commands/AdHocCommandManager.java
@@ -1,750 +1,750 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2005-2008 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.commands;
-
-import org.jivesoftware.smack.*;
-import org.jivesoftware.smack.filter.PacketFilter;
-import org.jivesoftware.smack.filter.PacketTypeFilter;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.packet.XMPPError;
-import org.jivesoftware.smack.util.StringUtils;
-import org.jivesoftware.smackx.Form;
-import org.jivesoftware.smackx.NodeInformationProvider;
-import org.jivesoftware.smackx.ServiceDiscoveryManager;
-import org.jivesoftware.smackx.commands.AdHocCommand.Action;
-import org.jivesoftware.smackx.commands.AdHocCommand.Status;
-import org.jivesoftware.smackx.packet.AdHocCommandData;
-import org.jivesoftware.smackx.packet.DiscoverInfo;
-import org.jivesoftware.smackx.packet.DiscoverInfo.Identity;
-import org.jivesoftware.smackx.packet.DiscoverItems;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * An AdHocCommandManager is responsible for keeping the list of available
- * commands offered by a service and for processing commands requests.
- *
- * Pass in a Connection instance to
- * {@link #getAddHocCommandsManager(org.jivesoftware.smack.Connection)} in order to
- * get an instance of this class. 
- * 
- * @author Gabriel Guardincerri
- */
-public class AdHocCommandManager {
-
-    private static final String DISCO_NAMESPACE = "http://jabber.org/protocol/commands";
-
-    private static final String discoNode = DISCO_NAMESPACE;
-
-    /**
-     * The session time out in seconds.
-     */
-    private static final int SESSION_TIMEOUT = 2 * 60;
-
-    /**
-     * Map a Connection with it AdHocCommandManager. This map have a key-value
-     * pair for every active connection.
-     */
-    private static Map<Connection, AdHocCommandManager> instances =
-            new ConcurrentHashMap<Connection, AdHocCommandManager>();
-
-    /**
-     * Register the listener for all the connection creations. When a new
-     * connection is created a new AdHocCommandManager is also created and
-     * related to that connection.
-     */
-    static {
-        Connection.addConnectionCreationListener(new ConnectionCreationListener() {
-            public void connectionCreated(Connection connection) {
-                new AdHocCommandManager(connection);
-            }
-        });
-    }
-
-    /**
-     * Returns the <code>AdHocCommandManager</code> related to the
-     * <code>connection</code>.
-     *
-     * @param connection the XMPP connection.
-     * @return the AdHocCommandManager associated with the connection.
-     */
-    public static AdHocCommandManager getAddHocCommandsManager(Connection connection) {
-        return instances.get(connection);
-    }
-
-    /**
-     * Thread that reaps stale sessions.
-     */
-    private Thread sessionsSweeper;
-
-    /**
-     * The Connection that this instances of AdHocCommandManager manages
-     */
-    private Connection connection;
-
-    /**
-     * Map a command node with its AdHocCommandInfo. Note: Key=command node,
-     * Value=command. Command node matches the node attribute sent by command
-     * requesters.
-     */
-    private Map<String, AdHocCommandInfo> commands = new ConcurrentHashMap<String, AdHocCommandInfo>();
-
-    /**
-     * Map a command session ID with the instance LocalCommand. The LocalCommand
-     * is the an objects that has all the information of the current state of
-     * the command execution. Note: Key=session ID, Value=LocalCommand. Session
-     * ID matches the sessionid attribute sent by command responders.
-     */
-    private Map<String, LocalCommand> executingCommands = new ConcurrentHashMap<String, LocalCommand>();
-
-    private AdHocCommandManager(Connection connection) {
-        super();
-        this.connection = connection;
-        init();
-    }
-
-    /**
-     * Registers a new command with this command manager, which is related to a
-     * connection. The <tt>node</tt> is an unique identifier of that command for
-     * the connection related to this command manager. The <tt>name</tt> is the
-     * human readable name of the command. The <tt>class</tt> is the class of
-     * the command, which must extend {@link LocalCommand} and have a default
-     * constructor.
-     *
-     * @param node the unique identifier of the command.
-     * @param name the human readable name of the command.
-     * @param clazz the class of the command, which must extend {@link LocalCommand}.
-     */
-    public void registerCommand(String node, String name, final Class<? extends LocalCommand> clazz) {
-        registerCommand(node, name, new LocalCommandFactory() {
-            public LocalCommand getInstance() throws InstantiationException, IllegalAccessException  {
-                return clazz.newInstance();
-            }
-        });
-    }
-
-    /**
-     * Registers a new command with this command manager, which is related to a
-     * connection. The <tt>node</tt> is an unique identifier of that
-     * command for the connection related to this command manager. The <tt>name</tt>
-     * is the human readeale name of the command. The <tt>factory</tt> generates
-     * new instances of the command.
-     *
-     * @param node the unique identifier of the command.
-     * @param name the human readable name of the command.
-     * @param factory a factory to create new instances of the command.
-     */
-    public void registerCommand(String node, final String name, LocalCommandFactory factory) {
-        AdHocCommandInfo commandInfo = new AdHocCommandInfo(node, name, connection.getUser(), factory);
-
-        commands.put(node, commandInfo);
-        // Set the NodeInformationProvider that will provide information about
-        // the added command
-        ServiceDiscoveryManager.getInstanceFor(connection).setNodeInformationProvider(node,
-                new NodeInformationProvider() {
-                    public List<DiscoverItems.Item> getNodeItems() {
-                        return null;
-                    }
-
-                    public List<String> getNodeFeatures() {
-                        List<String> answer = new ArrayList<String>();
-                        answer.add(DISCO_NAMESPACE);
-                        // TODO: check if this service is provided by the
-                        // TODO: current connection.
-                        answer.add("jabber:x:data");
-                        return answer;
-                    }
-
-                    public List<DiscoverInfo.Identity> getNodeIdentities() {
-                        List<DiscoverInfo.Identity> answer = new ArrayList<DiscoverInfo.Identity>();
-                        DiscoverInfo.Identity identity = new DiscoverInfo.Identity(
-                                "automation", name, "command-node");
-                        answer.add(identity);
-                        return answer;
-                    }
-
-                    @Override
-                    public List<PacketExtension> getNodePacketExtensions() {
-                        return null;
-                    }
-
-                });
-    }
-
-    /**
-     * Discover the commands of an specific JID. The <code>jid</code> is a
-     * full JID.
-     *
-     * @param jid the full JID to retrieve the commands for.
-     * @return the discovered items.
-     * @throws XMPPException if the operation failed for some reason.
-     */
-    public DiscoverItems discoverCommands(String jid) throws XMPPException {
-        ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager
-                .getInstanceFor(connection);
-        return serviceDiscoveryManager.discoverItems(jid, discoNode);
-    }
-
-    /**
-     * Publish the commands to an specific JID.
-     *
-     * @param jid the full JID to publish the commands to.
-     * @throws XMPPException if the operation failed for some reason.
-     */
-    public void publishCommands(String jid) throws XMPPException {
-        ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager
-                .getInstanceFor(connection);
-
-        // Collects the commands to publish as items
-        DiscoverItems discoverItems = new DiscoverItems();
-        Collection<AdHocCommandInfo> xCommandsList = getRegisteredCommands();
-
-        for (AdHocCommandInfo info : xCommandsList) {
-            DiscoverItems.Item item = new DiscoverItems.Item(info.getOwnerJID());
-            item.setName(info.getName());
-            item.setNode(info.getNode());
-            discoverItems.addItem(item);
-        }
-
-        serviceDiscoveryManager.publishItems(jid, discoNode, discoverItems);
-    }
-
-    /**
-     * Returns a command that represents an instance of a command in a remote
-     * host. It is used to execute remote commands. The concept is similar to
-     * RMI. Every invocation on this command is equivalent to an invocation in
-     * the remote command.
-     *
-     * @param jid the full JID of the host of the remote command
-     * @param node the identifier of the command
-     * @return a local instance equivalent to the remote command.
-     */
-    public RemoteCommand getRemoteCommand(String jid, String node) {
-        return new RemoteCommand(connection, node, jid);
-    }
-
-    /**
-     * <ul>
-     * <li>Adds listeners to the connection</li>
-     * <li>Registers the ad-hoc command feature to the ServiceDiscoveryManager</li>
-     * <li>Registers the items of the feature</li>
-     * <li>Adds packet listeners to handle execution requests</li>
-     * <li>Creates and start the session sweeper</li>
-     * </ul>
-     */
-    private void init() {
-        // Register the new instance and associate it with the connection
-        instances.put(connection, this);
-
-        // Add a listener to the connection that removes the registered instance
-        // when the connection is closed
-        connection.addConnectionListener(new ConnectionListener() {
-            public void connectionClosed() {
-                // Unregister this instance since the connection has been closed
-                instances.remove(connection);
-            }
-
-            public void connectionClosedOnError(Exception e) {
-                // Unregister this instance since the connection has been closed
-                instances.remove(connection);
-            }
-
-            public void reconnectionSuccessful() {
-                // Register this instance since the connection has been
-                // reestablished
-                instances.put(connection, AdHocCommandManager.this);
-            }
-
-            public void reconnectingIn(int seconds) {
-                // Nothing to do
-            }
-
-            public void reconnectionFailed(Exception e) {
-                // Nothing to do
-            }
-        });
-
-        // Add the feature to the service discovery manage to show that this
-        // connection supports the AdHoc-Commands protocol.
-        // This information will be used when another client tries to
-        // discover whether this client supports AdHoc-Commands or not.
-        ServiceDiscoveryManager.getInstanceFor(connection).addFeature(
-                DISCO_NAMESPACE);
-
-        // Set the NodeInformationProvider that will provide information about
-        // which AdHoc-Commands are registered, whenever a disco request is
-        // received
-        ServiceDiscoveryManager.getInstanceFor(connection)
-                .setNodeInformationProvider(discoNode,
-                        new NodeInformationProvider() {
-                            public List<DiscoverItems.Item> getNodeItems() {
-
-                                List<DiscoverItems.Item> answer = new ArrayList<DiscoverItems.Item>();
-                                Collection<AdHocCommandInfo> commandsList = getRegisteredCommands();
-
-                                for (AdHocCommandInfo info : commandsList) {
-                                    DiscoverItems.Item item = new DiscoverItems.Item(
-                                            info.getOwnerJID());
-                                    item.setName(info.getName());
-                                    item.setNode(info.getNode());
-                                    answer.add(item);
-                                }
-
-                                return answer;
-                            }
-
-                            public List<String> getNodeFeatures() {
-                                return null;
-                            }
-
-                            public List<Identity> getNodeIdentities() {
-                                return null;
-                            }
-
-                            @Override
-                            public List<PacketExtension> getNodePacketExtensions() {
-                                return null;
-                            }
-                        });
-
-        // The packet listener and the filter for processing some AdHoc Commands
-        // Packets
-        PacketListener listener = new PacketListener() {
-            public void processPacket(Packet packet) {
-                AdHocCommandData requestData = (AdHocCommandData) packet;
-                processAdHocCommand(requestData);
-            }
-        };
-
-        PacketFilter filter = new PacketTypeFilter(AdHocCommandData.class);
-        connection.addPacketListener(listener, filter);
-
-        sessionsSweeper = null;
-    }
-
-    /**
-     * Process the AdHoc-Command packet that request the execution of some
-     * action of a command. If this is the first request, this method checks,
-     * before executing the command, if:
-     * <ul>
-     *  <li>The requested command exists</li>
-     *  <li>The requester has permissions to execute it</li>
-     *  <li>The command has more than one stage, if so, it saves the command and
-     *      session ID for further use</li>
-     * </ul>
-     * 
-     * <br>
-     * <br>
-     * If this is not the first request, this method checks, before executing
-     * the command, if:
-     * <ul>
-     *  <li>The session ID of the request was stored</li>
-     *  <li>The session life do not exceed the time out</li>
-     *  <li>The action to execute is one of the available actions</li>
-     * </ul>
-     *
-     * @param requestData
-     *            the packet to process.
-     */
-    private void processAdHocCommand(AdHocCommandData requestData) {
-        // Only process requests of type SET
-        if (requestData.getType() != IQ.Type.SET) {
-            return;
-        }
-
-        // Creates the response with the corresponding data
-        AdHocCommandData response = new AdHocCommandData();
-        response.setTo(requestData.getFrom());
-        response.setPacketID(requestData.getPacketID());
-        response.setNode(requestData.getNode());
-        response.setId(requestData.getTo());
-
-        String sessionId = requestData.getSessionID();
-        String commandNode = requestData.getNode();
-
-        if (sessionId == null) {
-            // A new execution request has been received. Check that the
-            // command exists
-            if (!commands.containsKey(commandNode)) {
-                // Requested command does not exist so return
-                // item_not_found error.
-                respondError(response, XMPPError.Condition.item_not_found);
-                return;
-            }
-
-            // Create new session ID
-            sessionId = StringUtils.randomString(15);
-
-            try {
-                // Create a new instance of the command with the
-                // corresponding sessioid
-                LocalCommand command = newInstanceOfCmd(commandNode, sessionId);
-
-                response.setType(IQ.Type.RESULT);
-                command.setData(response);
-
-                // Check that the requester has enough permission.
-                // Answer forbidden error if requester permissions are not
-                // enough to execute the requested command
-                if (!command.hasPermission(requestData.getFrom())) {
-                    respondError(response, XMPPError.Condition.forbidden);
-                    return;
-                }
-
-                Action action = requestData.getAction();
-
-                // If the action is unknown then respond an error.
-                if (action != null && action.equals(Action.unknown)) {
-                    respondError(response, XMPPError.Condition.bad_request,
-                            AdHocCommand.SpecificErrorCondition.malformedAction);
-                    return;
-                }
-
-                // If the action is not execute, then it is an invalid action.
-                if (action != null && !action.equals(Action.execute)) {
-                    respondError(response, XMPPError.Condition.bad_request,
-                            AdHocCommand.SpecificErrorCondition.badAction);
-                    return;
-                }
-
-                // Increase the state number, so the command knows in witch
-                // stage it is
-                command.incrementStage();
-                // Executes the command
-                command.execute();
-
-                if (command.isLastStage()) {
-                    // If there is only one stage then the command is completed
-                    response.setStatus(Status.completed);
-                }
-                else {
-                    // Else it is still executing, and is registered to be
-                    // available for the next call
-                    response.setStatus(Status.executing);
-                    executingCommands.put(sessionId, command);
-                    // See if the session reaping thread is started. If not, start it.
-                    if (sessionsSweeper == null) {
-                        sessionsSweeper = new Thread(new Runnable() {
-                            public void run() {
-                                while (true) {
-                                    for (String sessionId : executingCommands.keySet()) {
-                                        LocalCommand command = executingCommands.get(sessionId);
-                                        // Since the command could be removed in the meanwhile
-                                        // of getting the key and getting the value - by a
-                                        // processed packet. We must check if it still in the
-                                        // map.
-                                        if (command != null) {
-                                            long creationStamp = command.getCreationDate();
-                                            // Check if the Session data has expired (default is
-                                            // 10 minutes)
-                                            // To remove it from the session list it waits for
-                                            // the double of the of time out time. This is to
-                                            // let
-                                            // the requester know why his execution request is
-                                            // not accepted. If the session is removed just
-                                            // after the time out, then whe the user request to
-                                            // continue the execution he will recieved an
-                                            // invalid session error and not a time out error.
-                                            if (System.currentTimeMillis() - creationStamp > SESSION_TIMEOUT * 1000 * 2) {
-                                                // Remove the expired session
-                                                executingCommands.remove(sessionId);
-                                            }
-                                        }
-                                    }
-                                    try {
-                                        Thread.sleep(1000);
-                                    }
-                                    catch (InterruptedException ie) {
-                                        // Ignore.
-                                    }
-                                }
-                            }
-
-                        });
-                        sessionsSweeper.setDaemon(true);
-                        sessionsSweeper.start();
-                    }
-                }
-
-                // Sends the response packet
-                connection.sendPacket(response);
-
-            }
-            catch (XMPPException e) {
-                // If there is an exception caused by the next, complete,
-                // prev or cancel method, then that error is returned to the
-                // requester.
-                XMPPError error = e.getXMPPError();
-
-                // If the error type is cancel, then the execution is
-                // canceled therefore the status must show that, and the
-                // command be removed from the executing list.
-                if (XMPPError.Type.CANCEL.equals(error.getType())) {
-                    response.setStatus(Status.canceled);
-                    executingCommands.remove(sessionId);
-                }
-                respondError(response, error);
-                e.printStackTrace();
-            }
-        }
-        else {
-            LocalCommand command = executingCommands.get(sessionId);
-
-            // Check that a command exists for the specified sessionID
-            // This also handles if the command was removed in the meanwhile
-            // of getting the key and the value of the map.
-            if (command == null) {
-                respondError(response, XMPPError.Condition.bad_request,
-                        AdHocCommand.SpecificErrorCondition.badSessionid);
-                return;
-            }
-
-            // Check if the Session data has expired (default is 10 minutes)
-            long creationStamp = command.getCreationDate();
-            if (System.currentTimeMillis() - creationStamp > SESSION_TIMEOUT * 1000) {
-                // Remove the expired session
-                executingCommands.remove(sessionId);
-
-                // Answer a not_allowed error (session-expired)
-                respondError(response, XMPPError.Condition.not_allowed,
-                        AdHocCommand.SpecificErrorCondition.sessionExpired);
-                return;
-            }
-
-            /*
-             * Since the requester could send two requests for the same
-             * executing command i.e. the same session id, all the execution of
-             * the action must be synchronized to avoid inconsistencies.
-             */
-            synchronized (command) {
-                Action action = requestData.getAction();
-
-                // If the action is unknown the respond an error
-                if (action != null && action.equals(Action.unknown)) {
-                    respondError(response, XMPPError.Condition.bad_request,
-                            AdHocCommand.SpecificErrorCondition.malformedAction);
-                    return;
-                }
-
-                // If the user didn't specify an action or specify the execute
-                // action then follow the actual default execute action
-                if (action == null || Action.execute.equals(action)) {
-                    action = command.getExecuteAction();
-                }
-
-                // Check that the specified action was previously
-                // offered
-                if (!command.isValidAction(action)) {
-                    respondError(response, XMPPError.Condition.bad_request,
-                            AdHocCommand.SpecificErrorCondition.badAction);
-                    return;
-                }
-
-                try {
-                    // TODO: Check that all the requierd fields of the form are
-                    // TODO: filled, if not throw an exception. This will simplify the
-                    // TODO: construction of new commands
-
-                    // Since all errors were passed, the response is now a
-                    // result
-                    response.setType(IQ.Type.RESULT);
-
-                    // Set the new data to the command.
-                    command.setData(response);
-
-                    if (Action.next.equals(action)) {
-                        command.incrementStage();
-                        command.next(new Form(requestData.getForm()));
-                        if (command.isLastStage()) {
-                            // If it is the last stage then the command is
-                            // completed
-                            response.setStatus(Status.completed);
-                        }
-                        else {
-                            // Otherwise it is still executing
-                            response.setStatus(Status.executing);
-                        }
-                    }
-                    else if (Action.complete.equals(action)) {
-                        command.incrementStage();
-                        command.complete(new Form(requestData.getForm()));
-                        response.setStatus(Status.completed);
-                        // Remove the completed session
-                        executingCommands.remove(sessionId);
-                    }
-                    else if (Action.prev.equals(action)) {
-                        command.decrementStage();
-                        command.prev();
-                    }
-                    else if (Action.cancel.equals(action)) {
-                        command.cancel();
-                        response.setStatus(Status.canceled);
-                        // Remove the canceled session
-                        executingCommands.remove(sessionId);
-                    }
-
-                    connection.sendPacket(response);
-                }
-                catch (XMPPException e) {
-                    // If there is an exception caused by the next, complete,
-                    // prev or cancel method, then that error is returned to the
-                    // requester.
-                    XMPPError error = e.getXMPPError();
-
-                    // If the error type is cancel, then the execution is
-                    // canceled therefore the status must show that, and the
-                    // command be removed from the executing list.
-                    if (XMPPError.Type.CANCEL.equals(error.getType())) {
-                        response.setStatus(Status.canceled);
-                        executingCommands.remove(sessionId);
-                    }
-                    respondError(response, error);
-
-                    e.printStackTrace();
-                }
-            }
-        }
-    }
-
-    /**
-     * Responds an error with an specific condition.
-     * 
-     * @param response the response to send.
-     * @param condition the condition of the error.
-     */
-    private void respondError(AdHocCommandData response,
-            XMPPError.Condition condition) {
-        respondError(response, new XMPPError(condition));
-    }
-
-    /**
-     * Responds an error with an specific condition.
-     * 
-     * @param response the response to send.
-     * @param condition the condition of the error.
-     * @param specificCondition the adhoc command error condition.
-     */
-    private void respondError(AdHocCommandData response, XMPPError.Condition condition,
-            AdHocCommand.SpecificErrorCondition specificCondition)
-    {
-        XMPPError error = new XMPPError(condition);
-        error.addExtension(new AdHocCommandData.SpecificError(specificCondition));
-        respondError(response, error);
-    }
-
-    /**
-     * Responds an error with an specific error.
-     * 
-     * @param response the response to send.
-     * @param error the error to send.
-     */
-    private void respondError(AdHocCommandData response, XMPPError error) {
-        response.setType(IQ.Type.ERROR);
-        response.setError(error);
-        connection.sendPacket(response);
-    }
-
-    /**
-     * Creates a new instance of a command to be used by a new execution request
-     * 
-     * @param commandNode the command node that identifies it.
-     * @param sessionID the session id of this execution.
-     * @return the command instance to execute.
-     * @throws XMPPException if there is problem creating the new instance.
-     */
-    private LocalCommand newInstanceOfCmd(String commandNode, String sessionID)
-            throws XMPPException
-    {
-        AdHocCommandInfo commandInfo = commands.get(commandNode);
-        LocalCommand command;
-        try {
-            command = (LocalCommand) commandInfo.getCommandInstance();
-            command.setSessionID(sessionID);
-            command.setName(commandInfo.getName());
-            command.setNode(commandInfo.getNode());
-        }
-        catch (InstantiationException e) {
-            e.printStackTrace();
-            throw new XMPPException(new XMPPError(
-                    XMPPError.Condition.interna_server_error));
-        }
-        catch (IllegalAccessException e) {
-            e.printStackTrace();
-            throw new XMPPException(new XMPPError(
-                    XMPPError.Condition.interna_server_error));
-        }
-        return command;
-    }
-
-    /**
-     * Returns the registered commands of this command manager, which is related
-     * to a connection.
-     * 
-     * @return the registered commands.
-     */
-    private Collection<AdHocCommandInfo> getRegisteredCommands() {
-        return commands.values();
-    }
-
-    /**
-     * Stores ad-hoc command information.
-     */
-    private static class AdHocCommandInfo {
-
-        private String node;
-        private String name;
-        private String ownerJID;
-        private LocalCommandFactory factory;
-
-        public AdHocCommandInfo(String node, String name, String ownerJID,
-                LocalCommandFactory factory)
-        {
-            this.node = node;
-            this.name = name;
-            this.ownerJID = ownerJID;
-            this.factory = factory;
-        }
-
-        public LocalCommand getCommandInstance() throws InstantiationException,
-                IllegalAccessException
-        {
-            return factory.getInstance();
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public String getNode() {
-            return node;
-        }
-
-        public String getOwnerJID() {
-            return ownerJID;
-        }
-    }
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2005-2008 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.commands;
+
+import org.jivesoftware.smack.*;
+import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.filter.PacketTypeFilter;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.packet.XMPPError;
+import org.jivesoftware.smack.util.StringUtils;
+import org.jivesoftware.smackx.Form;
+import org.jivesoftware.smackx.NodeInformationProvider;
+import org.jivesoftware.smackx.ServiceDiscoveryManager;
+import org.jivesoftware.smackx.commands.AdHocCommand.Action;
+import org.jivesoftware.smackx.commands.AdHocCommand.Status;
+import org.jivesoftware.smackx.packet.AdHocCommandData;
+import org.jivesoftware.smackx.packet.DiscoverInfo;
+import org.jivesoftware.smackx.packet.DiscoverInfo.Identity;
+import org.jivesoftware.smackx.packet.DiscoverItems;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * An AdHocCommandManager is responsible for keeping the list of available
+ * commands offered by a service and for processing commands requests.
+ *
+ * Pass in a Connection instance to
+ * {@link #getAddHocCommandsManager(org.jivesoftware.smack.Connection)} in order to
+ * get an instance of this class. 
+ * 
+ * @author Gabriel Guardincerri
+ */
+public class AdHocCommandManager {
+
+    private static final String DISCO_NAMESPACE = "http://jabber.org/protocol/commands";
+
+    private static final String discoNode = DISCO_NAMESPACE;
+
+    /**
+     * The session time out in seconds.
+     */
+    private static final int SESSION_TIMEOUT = 2 * 60;
+
+    /**
+     * Map a Connection with it AdHocCommandManager. This map have a key-value
+     * pair for every active connection.
+     */
+    private static Map<Connection, AdHocCommandManager> instances =
+            new ConcurrentHashMap<Connection, AdHocCommandManager>();
+
+    /**
+     * Register the listener for all the connection creations. When a new
+     * connection is created a new AdHocCommandManager is also created and
+     * related to that connection.
+     */
+    static {
+        Connection.addConnectionCreationListener(new ConnectionCreationListener() {
+            public void connectionCreated(Connection connection) {
+                new AdHocCommandManager(connection);
+            }
+        });
+    }
+
+    /**
+     * Returns the <code>AdHocCommandManager</code> related to the
+     * <code>connection</code>.
+     *
+     * @param connection the XMPP connection.
+     * @return the AdHocCommandManager associated with the connection.
+     */
+    public static AdHocCommandManager getAddHocCommandsManager(Connection connection) {
+        return instances.get(connection);
+    }
+
+    /**
+     * Thread that reaps stale sessions.
+     */
+    private Thread sessionsSweeper;
+
+    /**
+     * The Connection that this instances of AdHocCommandManager manages
+     */
+    private Connection connection;
+
+    /**
+     * Map a command node with its AdHocCommandInfo. Note: Key=command node,
+     * Value=command. Command node matches the node attribute sent by command
+     * requesters.
+     */
+    private Map<String, AdHocCommandInfo> commands = new ConcurrentHashMap<String, AdHocCommandInfo>();
+
+    /**
+     * Map a command session ID with the instance LocalCommand. The LocalCommand
+     * is the an objects that has all the information of the current state of
+     * the command execution. Note: Key=session ID, Value=LocalCommand. Session
+     * ID matches the sessionid attribute sent by command responders.
+     */
+    private Map<String, LocalCommand> executingCommands = new ConcurrentHashMap<String, LocalCommand>();
+
+    private AdHocCommandManager(Connection connection) {
+        super();
+        this.connection = connection;
+        init();
+    }
+
+    /**
+     * Registers a new command with this command manager, which is related to a
+     * connection. The <tt>node</tt> is an unique identifier of that command for
+     * the connection related to this command manager. The <tt>name</tt> is the
+     * human readable name of the command. The <tt>class</tt> is the class of
+     * the command, which must extend {@link LocalCommand} and have a default
+     * constructor.
+     *
+     * @param node the unique identifier of the command.
+     * @param name the human readable name of the command.
+     * @param clazz the class of the command, which must extend {@link LocalCommand}.
+     */
+    public void registerCommand(String node, String name, final Class<? extends LocalCommand> clazz) {
+        registerCommand(node, name, new LocalCommandFactory() {
+            public LocalCommand getInstance() throws InstantiationException, IllegalAccessException  {
+                return clazz.newInstance();
+            }
+        });
+    }
+
+    /**
+     * Registers a new command with this command manager, which is related to a
+     * connection. The <tt>node</tt> is an unique identifier of that
+     * command for the connection related to this command manager. The <tt>name</tt>
+     * is the human readeale name of the command. The <tt>factory</tt> generates
+     * new instances of the command.
+     *
+     * @param node the unique identifier of the command.
+     * @param name the human readable name of the command.
+     * @param factory a factory to create new instances of the command.
+     */
+    public void registerCommand(String node, final String name, LocalCommandFactory factory) {
+        AdHocCommandInfo commandInfo = new AdHocCommandInfo(node, name, connection.getUser(), factory);
+
+        commands.put(node, commandInfo);
+        // Set the NodeInformationProvider that will provide information about
+        // the added command
+        ServiceDiscoveryManager.getInstanceFor(connection).setNodeInformationProvider(node,
+                new NodeInformationProvider() {
+                    public List<DiscoverItems.Item> getNodeItems() {
+                        return null;
+                    }
+
+                    public List<String> getNodeFeatures() {
+                        List<String> answer = new ArrayList<String>();
+                        answer.add(DISCO_NAMESPACE);
+                        // TODO: check if this service is provided by the
+                        // TODO: current connection.
+                        answer.add("jabber:x:data");
+                        return answer;
+                    }
+
+                    public List<DiscoverInfo.Identity> getNodeIdentities() {
+                        List<DiscoverInfo.Identity> answer = new ArrayList<DiscoverInfo.Identity>();
+                        DiscoverInfo.Identity identity = new DiscoverInfo.Identity(
+                                "automation", name, "command-node");
+                        answer.add(identity);
+                        return answer;
+                    }
+
+                    @Override
+                    public List<PacketExtension> getNodePacketExtensions() {
+                        return null;
+                    }
+
+                });
+    }
+
+    /**
+     * Discover the commands of an specific JID. The <code>jid</code> is a
+     * full JID.
+     *
+     * @param jid the full JID to retrieve the commands for.
+     * @return the discovered items.
+     * @throws XMPPException if the operation failed for some reason.
+     */
+    public DiscoverItems discoverCommands(String jid) throws XMPPException {
+        ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager
+                .getInstanceFor(connection);
+        return serviceDiscoveryManager.discoverItems(jid, discoNode);
+    }
+
+    /**
+     * Publish the commands to an specific JID.
+     *
+     * @param jid the full JID to publish the commands to.
+     * @throws XMPPException if the operation failed for some reason.
+     */
+    public void publishCommands(String jid) throws XMPPException {
+        ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager
+                .getInstanceFor(connection);
+
+        // Collects the commands to publish as items
+        DiscoverItems discoverItems = new DiscoverItems();
+        Collection<AdHocCommandInfo> xCommandsList = getRegisteredCommands();
+
+        for (AdHocCommandInfo info : xCommandsList) {
+            DiscoverItems.Item item = new DiscoverItems.Item(info.getOwnerJID());
+            item.setName(info.getName());
+            item.setNode(info.getNode());
+            discoverItems.addItem(item);
+        }
+
+        serviceDiscoveryManager.publishItems(jid, discoNode, discoverItems);
+    }
+
+    /**
+     * Returns a command that represents an instance of a command in a remote
+     * host. It is used to execute remote commands. The concept is similar to
+     * RMI. Every invocation on this command is equivalent to an invocation in
+     * the remote command.
+     *
+     * @param jid the full JID of the host of the remote command
+     * @param node the identifier of the command
+     * @return a local instance equivalent to the remote command.
+     */
+    public RemoteCommand getRemoteCommand(String jid, String node) {
+        return new RemoteCommand(connection, node, jid);
+    }
+
+    /**
+     * <ul>
+     * <li>Adds listeners to the connection</li>
+     * <li>Registers the ad-hoc command feature to the ServiceDiscoveryManager</li>
+     * <li>Registers the items of the feature</li>
+     * <li>Adds packet listeners to handle execution requests</li>
+     * <li>Creates and start the session sweeper</li>
+     * </ul>
+     */
+    private void init() {
+        // Register the new instance and associate it with the connection
+        instances.put(connection, this);
+
+        // Add a listener to the connection that removes the registered instance
+        // when the connection is closed
+        connection.addConnectionListener(new ConnectionListener() {
+            public void connectionClosed() {
+                // Unregister this instance since the connection has been closed
+                instances.remove(connection);
+            }
+
+            public void connectionClosedOnError(Exception e) {
+                // Unregister this instance since the connection has been closed
+                instances.remove(connection);
+            }
+
+            public void reconnectionSuccessful() {
+                // Register this instance since the connection has been
+                // reestablished
+                instances.put(connection, AdHocCommandManager.this);
+            }
+
+            public void reconnectingIn(int seconds) {
+                // Nothing to do
+            }
+
+            public void reconnectionFailed(Exception e) {
+                // Nothing to do
+            }
+        });
+
+        // Add the feature to the service discovery manage to show that this
+        // connection supports the AdHoc-Commands protocol.
+        // This information will be used when another client tries to
+        // discover whether this client supports AdHoc-Commands or not.
+        ServiceDiscoveryManager.getInstanceFor(connection).addFeature(
+                DISCO_NAMESPACE);
+
+        // Set the NodeInformationProvider that will provide information about
+        // which AdHoc-Commands are registered, whenever a disco request is
+        // received
+        ServiceDiscoveryManager.getInstanceFor(connection)
+                .setNodeInformationProvider(discoNode,
+                        new NodeInformationProvider() {
+                            public List<DiscoverItems.Item> getNodeItems() {
+
+                                List<DiscoverItems.Item> answer = new ArrayList<DiscoverItems.Item>();
+                                Collection<AdHocCommandInfo> commandsList = getRegisteredCommands();
+
+                                for (AdHocCommandInfo info : commandsList) {
+                                    DiscoverItems.Item item = new DiscoverItems.Item(
+                                            info.getOwnerJID());
+                                    item.setName(info.getName());
+                                    item.setNode(info.getNode());
+                                    answer.add(item);
+                                }
+
+                                return answer;
+                            }
+
+                            public List<String> getNodeFeatures() {
+                                return null;
+                            }
+
+                            public List<Identity> getNodeIdentities() {
+                                return null;
+                            }
+
+                            @Override
+                            public List<PacketExtension> getNodePacketExtensions() {
+                                return null;
+                            }
+                        });
+
+        // The packet listener and the filter for processing some AdHoc Commands
+        // Packets
+        PacketListener listener = new PacketListener() {
+            public void processPacket(Packet packet) {
+                AdHocCommandData requestData = (AdHocCommandData) packet;
+                processAdHocCommand(requestData);
+            }
+        };
+
+        PacketFilter filter = new PacketTypeFilter(AdHocCommandData.class);
+        connection.addPacketListener(listener, filter);
+
+        sessionsSweeper = null;
+    }
+
+    /**
+     * Process the AdHoc-Command packet that request the execution of some
+     * action of a command. If this is the first request, this method checks,
+     * before executing the command, if:
+     * <ul>
+     *  <li>The requested command exists</li>
+     *  <li>The requester has permissions to execute it</li>
+     *  <li>The command has more than one stage, if so, it saves the command and
+     *      session ID for further use</li>
+     * </ul>
+     * 
+     * <br>
+     * <br>
+     * If this is not the first request, this method checks, before executing
+     * the command, if:
+     * <ul>
+     *  <li>The session ID of the request was stored</li>
+     *  <li>The session life do not exceed the time out</li>
+     *  <li>The action to execute is one of the available actions</li>
+     * </ul>
+     *
+     * @param requestData
+     *            the packet to process.
+     */
+    private void processAdHocCommand(AdHocCommandData requestData) {
+        // Only process requests of type SET
+        if (requestData.getType() != IQ.Type.SET) {
+            return;
+        }
+
+        // Creates the response with the corresponding data
+        AdHocCommandData response = new AdHocCommandData();
+        response.setTo(requestData.getFrom());
+        response.setPacketID(requestData.getPacketID());
+        response.setNode(requestData.getNode());
+        response.setId(requestData.getTo());
+
+        String sessionId = requestData.getSessionID();
+        String commandNode = requestData.getNode();
+
+        if (sessionId == null) {
+            // A new execution request has been received. Check that the
+            // command exists
+            if (!commands.containsKey(commandNode)) {
+                // Requested command does not exist so return
+                // item_not_found error.
+                respondError(response, XMPPError.Condition.item_not_found);
+                return;
+            }
+
+            // Create new session ID
+            sessionId = StringUtils.randomString(15);
+
+            try {
+                // Create a new instance of the command with the
+                // corresponding sessioid
+                LocalCommand command = newInstanceOfCmd(commandNode, sessionId);
+
+                response.setType(IQ.Type.RESULT);
+                command.setData(response);
+
+                // Check that the requester has enough permission.
+                // Answer forbidden error if requester permissions are not
+                // enough to execute the requested command
+                if (!command.hasPermission(requestData.getFrom())) {
+                    respondError(response, XMPPError.Condition.forbidden);
+                    return;
+                }
+
+                Action action = requestData.getAction();
+
+                // If the action is unknown then respond an error.
+                if (action != null && action.equals(Action.unknown)) {
+                    respondError(response, XMPPError.Condition.bad_request,
+                            AdHocCommand.SpecificErrorCondition.malformedAction);
+                    return;
+                }
+
+                // If the action is not execute, then it is an invalid action.
+                if (action != null && !action.equals(Action.execute)) {
+                    respondError(response, XMPPError.Condition.bad_request,
+                            AdHocCommand.SpecificErrorCondition.badAction);
+                    return;
+                }
+
+                // Increase the state number, so the command knows in witch
+                // stage it is
+                command.incrementStage();
+                // Executes the command
+                command.execute();
+
+                if (command.isLastStage()) {
+                    // If there is only one stage then the command is completed
+                    response.setStatus(Status.completed);
+                }
+                else {
+                    // Else it is still executing, and is registered to be
+                    // available for the next call
+                    response.setStatus(Status.executing);
+                    executingCommands.put(sessionId, command);
+                    // See if the session reaping thread is started. If not, start it.
+                    if (sessionsSweeper == null) {
+                        sessionsSweeper = new Thread(new Runnable() {
+                            public void run() {
+                                while (true) {
+                                    for (String sessionId : executingCommands.keySet()) {
+                                        LocalCommand command = executingCommands.get(sessionId);
+                                        // Since the command could be removed in the meanwhile
+                                        // of getting the key and getting the value - by a
+                                        // processed packet. We must check if it still in the
+                                        // map.
+                                        if (command != null) {
+                                            long creationStamp = command.getCreationDate();
+                                            // Check if the Session data has expired (default is
+                                            // 10 minutes)
+                                            // To remove it from the session list it waits for
+                                            // the double of the of time out time. This is to
+                                            // let
+                                            // the requester know why his execution request is
+                                            // not accepted. If the session is removed just
+                                            // after the time out, then whe the user request to
+                                            // continue the execution he will recieved an
+                                            // invalid session error and not a time out error.
+                                            if (System.currentTimeMillis() - creationStamp > SESSION_TIMEOUT * 1000 * 2) {
+                                                // Remove the expired session
+                                                executingCommands.remove(sessionId);
+                                            }
+                                        }
+                                    }
+                                    try {
+                                        Thread.sleep(1000);
+                                    }
+                                    catch (InterruptedException ie) {
+                                        // Ignore.
+                                    }
+                                }
+                            }
+
+                        });
+                        sessionsSweeper.setDaemon(true);
+                        sessionsSweeper.start();
+                    }
+                }
+
+                // Sends the response packet
+                connection.sendPacket(response);
+
+            }
+            catch (XMPPException e) {
+                // If there is an exception caused by the next, complete,
+                // prev or cancel method, then that error is returned to the
+                // requester.
+                XMPPError error = e.getXMPPError();
+
+                // If the error type is cancel, then the execution is
+                // canceled therefore the status must show that, and the
+                // command be removed from the executing list.
+                if (XMPPError.Type.CANCEL.equals(error.getType())) {
+                    response.setStatus(Status.canceled);
+                    executingCommands.remove(sessionId);
+                }
+                respondError(response, error);
+                e.printStackTrace();
+            }
+        }
+        else {
+            LocalCommand command = executingCommands.get(sessionId);
+
+            // Check that a command exists for the specified sessionID
+            // This also handles if the command was removed in the meanwhile
+            // of getting the key and the value of the map.
+            if (command == null) {
+                respondError(response, XMPPError.Condition.bad_request,
+                        AdHocCommand.SpecificErrorCondition.badSessionid);
+                return;
+            }
+
+            // Check if the Session data has expired (default is 10 minutes)
+            long creationStamp = command.getCreationDate();
+            if (System.currentTimeMillis() - creationStamp > SESSION_TIMEOUT * 1000) {
+                // Remove the expired session
+                executingCommands.remove(sessionId);
+
+                // Answer a not_allowed error (session-expired)
+                respondError(response, XMPPError.Condition.not_allowed,
+                        AdHocCommand.SpecificErrorCondition.sessionExpired);
+                return;
+            }
+
+            /*
+             * Since the requester could send two requests for the same
+             * executing command i.e. the same session id, all the execution of
+             * the action must be synchronized to avoid inconsistencies.
+             */
+            synchronized (command) {
+                Action action = requestData.getAction();
+
+                // If the action is unknown the respond an error
+                if (action != null && action.equals(Action.unknown)) {
+                    respondError(response, XMPPError.Condition.bad_request,
+                            AdHocCommand.SpecificErrorCondition.malformedAction);
+                    return;
+                }
+
+                // If the user didn't specify an action or specify the execute
+                // action then follow the actual default execute action
+                if (action == null || Action.execute.equals(action)) {
+                    action = command.getExecuteAction();
+                }
+
+                // Check that the specified action was previously
+                // offered
+                if (!command.isValidAction(action)) {
+                    respondError(response, XMPPError.Condition.bad_request,
+                            AdHocCommand.SpecificErrorCondition.badAction);
+                    return;
+                }
+
+                try {
+                    // TODO: Check that all the requierd fields of the form are
+                    // TODO: filled, if not throw an exception. This will simplify the
+                    // TODO: construction of new commands
+
+                    // Since all errors were passed, the response is now a
+                    // result
+                    response.setType(IQ.Type.RESULT);
+
+                    // Set the new data to the command.
+                    command.setData(response);
+
+                    if (Action.next.equals(action)) {
+                        command.incrementStage();
+                        command.next(new Form(requestData.getForm()));
+                        if (command.isLastStage()) {
+                            // If it is the last stage then the command is
+                            // completed
+                            response.setStatus(Status.completed);
+                        }
+                        else {
+                            // Otherwise it is still executing
+                            response.setStatus(Status.executing);
+                        }
+                    }
+                    else if (Action.complete.equals(action)) {
+                        command.incrementStage();
+                        command.complete(new Form(requestData.getForm()));
+                        response.setStatus(Status.completed);
+                        // Remove the completed session
+                        executingCommands.remove(sessionId);
+                    }
+                    else if (Action.prev.equals(action)) {
+                        command.decrementStage();
+                        command.prev();
+                    }
+                    else if (Action.cancel.equals(action)) {
+                        command.cancel();
+                        response.setStatus(Status.canceled);
+                        // Remove the canceled session
+                        executingCommands.remove(sessionId);
+                    }
+
+                    connection.sendPacket(response);
+                }
+                catch (XMPPException e) {
+                    // If there is an exception caused by the next, complete,
+                    // prev or cancel method, then that error is returned to the
+                    // requester.
+                    XMPPError error = e.getXMPPError();
+
+                    // If the error type is cancel, then the execution is
+                    // canceled therefore the status must show that, and the
+                    // command be removed from the executing list.
+                    if (XMPPError.Type.CANCEL.equals(error.getType())) {
+                        response.setStatus(Status.canceled);
+                        executingCommands.remove(sessionId);
+                    }
+                    respondError(response, error);
+
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    /**
+     * Responds an error with an specific condition.
+     * 
+     * @param response the response to send.
+     * @param condition the condition of the error.
+     */
+    private void respondError(AdHocCommandData response,
+            XMPPError.Condition condition) {
+        respondError(response, new XMPPError(condition));
+    }
+
+    /**
+     * Responds an error with an specific condition.
+     * 
+     * @param response the response to send.
+     * @param condition the condition of the error.
+     * @param specificCondition the adhoc command error condition.
+     */
+    private void respondError(AdHocCommandData response, XMPPError.Condition condition,
+            AdHocCommand.SpecificErrorCondition specificCondition)
+    {
+        XMPPError error = new XMPPError(condition);
+        error.addExtension(new AdHocCommandData.SpecificError(specificCondition));
+        respondError(response, error);
+    }
+
+    /**
+     * Responds an error with an specific error.
+     * 
+     * @param response the response to send.
+     * @param error the error to send.
+     */
+    private void respondError(AdHocCommandData response, XMPPError error) {
+        response.setType(IQ.Type.ERROR);
+        response.setError(error);
+        connection.sendPacket(response);
+    }
+
+    /**
+     * Creates a new instance of a command to be used by a new execution request
+     * 
+     * @param commandNode the command node that identifies it.
+     * @param sessionID the session id of this execution.
+     * @return the command instance to execute.
+     * @throws XMPPException if there is problem creating the new instance.
+     */
+    private LocalCommand newInstanceOfCmd(String commandNode, String sessionID)
+            throws XMPPException
+    {
+        AdHocCommandInfo commandInfo = commands.get(commandNode);
+        LocalCommand command;
+        try {
+            command = (LocalCommand) commandInfo.getCommandInstance();
+            command.setSessionID(sessionID);
+            command.setName(commandInfo.getName());
+            command.setNode(commandInfo.getNode());
+        }
+        catch (InstantiationException e) {
+            e.printStackTrace();
+            throw new XMPPException(new XMPPError(
+                    XMPPError.Condition.interna_server_error));
+        }
+        catch (IllegalAccessException e) {
+            e.printStackTrace();
+            throw new XMPPException(new XMPPError(
+                    XMPPError.Condition.interna_server_error));
+        }
+        return command;
+    }
+
+    /**
+     * Returns the registered commands of this command manager, which is related
+     * to a connection.
+     * 
+     * @return the registered commands.
+     */
+    private Collection<AdHocCommandInfo> getRegisteredCommands() {
+        return commands.values();
+    }
+
+    /**
+     * Stores ad-hoc command information.
+     */
+    private static class AdHocCommandInfo {
+
+        private String node;
+        private String name;
+        private String ownerJID;
+        private LocalCommandFactory factory;
+
+        public AdHocCommandInfo(String node, String name, String ownerJID,
+                LocalCommandFactory factory)
+        {
+            this.node = node;
+            this.name = name;
+            this.ownerJID = ownerJID;
+            this.factory = factory;
+        }
+
+        public LocalCommand getCommandInstance() throws InstantiationException,
+                IllegalAccessException
+        {
+            return factory.getInstance();
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public String getNode() {
+            return node;
+        }
+
+        public String getOwnerJID() {
+            return ownerJID;
+        }
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/commands/AdHocCommandNote.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/commands/AdHocCommandNote.java
index 10dedbe..15ef4b2 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/commands/AdHocCommandNote.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/commands/AdHocCommandNote.java
@@ -1,86 +1,86 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2005-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.commands;
-
-/**
- * Notes can be added to a command execution response. A note has a type and value.
- * 
- * @author Gabriel Guardincerri
- */
-public class AdHocCommandNote {
-
-    private Type type;
-    private String value;
-
-    /**
-     * Creates a new adhoc command note with the specified type and value.
-     *
-     * @param type the type of the note.
-     * @param value the value of the note.
-     */
-    public AdHocCommandNote(Type type, String value) {
-        this.type = type;
-        this.value = value;
-    }
-
-    /**
-     * Returns the value or message of the note.
-     * 
-     * @return the value or message of the note.
-     */
-    public String getValue() {
-        return value;
-    }
-
-    /**
-     * Return the type of the note.
-     * 
-     * @return the type of the note.
-     */
-    public Type getType() {
-        return type;
-    }
-
-    /**
-     * Represents a note type.
-     */
-    public enum Type {
-
-        /**
-         * The note is informational only. This is not really an exceptional
-         * condition.
-         */
-        info,
-
-        /**
-         * The note indicates a warning. Possibly due to illogical (yet valid)
-         * data.
-         */
-        warn,
-
-        /**
-         * The note indicates an error. The text should indicate the reason for
-         * the error.
-         */
-        error
-    }
-
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2005-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.commands;
+
+/**
+ * Notes can be added to a command execution response. A note has a type and value.
+ * 
+ * @author Gabriel Guardincerri
+ */
+public class AdHocCommandNote {
+
+    private Type type;
+    private String value;
+
+    /**
+     * Creates a new adhoc command note with the specified type and value.
+     *
+     * @param type the type of the note.
+     * @param value the value of the note.
+     */
+    public AdHocCommandNote(Type type, String value) {
+        this.type = type;
+        this.value = value;
+    }
+
+    /**
+     * Returns the value or message of the note.
+     * 
+     * @return the value or message of the note.
+     */
+    public String getValue() {
+        return value;
+    }
+
+    /**
+     * Return the type of the note.
+     * 
+     * @return the type of the note.
+     */
+    public Type getType() {
+        return type;
+    }
+
+    /**
+     * Represents a note type.
+     */
+    public enum Type {
+
+        /**
+         * The note is informational only. This is not really an exceptional
+         * condition.
+         */
+        info,
+
+        /**
+         * The note indicates a warning. Possibly due to illogical (yet valid)
+         * data.
+         */
+        warn,
+
+        /**
+         * The note indicates an error. The text should indicate the reason for
+         * the error.
+         */
+        error
+    }
+
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/commands/LocalCommand.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/commands/LocalCommand.java
index 627d30e..dae1fb4 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/commands/LocalCommand.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/commands/LocalCommand.java
@@ -1,169 +1,169 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2005-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.commands;
-
-import org.jivesoftware.smackx.packet.AdHocCommandData;
-
-/**
- * Represents a command that can be executed locally from a remote location. This
- * class must be extended to implement an specific ad-hoc command. This class
- * provides some useful tools:<ul>
- *      <li>Node</li>
- *      <li>Name</li>
- *      <li>Session ID</li>
- *      <li>Current Stage</li>
- *      <li>Available actions</li>
- *      <li>Default action</li>
- * </ul><p/>
- * To implement a new command extend this class and implement all the abstract
- * methods. When implementing the actions remember that they could be invoked
- * several times, and that you must use the current stage number to know what to
- * do.
- * 
- * @author Gabriel Guardincerri
- */
-public abstract class LocalCommand extends AdHocCommand {
-
-    /**
-     * The time stamp of first invokation of the command. Used to implement the session timeout.
-     */
-    private long creationDate;
-
-    /**
-     * The unique ID of the execution of the command.
-     */
-    private String sessionID;
-
-    /**
-     * The full JID of the host of the command.
-     */
-    private String ownerJID;
-
-    /**
-     * The number of the current stage.
-     */
-    private int currenStage;
-
-    public LocalCommand() {
-        super();
-        this.creationDate = System.currentTimeMillis();
-        currenStage = -1;
-    }
-
-    /**
-     * The sessionID is an unique identifier of an execution request. This is
-     * automatically handled and should not be called.
-     * 
-     * @param sessionID the unique session id of this execution
-     */
-    public void setSessionID(String sessionID) {
-        this.sessionID = sessionID;
-        getData().setSessionID(sessionID);
-    }
-
-    /**
-     * Returns the session ID of this execution.
-     * 
-     * @return the unique session id of this execution
-     */
-    public String getSessionID() {
-        return sessionID;
-    }
-
-    /**
-     * Sets the JID of the command host. This is automatically handled and should
-     * not be called.
-     * 
-     * @param ownerJID the JID of the owner.
-     */
-    public void setOwnerJID(String ownerJID) {
-        this.ownerJID = ownerJID;
-    }
-
-    @Override
-    public String getOwnerJID() {
-        return ownerJID;
-    }
-
-    /**
-     * Returns the date the command was created.
-     * 
-     * @return the date the command was created.
-     */
-    public long getCreationDate() {
-        return creationDate;
-    }
-
-    /**
-     * Returns true if the current stage is the last one. If it is then the
-     * execution of some action will complete the execution of the command.
-     * Commands that don't have multiple stages can always return <tt>true</tt>.
-     * 
-     * @return true if the command is in the last stage.
-     */
-    public abstract boolean isLastStage();
-
-    /**
-     * Returns true if the specified requester has permission to execute all the
-     * stages of this action. This is checked when the first request is received,
-     * if the permission is grant then the requester will be able to execute
-     * all the stages of the command. It is not checked again during the
-     * execution.
-     *
-     * @param jid the JID to check permissions on.
-     * @return true if the user has permission to execute this action.
-     */
-    public abstract boolean hasPermission(String jid);
-
-    /**
-     * Returns the currently executing stage number. The first stage number is
-     * 0. During the execution of the first action this method will answer 0.
-     *
-     * @return the current stage number.
-     */
-    public int getCurrentStage() {
-        return currenStage;
-    }
-
-    @Override
-    void setData(AdHocCommandData data) {
-        data.setSessionID(sessionID);
-        super.setData(data);
-    }
-
-    /**
-     * Increase the current stage number. This is automatically handled and should
-     * not be called.
-     * 
-     */
-    void incrementStage() {
-        currenStage++;
-    }
-
-    /**
-     * Decrease the current stage number. This is automatically handled and should
-     * not be called.
-     * 
-     */
-    void decrementStage() {
-        currenStage--;
-    }
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2005-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.commands;
+
+import org.jivesoftware.smackx.packet.AdHocCommandData;
+
+/**
+ * Represents a command that can be executed locally from a remote location. This
+ * class must be extended to implement an specific ad-hoc command. This class
+ * provides some useful tools:<ul>
+ *      <li>Node</li>
+ *      <li>Name</li>
+ *      <li>Session ID</li>
+ *      <li>Current Stage</li>
+ *      <li>Available actions</li>
+ *      <li>Default action</li>
+ * </ul><p/>
+ * To implement a new command extend this class and implement all the abstract
+ * methods. When implementing the actions remember that they could be invoked
+ * several times, and that you must use the current stage number to know what to
+ * do.
+ * 
+ * @author Gabriel Guardincerri
+ */
+public abstract class LocalCommand extends AdHocCommand {
+
+    /**
+     * The time stamp of first invokation of the command. Used to implement the session timeout.
+     */
+    private long creationDate;
+
+    /**
+     * The unique ID of the execution of the command.
+     */
+    private String sessionID;
+
+    /**
+     * The full JID of the host of the command.
+     */
+    private String ownerJID;
+
+    /**
+     * The number of the current stage.
+     */
+    private int currenStage;
+
+    public LocalCommand() {
+        super();
+        this.creationDate = System.currentTimeMillis();
+        currenStage = -1;
+    }
+
+    /**
+     * The sessionID is an unique identifier of an execution request. This is
+     * automatically handled and should not be called.
+     * 
+     * @param sessionID the unique session id of this execution
+     */
+    public void setSessionID(String sessionID) {
+        this.sessionID = sessionID;
+        getData().setSessionID(sessionID);
+    }
+
+    /**
+     * Returns the session ID of this execution.
+     * 
+     * @return the unique session id of this execution
+     */
+    public String getSessionID() {
+        return sessionID;
+    }
+
+    /**
+     * Sets the JID of the command host. This is automatically handled and should
+     * not be called.
+     * 
+     * @param ownerJID the JID of the owner.
+     */
+    public void setOwnerJID(String ownerJID) {
+        this.ownerJID = ownerJID;
+    }
+
+    @Override
+    public String getOwnerJID() {
+        return ownerJID;
+    }
+
+    /**
+     * Returns the date the command was created.
+     * 
+     * @return the date the command was created.
+     */
+    public long getCreationDate() {
+        return creationDate;
+    }
+
+    /**
+     * Returns true if the current stage is the last one. If it is then the
+     * execution of some action will complete the execution of the command.
+     * Commands that don't have multiple stages can always return <tt>true</tt>.
+     * 
+     * @return true if the command is in the last stage.
+     */
+    public abstract boolean isLastStage();
+
+    /**
+     * Returns true if the specified requester has permission to execute all the
+     * stages of this action. This is checked when the first request is received,
+     * if the permission is grant then the requester will be able to execute
+     * all the stages of the command. It is not checked again during the
+     * execution.
+     *
+     * @param jid the JID to check permissions on.
+     * @return true if the user has permission to execute this action.
+     */
+    public abstract boolean hasPermission(String jid);
+
+    /**
+     * Returns the currently executing stage number. The first stage number is
+     * 0. During the execution of the first action this method will answer 0.
+     *
+     * @return the current stage number.
+     */
+    public int getCurrentStage() {
+        return currenStage;
+    }
+
+    @Override
+    void setData(AdHocCommandData data) {
+        data.setSessionID(sessionID);
+        super.setData(data);
+    }
+
+    /**
+     * Increase the current stage number. This is automatically handled and should
+     * not be called.
+     * 
+     */
+    void incrementStage() {
+        currenStage++;
+    }
+
+    /**
+     * Decrease the current stage number. This is automatically handled and should
+     * not be called.
+     * 
+     */
+    void decrementStage() {
+        currenStage--;
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java
index b840fd5..13d2c5a 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java
@@ -1,380 +1,380 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2006 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.filetransfer;
-
-import org.jivesoftware.smack.XMPPException;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * Contains the generic file information and progress related to a particular
- * file transfer.
- *
- * @author Alexander Wenckus
- *
- */
-public abstract class FileTransfer {
-
-	private String fileName;
-
-	private String filePath;
-
-	private long fileSize;
-
-	private String peer;
-
-	private Status status = Status.initial;
-
-    private final Object statusMonitor = new Object();
-
-	protected FileTransferNegotiator negotiator;
-
-	protected String streamID;
-
-	protected long amountWritten = -1;
-
-	private Error error;
-
-	private Exception exception;
-
-    /**
-     * Buffer size between input and output
-     */
-    private static final int BUFFER_SIZE = 8192;
-
-    protected FileTransfer(String peer, String streamID,
-			FileTransferNegotiator negotiator) {
-		this.peer = peer;
-		this.streamID = streamID;
-		this.negotiator = negotiator;
-	}
-
-	protected void setFileInfo(String fileName, long fileSize) {
-		this.fileName = fileName;
-		this.fileSize = fileSize;
-	}
-
-	protected void setFileInfo(String path, String fileName, long fileSize) {
-		this.filePath = path;
-		this.fileName = fileName;
-		this.fileSize = fileSize;
-	}
-
-	/**
-	 * Returns the size of the file being transfered.
-	 *
-	 * @return Returns the size of the file being transfered.
-	 */
-	public long getFileSize() {
-		return fileSize;
-	}
-
-	/**
-	 * Returns the name of the file being transfered.
-	 *
-	 * @return Returns the name of the file being transfered.
-	 */
-	public String getFileName() {
-		return fileName;
-	}
-
-	/**
-	 * Returns the local path of the file.
-	 *
-	 * @return Returns the local path of the file.
-	 */
-	public String getFilePath() {
-		return filePath;
-	}
-
-	/**
-	 * Returns the JID of the peer for this file transfer.
-	 *
-	 * @return Returns the JID of the peer for this file transfer.
-	 */
-	public String getPeer() {
-		return peer;
-	}
-
-	/**
-	 * Returns the progress of the file transfer as a number between 0 and 1.
-	 *
-	 * @return Returns the progress of the file transfer as a number between 0
-	 *         and 1.
-	 */
-	public double getProgress() {
-        if (amountWritten <= 0 || fileSize <= 0) {
-            return 0;
-        }
-        return (double) amountWritten / (double) fileSize;
-	}
-
-	/**
-	 * Returns true if the transfer has been cancelled, if it has stopped because
-	 * of a an error, or the transfer completed successfully.
-	 *
-	 * @return Returns true if the transfer has been cancelled, if it has stopped
-	 *         because of a an error, or the transfer completed successfully.
-	 */
-	public boolean isDone() {
-		return status == Status.cancelled || status == Status.error
-				|| status == Status.complete || status == Status.refused;
-	}
-
-	/**
-	 * Returns the current status of the file transfer.
-	 *
-	 * @return Returns the current status of the file transfer.
-	 */
-	public Status getStatus() {
-		return status;
-	}
-
-	protected void setError(Error type) {
-		this.error = type;
-	}
-
-	/**
-	 * When {@link #getStatus()} returns that there was an {@link Status#error}
-	 * during the transfer, the type of error can be retrieved through this
-	 * method.
-	 *
-	 * @return Returns the type of error that occurred if one has occurred.
-	 */
-	public Error getError() {
-		return error;
-	}
-
-	/**
-	 * If an exception occurs asynchronously it will be stored for later
-	 * retrieval. If there is an error there maybe an exception set.
-	 *
-	 * @return The exception that occurred or null if there was no exception.
-	 * @see #getError()
-	 */
-	public Exception getException() {
-		return exception;
-	}
-
-    public String getStreamID() {
-        return streamID;
-    }
-
-	/**
-	 * Cancels the file transfer.
-	 */
-	public abstract void cancel();
-
-	protected void setException(Exception exception) {
-		this.exception = exception;
-	}
-
-	protected void setStatus(Status status) {
-        synchronized (statusMonitor) {
-		    this.status = status;
-	    }
-    }
-
-    protected boolean updateStatus(Status oldStatus, Status newStatus) {
-        synchronized (statusMonitor) {
-            if (oldStatus != status) {
-                return false;
-            }
-            status = newStatus;
-            return true;
-        }
-    }
-
-	protected void writeToStream(final InputStream in, final OutputStream out)
-			throws XMPPException
-    {
-		final byte[] b = new byte[BUFFER_SIZE];
-		int count = 0;
-		amountWritten = 0;
-
-        do {
-			// write to the output stream
-			try {
-				out.write(b, 0, count);
-			} catch (IOException e) {
-				throw new XMPPException("error writing to output stream", e);
-			}
-
-			amountWritten += count;
-
-			// read more bytes from the input stream
-			try {
-				count = in.read(b);
-			} catch (IOException e) {
-				throw new XMPPException("error reading from input stream", e);
-			}
-		} while (count != -1 && !getStatus().equals(Status.cancelled));
-
-		// the connection was likely terminated abrubtly if these are not equal
-		if (!getStatus().equals(Status.cancelled) && getError() == Error.none
-				&& amountWritten != fileSize) {
-            setStatus(Status.error);
-			this.error = Error.connection;
-		}
-	}
-
-	/**
-	 * A class to represent the current status of the file transfer.
-	 *
-	 * @author Alexander Wenckus
-	 *
-	 */
-	public enum Status {
-
-		/**
-		 * An error occurred during the transfer.
-		 *
-		 * @see FileTransfer#getError()
-		 */
-		error("Error"),
-
-		/**
-         * The initial status of the file transfer.
-         */
-        initial("Initial"),
-
-        /**
-		 * The file transfer is being negotiated with the peer. The party
-		 * Receiving the file has the option to accept or refuse a file transfer
-		 * request. If they accept, then the process of stream negotiation will
-		 * begin. If they refuse the file will not be transfered.
-		 *
-		 * @see #negotiating_stream
-		 */
-		negotiating_transfer("Negotiating Transfer"),
-
-		/**
-		 * The peer has refused the file transfer request halting the file
-		 * transfer negotiation process.
-		 */
-		refused("Refused"),
-
-		/**
-		 * The stream to transfer the file is being negotiated over the chosen
-		 * stream type. After the stream negotiating process is complete the
-		 * status becomes negotiated.
-		 *
-		 * @see #negotiated
-		 */
-		negotiating_stream("Negotiating Stream"),
-
-		/**
-		 * After the stream negotiation has completed the intermediate state
-		 * between the time when the negotiation is finished and the actual
-		 * transfer begins.
-		 */
-		negotiated("Negotiated"),
-
-		/**
-		 * The transfer is in progress.
-		 *
-		 * @see FileTransfer#getProgress()
-		 */
-		in_progress("In Progress"),
-
-		/**
-		 * The transfer has completed successfully.
-		 */
-		complete("Complete"),
-
-		/**
-		 * The file transfer was cancelled
-		 */
-		cancelled("Cancelled");
-
-        private String status;
-
-        private Status(String status) {
-            this.status = status;
-        }
-
-        public String toString() {
-            return status;
-        }
-    }
-
-    /**
-     * Return the length of bytes written out to the stream.
-     * @return the amount in bytes written out.
-     */
-    public long getAmountWritten(){
-        return amountWritten;
-    }
-
-    public enum Error {
-		/**
-		 * No error
-		 */
-		none("No error"),
-
-		/**
-		 * The peer did not find any of the provided stream mechanisms
-		 * acceptable.
-		 */
-		not_acceptable("The peer did not find any of the provided stream mechanisms acceptable."),
-
-		/**
-		 * The provided file to transfer does not exist or could not be read.
-		 */
-		bad_file("The provided file to transfer does not exist or could not be read."),
-
-		/**
-		 * The remote user did not respond or the connection timed out.
-		 */
-		no_response("The remote user did not respond or the connection timed out."),
-
-		/**
-		 * An error occurred over the socket connected to send the file.
-		 */
-		connection("An error occured over the socket connected to send the file."),
-
-		/**
-		 * An error occurred while sending or receiving the file
-		 */
-		stream("An error occured while sending or recieving the file.");
-
-		private final String msg;
-
-		private Error(String msg) {
-			this.msg = msg;
-		}
-
-		/**
-		 * Returns a String representation of this error.
-		 *
-		 * @return Returns a String representation of this error.
-		 */
-		public String getMessage() {
-			return msg;
-		}
-
-		public String toString() {
-			return msg;
-		}
-	}
-
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2006 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.filetransfer;
+
+import org.jivesoftware.smack.XMPPException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Contains the generic file information and progress related to a particular
+ * file transfer.
+ *
+ * @author Alexander Wenckus
+ *
+ */
+public abstract class FileTransfer {
+
+	private String fileName;
+
+	private String filePath;
+
+	private long fileSize;
+
+	private String peer;
+
+	private Status status = Status.initial;
+
+    private final Object statusMonitor = new Object();
+
+	protected FileTransferNegotiator negotiator;
+
+	protected String streamID;
+
+	protected long amountWritten = -1;
+
+	private Error error;
+
+	private Exception exception;
+
+    /**
+     * Buffer size between input and output
+     */
+    private static final int BUFFER_SIZE = 8192;
+
+    protected FileTransfer(String peer, String streamID,
+			FileTransferNegotiator negotiator) {
+		this.peer = peer;
+		this.streamID = streamID;
+		this.negotiator = negotiator;
+	}
+
+	protected void setFileInfo(String fileName, long fileSize) {
+		this.fileName = fileName;
+		this.fileSize = fileSize;
+	}
+
+	protected void setFileInfo(String path, String fileName, long fileSize) {
+		this.filePath = path;
+		this.fileName = fileName;
+		this.fileSize = fileSize;
+	}
+
+	/**
+	 * Returns the size of the file being transfered.
+	 *
+	 * @return Returns the size of the file being transfered.
+	 */
+	public long getFileSize() {
+		return fileSize;
+	}
+
+	/**
+	 * Returns the name of the file being transfered.
+	 *
+	 * @return Returns the name of the file being transfered.
+	 */
+	public String getFileName() {
+		return fileName;
+	}
+
+	/**
+	 * Returns the local path of the file.
+	 *
+	 * @return Returns the local path of the file.
+	 */
+	public String getFilePath() {
+		return filePath;
+	}
+
+	/**
+	 * Returns the JID of the peer for this file transfer.
+	 *
+	 * @return Returns the JID of the peer for this file transfer.
+	 */
+	public String getPeer() {
+		return peer;
+	}
+
+	/**
+	 * Returns the progress of the file transfer as a number between 0 and 1.
+	 *
+	 * @return Returns the progress of the file transfer as a number between 0
+	 *         and 1.
+	 */
+	public double getProgress() {
+        if (amountWritten <= 0 || fileSize <= 0) {
+            return 0;
+        }
+        return (double) amountWritten / (double) fileSize;
+	}
+
+	/**
+	 * Returns true if the transfer has been cancelled, if it has stopped because
+	 * of a an error, or the transfer completed successfully.
+	 *
+	 * @return Returns true if the transfer has been cancelled, if it has stopped
+	 *         because of a an error, or the transfer completed successfully.
+	 */
+	public boolean isDone() {
+		return status == Status.cancelled || status == Status.error
+				|| status == Status.complete || status == Status.refused;
+	}
+
+	/**
+	 * Returns the current status of the file transfer.
+	 *
+	 * @return Returns the current status of the file transfer.
+	 */
+	public Status getStatus() {
+		return status;
+	}
+
+	protected void setError(Error type) {
+		this.error = type;
+	}
+
+	/**
+	 * When {@link #getStatus()} returns that there was an {@link Status#error}
+	 * during the transfer, the type of error can be retrieved through this
+	 * method.
+	 *
+	 * @return Returns the type of error that occurred if one has occurred.
+	 */
+	public Error getError() {
+		return error;
+	}
+
+	/**
+	 * If an exception occurs asynchronously it will be stored for later
+	 * retrieval. If there is an error there maybe an exception set.
+	 *
+	 * @return The exception that occurred or null if there was no exception.
+	 * @see #getError()
+	 */
+	public Exception getException() {
+		return exception;
+	}
+
+    public String getStreamID() {
+        return streamID;
+    }
+
+	/**
+	 * Cancels the file transfer.
+	 */
+	public abstract void cancel();
+
+	protected void setException(Exception exception) {
+		this.exception = exception;
+	}
+
+	protected void setStatus(Status status) {
+        synchronized (statusMonitor) {
+		    this.status = status;
+	    }
+    }
+
+    protected boolean updateStatus(Status oldStatus, Status newStatus) {
+        synchronized (statusMonitor) {
+            if (oldStatus != status) {
+                return false;
+            }
+            status = newStatus;
+            return true;
+        }
+    }
+
+	protected void writeToStream(final InputStream in, final OutputStream out)
+			throws XMPPException
+    {
+		final byte[] b = new byte[BUFFER_SIZE];
+		int count = 0;
+		amountWritten = 0;
+
+        do {
+			// write to the output stream
+			try {
+				out.write(b, 0, count);
+			} catch (IOException e) {
+				throw new XMPPException("error writing to output stream", e);
+			}
+
+			amountWritten += count;
+
+			// read more bytes from the input stream
+			try {
+				count = in.read(b);
+			} catch (IOException e) {
+				throw new XMPPException("error reading from input stream", e);
+			}
+		} while (count != -1 && !getStatus().equals(Status.cancelled));
+
+		// the connection was likely terminated abrubtly if these are not equal
+		if (!getStatus().equals(Status.cancelled) && getError() == Error.none
+				&& amountWritten != fileSize) {
+            setStatus(Status.error);
+			this.error = Error.connection;
+		}
+	}
+
+	/**
+	 * A class to represent the current status of the file transfer.
+	 *
+	 * @author Alexander Wenckus
+	 *
+	 */
+	public enum Status {
+
+		/**
+		 * An error occurred during the transfer.
+		 *
+		 * @see FileTransfer#getError()
+		 */
+		error("Error"),
+
+		/**
+         * The initial status of the file transfer.
+         */
+        initial("Initial"),
+
+        /**
+		 * The file transfer is being negotiated with the peer. The party
+		 * Receiving the file has the option to accept or refuse a file transfer
+		 * request. If they accept, then the process of stream negotiation will
+		 * begin. If they refuse the file will not be transfered.
+		 *
+		 * @see #negotiating_stream
+		 */
+		negotiating_transfer("Negotiating Transfer"),
+
+		/**
+		 * The peer has refused the file transfer request halting the file
+		 * transfer negotiation process.
+		 */
+		refused("Refused"),
+
+		/**
+		 * The stream to transfer the file is being negotiated over the chosen
+		 * stream type. After the stream negotiating process is complete the
+		 * status becomes negotiated.
+		 *
+		 * @see #negotiated
+		 */
+		negotiating_stream("Negotiating Stream"),
+
+		/**
+		 * After the stream negotiation has completed the intermediate state
+		 * between the time when the negotiation is finished and the actual
+		 * transfer begins.
+		 */
+		negotiated("Negotiated"),
+
+		/**
+		 * The transfer is in progress.
+		 *
+		 * @see FileTransfer#getProgress()
+		 */
+		in_progress("In Progress"),
+
+		/**
+		 * The transfer has completed successfully.
+		 */
+		complete("Complete"),
+
+		/**
+		 * The file transfer was cancelled
+		 */
+		cancelled("Cancelled");
+
+        private String status;
+
+        private Status(String status) {
+            this.status = status;
+        }
+
+        public String toString() {
+            return status;
+        }
+    }
+
+    /**
+     * Return the length of bytes written out to the stream.
+     * @return the amount in bytes written out.
+     */
+    public long getAmountWritten(){
+        return amountWritten;
+    }
+
+    public enum Error {
+		/**
+		 * No error
+		 */
+		none("No error"),
+
+		/**
+		 * The peer did not find any of the provided stream mechanisms
+		 * acceptable.
+		 */
+		not_acceptable("The peer did not find any of the provided stream mechanisms acceptable."),
+
+		/**
+		 * The provided file to transfer does not exist or could not be read.
+		 */
+		bad_file("The provided file to transfer does not exist or could not be read."),
+
+		/**
+		 * The remote user did not respond or the connection timed out.
+		 */
+		no_response("The remote user did not respond or the connection timed out."),
+
+		/**
+		 * An error occurred over the socket connected to send the file.
+		 */
+		connection("An error occured over the socket connected to send the file."),
+
+		/**
+		 * An error occurred while sending or receiving the file
+		 */
+		stream("An error occured while sending or recieving the file.");
+
+		private final String msg;
+
+		private Error(String msg) {
+			this.msg = msg;
+		}
+
+		/**
+		 * Returns a String representation of this error.
+		 *
+		 * @return Returns a String representation of this error.
+		 */
+		public String getMessage() {
+			return msg;
+		}
+
+		public String toString() {
+			return msg;
+		}
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferListener.java
index 8e07543..904623c 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferListener.java
@@ -1,36 +1,36 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2006 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.filetransfer;
-
-/**
- * File transfers can cause several events to be raised. These events can be
- * monitored through this interface.
- * 
- * @author Alexander Wenckus
- */
-public interface FileTransferListener {
-	/**
-	 * A request to send a file has been recieved from another user.
-	 * 
-	 * @param request
-	 *            The request from the other user.
-	 */
-	public void fileTransferRequest(final FileTransferRequest request);
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2006 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.filetransfer;
+
+/**
+ * File transfers can cause several events to be raised. These events can be
+ * monitored through this interface.
+ * 
+ * @author Alexander Wenckus
+ */
+public interface FileTransferListener {
+	/**
+	 * A request to send a file has been recieved from another user.
+	 * 
+	 * @param request
+	 *            The request from the other user.
+	 */
+	public void fileTransferRequest(final FileTransferRequest request);
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferManager.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferManager.java
index 6e413fa..493fda8 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferManager.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferManager.java
@@ -1,182 +1,182 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2006 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.filetransfer;
-
-import org.jivesoftware.smack.PacketListener;
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.filter.AndFilter;
-import org.jivesoftware.smack.filter.IQTypeFilter;
-import org.jivesoftware.smack.filter.PacketTypeFilter;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smack.packet.XMPPError;
-import org.jivesoftware.smack.util.StringUtils;
-import org.jivesoftware.smackx.packet.StreamInitiation;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * The file transfer manager class handles the sending and recieving of files.
- * To send a file invoke the {@link #createOutgoingFileTransfer(String)} method.
- * <p>
- * And to recieve a file add a file transfer listener to the manager. The
- * listener will notify you when there is a new file transfer request. To create
- * the {@link IncomingFileTransfer} object accept the transfer, or, if the
- * transfer is not desirable reject it.
- * 
- * @author Alexander Wenckus
- * 
- */
-public class FileTransferManager {
-
-	private final FileTransferNegotiator fileTransferNegotiator;
-
-	private List<FileTransferListener> listeners;
-
-	private Connection connection;
-
-	/**
-	 * Creates a file transfer manager to initiate and receive file transfers.
-	 * 
-	 * @param connection
-	 *            The Connection that the file transfers will use.
-	 */
-	public FileTransferManager(Connection connection) {
-		this.connection = connection;
-		this.fileTransferNegotiator = FileTransferNegotiator
-				.getInstanceFor(connection);
-	}
-
-	/**
-	 * Add a file transfer listener to listen to incoming file transfer
-	 * requests.
-	 * 
-	 * @param li
-	 *            The listener
-	 * @see #removeFileTransferListener(FileTransferListener)
-	 * @see FileTransferListener
-	 */
-	public void addFileTransferListener(final FileTransferListener li) {
-		if (listeners == null) {
-			initListeners();
-		}
-		synchronized (this.listeners) {
-			listeners.add(li);
-		}
-	}
-
-	private void initListeners() {
-		listeners = new ArrayList<FileTransferListener>();
-
-		connection.addPacketListener(new PacketListener() {
-			public void processPacket(Packet packet) {
-				fireNewRequest((StreamInitiation) packet);
-			}
-		}, new AndFilter(new PacketTypeFilter(StreamInitiation.class),
-				new IQTypeFilter(IQ.Type.SET)));
-	}
-
-	protected void fireNewRequest(StreamInitiation initiation) {
-		FileTransferListener[] listeners = null;
-		synchronized (this.listeners) {
-			listeners = new FileTransferListener[this.listeners.size()];
-			this.listeners.toArray(listeners);
-		}
-		FileTransferRequest request = new FileTransferRequest(this, initiation);
-		for (int i = 0; i < listeners.length; i++) {
-			listeners[i].fileTransferRequest(request);
-		}
-	}
-
-	/**
-	 * Removes a file transfer listener.
-	 * 
-	 * @param li
-	 *            The file transfer listener to be removed
-	 * @see FileTransferListener
-	 */
-	public void removeFileTransferListener(final FileTransferListener li) {
-		if (listeners == null) {
-			return;
-		}
-		synchronized (this.listeners) {
-			listeners.remove(li);
-		}
-	}
-
-	/**
-	 * Creates an OutgoingFileTransfer to send a file to another user.
-	 * 
-	 * @param userID
-	 *            The fully qualified jabber ID (i.e. full JID) with resource of the user to
-	 *            send the file to.
-	 * @return The send file object on which the negotiated transfer can be run.
-	 * @exception IllegalArgumentException if userID is null or not a full JID
-	 */
-	public OutgoingFileTransfer createOutgoingFileTransfer(String userID) {
-        if (userID == null) {
-            throw new IllegalArgumentException("userID was null");
-        }
-        // We need to create outgoing file transfers with a full JID since this method will later
-        // use XEP-0095 to negotiate the stream. This is done with IQ stanzas that need to be addressed to a full JID
-        // in order to reach an client entity.
-        else if (!StringUtils.isFullJID(userID)) {
-            throw new IllegalArgumentException("The provided user id was not a full JID (i.e. with resource part)");
-        }
-
-		return new OutgoingFileTransfer(connection.getUser(), userID,
-				fileTransferNegotiator.getNextStreamID(),
-				fileTransferNegotiator);
-	}
-
-	/**
-	 * When the file transfer request is acceptable, this method should be
-	 * invoked. It will create an IncomingFileTransfer which allows the
-	 * transmission of the file to procede.
-	 * 
-	 * @param request
-	 *            The remote request that is being accepted.
-	 * @return The IncomingFileTransfer which manages the download of the file
-	 *         from the transfer initiator.
-	 */
-	protected IncomingFileTransfer createIncomingFileTransfer(
-			FileTransferRequest request) {
-		if (request == null) {
-			throw new NullPointerException("RecieveRequest cannot be null");
-		}
-
-		IncomingFileTransfer transfer = new IncomingFileTransfer(request,
-                fileTransferNegotiator);
-		transfer.setFileInfo(request.getFileName(), request.getFileSize());
-
-		return transfer;
-	}
-
-	protected void rejectIncomingFileTransfer(FileTransferRequest request) {
-		StreamInitiation initiation = request.getStreamInitiation();
-
-		IQ rejection = FileTransferNegotiator.createIQ(
-				initiation.getPacketID(), initiation.getFrom(), initiation
-						.getTo(), IQ.Type.ERROR);
-		rejection.setError(new XMPPError(XMPPError.Condition.no_acceptable));
-		connection.sendPacket(rejection);
-	}
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2006 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.filetransfer;
+
+import org.jivesoftware.smack.PacketListener;
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.filter.AndFilter;
+import org.jivesoftware.smack.filter.IQTypeFilter;
+import org.jivesoftware.smack.filter.PacketTypeFilter;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.packet.XMPPError;
+import org.jivesoftware.smack.util.StringUtils;
+import org.jivesoftware.smackx.packet.StreamInitiation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The file transfer manager class handles the sending and recieving of files.
+ * To send a file invoke the {@link #createOutgoingFileTransfer(String)} method.
+ * <p>
+ * And to recieve a file add a file transfer listener to the manager. The
+ * listener will notify you when there is a new file transfer request. To create
+ * the {@link IncomingFileTransfer} object accept the transfer, or, if the
+ * transfer is not desirable reject it.
+ * 
+ * @author Alexander Wenckus
+ * 
+ */
+public class FileTransferManager {
+
+	private final FileTransferNegotiator fileTransferNegotiator;
+
+	private List<FileTransferListener> listeners;
+
+	private Connection connection;
+
+	/**
+	 * Creates a file transfer manager to initiate and receive file transfers.
+	 * 
+	 * @param connection
+	 *            The Connection that the file transfers will use.
+	 */
+	public FileTransferManager(Connection connection) {
+		this.connection = connection;
+		this.fileTransferNegotiator = FileTransferNegotiator
+				.getInstanceFor(connection);
+	}
+
+	/**
+	 * Add a file transfer listener to listen to incoming file transfer
+	 * requests.
+	 * 
+	 * @param li
+	 *            The listener
+	 * @see #removeFileTransferListener(FileTransferListener)
+	 * @see FileTransferListener
+	 */
+	public void addFileTransferListener(final FileTransferListener li) {
+		if (listeners == null) {
+			initListeners();
+		}
+		synchronized (this.listeners) {
+			listeners.add(li);
+		}
+	}
+
+	private void initListeners() {
+		listeners = new ArrayList<FileTransferListener>();
+
+		connection.addPacketListener(new PacketListener() {
+			public void processPacket(Packet packet) {
+				fireNewRequest((StreamInitiation) packet);
+			}
+		}, new AndFilter(new PacketTypeFilter(StreamInitiation.class),
+				new IQTypeFilter(IQ.Type.SET)));
+	}
+
+	protected void fireNewRequest(StreamInitiation initiation) {
+		FileTransferListener[] listeners = null;
+		synchronized (this.listeners) {
+			listeners = new FileTransferListener[this.listeners.size()];
+			this.listeners.toArray(listeners);
+		}
+		FileTransferRequest request = new FileTransferRequest(this, initiation);
+		for (int i = 0; i < listeners.length; i++) {
+			listeners[i].fileTransferRequest(request);
+		}
+	}
+
+	/**
+	 * Removes a file transfer listener.
+	 * 
+	 * @param li
+	 *            The file transfer listener to be removed
+	 * @see FileTransferListener
+	 */
+	public void removeFileTransferListener(final FileTransferListener li) {
+		if (listeners == null) {
+			return;
+		}
+		synchronized (this.listeners) {
+			listeners.remove(li);
+		}
+	}
+
+	/**
+	 * Creates an OutgoingFileTransfer to send a file to another user.
+	 * 
+	 * @param userID
+	 *            The fully qualified jabber ID (i.e. full JID) with resource of the user to
+	 *            send the file to.
+	 * @return The send file object on which the negotiated transfer can be run.
+	 * @exception IllegalArgumentException if userID is null or not a full JID
+	 */
+	public OutgoingFileTransfer createOutgoingFileTransfer(String userID) {
+        if (userID == null) {
+            throw new IllegalArgumentException("userID was null");
+        }
+        // We need to create outgoing file transfers with a full JID since this method will later
+        // use XEP-0095 to negotiate the stream. This is done with IQ stanzas that need to be addressed to a full JID
+        // in order to reach an client entity.
+        else if (!StringUtils.isFullJID(userID)) {
+            throw new IllegalArgumentException("The provided user id was not a full JID (i.e. with resource part)");
+        }
+
+		return new OutgoingFileTransfer(connection.getUser(), userID,
+				fileTransferNegotiator.getNextStreamID(),
+				fileTransferNegotiator);
+	}
+
+	/**
+	 * When the file transfer request is acceptable, this method should be
+	 * invoked. It will create an IncomingFileTransfer which allows the
+	 * transmission of the file to procede.
+	 * 
+	 * @param request
+	 *            The remote request that is being accepted.
+	 * @return The IncomingFileTransfer which manages the download of the file
+	 *         from the transfer initiator.
+	 */
+	protected IncomingFileTransfer createIncomingFileTransfer(
+			FileTransferRequest request) {
+		if (request == null) {
+			throw new NullPointerException("RecieveRequest cannot be null");
+		}
+
+		IncomingFileTransfer transfer = new IncomingFileTransfer(request,
+                fileTransferNegotiator);
+		transfer.setFileInfo(request.getFileName(), request.getFileSize());
+
+		return transfer;
+	}
+
+	protected void rejectIncomingFileTransfer(FileTransferRequest request) {
+		StreamInitiation initiation = request.getStreamInitiation();
+
+		IQ rejection = FileTransferNegotiator.createIQ(
+				initiation.getPacketID(), initiation.getFrom(), initiation
+						.getTo(), IQ.Type.ERROR);
+		rejection.setError(new XMPPError(XMPPError.Condition.no_acceptable));
+		connection.sendPacket(rejection);
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java
index d1fb7bf..3b2b30d 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java
@@ -1,485 +1,485 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2006 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.filetransfer;
-
-import java.net.URLConnection;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.ConnectionListener;
-import org.jivesoftware.smack.PacketCollector;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.filter.PacketIDFilter;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smack.packet.XMPPError;
-import org.jivesoftware.smackx.Form;
-import org.jivesoftware.smackx.FormField;
-import org.jivesoftware.smackx.ServiceDiscoveryManager;
-import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
-import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager;
-import org.jivesoftware.smackx.packet.DataForm;
-import org.jivesoftware.smackx.packet.StreamInitiation;
-
-/**
- * Manages the negotiation of file transfers according to JEP-0096. If a file is
- * being sent the remote user chooses the type of stream under which the file
- * will be sent.
- *
- * @author Alexander Wenckus
- * @see <a href="http://xmpp.org/extensions/xep-0096.html">XEP-0096: SI File Transfer</a>
- */
-public class FileTransferNegotiator {
-
-    // Static
-
-    private static final String[] NAMESPACE = {
-            "http://jabber.org/protocol/si/profile/file-transfer",
-            "http://jabber.org/protocol/si"};
-
-    private static final Map<Connection, FileTransferNegotiator> transferObject =
-            new ConcurrentHashMap<Connection, FileTransferNegotiator>();
-
-    private static final String STREAM_INIT_PREFIX = "jsi_";
-
-    protected static final String STREAM_DATA_FIELD_NAME = "stream-method";
-
-    private static final Random randomGenerator = new Random();
-
-    /**
-     * A static variable to use only offer IBB for file transfer. It is generally recommend to only
-     * set this variable to true for testing purposes as IBB is the backup file transfer method
-     * and shouldn't be used as the only transfer method in production systems.
-     */
-    public static boolean IBB_ONLY = (System.getProperty("ibb") != null);//true;
-
-    /**
-     * Returns the file transfer negotiator related to a particular connection.
-     * When this class is requested on a particular connection the file transfer
-     * service is automatically enabled.
-     *
-     * @param connection The connection for which the transfer manager is desired
-     * @return The IMFileTransferManager
-     */
-    public static FileTransferNegotiator getInstanceFor(
-            final Connection connection) {
-        if (connection == null) {
-            throw new IllegalArgumentException("Connection cannot be null");
-        }
-        if (!connection.isConnected()) {
-            return null;
-        }
-
-        if (transferObject.containsKey(connection)) {
-            return transferObject.get(connection);
-        }
-        else {
-            FileTransferNegotiator transfer = new FileTransferNegotiator(
-                    connection);
-            setServiceEnabled(connection, true);
-            transferObject.put(connection, transfer);
-            return transfer;
-        }
-    }
-
-    /**
-     * Enable the Jabber services related to file transfer on the particular
-     * connection.
-     *
-     * @param connection The connection on which to enable or disable the services.
-     * @param isEnabled  True to enable, false to disable.
-     */
-    public static void setServiceEnabled(final Connection connection,
-            final boolean isEnabled) {
-        ServiceDiscoveryManager manager = ServiceDiscoveryManager
-                .getInstanceFor(connection);
-
-        List<String> namespaces = new ArrayList<String>();
-        namespaces.addAll(Arrays.asList(NAMESPACE));
-        namespaces.add(InBandBytestreamManager.NAMESPACE);
-        if (!IBB_ONLY) {
-            namespaces.add(Socks5BytestreamManager.NAMESPACE);
-        }
-
-        for (String namespace : namespaces) {
-            if (isEnabled) {
-                if (!manager.includesFeature(namespace)) {
-                    manager.addFeature(namespace);
-                }
-            } else {
-                manager.removeFeature(namespace);
-            }
-        }
-        
-    }
-
-    /**
-     * Checks to see if all file transfer related services are enabled on the
-     * connection.
-     *
-     * @param connection The connection to check
-     * @return True if all related services are enabled, false if they are not.
-     */
-    public static boolean isServiceEnabled(final Connection connection) {
-        ServiceDiscoveryManager manager = ServiceDiscoveryManager
-                .getInstanceFor(connection);
-
-        List<String> namespaces = new ArrayList<String>();
-        namespaces.addAll(Arrays.asList(NAMESPACE));
-        namespaces.add(InBandBytestreamManager.NAMESPACE);
-        if (!IBB_ONLY) {
-            namespaces.add(Socks5BytestreamManager.NAMESPACE);
-        }
-
-        for (String namespace : namespaces) {
-            if (!manager.includesFeature(namespace)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * A convenience method to create an IQ packet.
-     *
-     * @param ID   The packet ID of the
-     * @param to   To whom the packet is addressed.
-     * @param from From whom the packet is sent.
-     * @param type The IQ type of the packet.
-     * @return The created IQ packet.
-     */
-    public static IQ createIQ(final String ID, final String to,
-            final String from, final IQ.Type type) {
-        IQ iqPacket = new IQ() {
-            public String getChildElementXML() {
-                return null;
-            }
-        };
-        iqPacket.setPacketID(ID);
-        iqPacket.setTo(to);
-        iqPacket.setFrom(from);
-        iqPacket.setType(type);
-
-        return iqPacket;
-    }
-
-    /**
-     * Returns a collection of the supported transfer protocols.
-     *
-     * @return Returns a collection of the supported transfer protocols.
-     */
-    public static Collection<String> getSupportedProtocols() {
-        List<String> protocols = new ArrayList<String>();
-        protocols.add(InBandBytestreamManager.NAMESPACE);
-        if (!IBB_ONLY) {
-            protocols.add(Socks5BytestreamManager.NAMESPACE);
-        }
-        return Collections.unmodifiableList(protocols);
-    }
-
-    // non-static
-
-    private final Connection connection;
-
-    private final StreamNegotiator byteStreamTransferManager;
-
-    private final StreamNegotiator inbandTransferManager;
-
-    private FileTransferNegotiator(final Connection connection) {
-        configureConnection(connection);
-
-        this.connection = connection;
-        byteStreamTransferManager = new Socks5TransferNegotiator(connection);
-        inbandTransferManager = new IBBTransferNegotiator(connection);
-    }
-
-    private void configureConnection(final Connection connection) {
-        connection.addConnectionListener(new ConnectionListener() {
-            public void connectionClosed() {
-                cleanup(connection);
-            }
-
-            public void connectionClosedOnError(Exception e) {
-                cleanup(connection);
-            }
-
-            public void reconnectionFailed(Exception e) {
-                // ignore
-            }
-
-            public void reconnectionSuccessful() {
-                // ignore
-            }
-
-            public void reconnectingIn(int seconds) {
-                // ignore
-            }
-        });
-    }
-
-    private void cleanup(final Connection connection) {
-        if (transferObject.remove(connection) != null) {
-            inbandTransferManager.cleanup();
-        }
-    }
-
-    /**
-     * Selects an appropriate stream negotiator after examining the incoming file transfer request.
-     *
-     * @param request The related file transfer request.
-     * @return The file transfer object that handles the transfer
-     * @throws XMPPException If there are either no stream methods contained in the packet, or
-     *                       there is not an appropriate stream method.
-     */
-    public StreamNegotiator selectStreamNegotiator(
-            FileTransferRequest request) throws XMPPException {
-        StreamInitiation si = request.getStreamInitiation();
-        FormField streamMethodField = getStreamMethodField(si
-                .getFeatureNegotiationForm());
-
-        if (streamMethodField == null) {
-            String errorMessage = "No stream methods contained in packet.";
-            XMPPError error = new XMPPError(XMPPError.Condition.bad_request, errorMessage);
-            IQ iqPacket = createIQ(si.getPacketID(), si.getFrom(), si.getTo(),
-                    IQ.Type.ERROR);
-            iqPacket.setError(error);
-            connection.sendPacket(iqPacket);
-            throw new XMPPException(errorMessage, error);
-        }
-
-        // select the appropriate protocol
-
-        StreamNegotiator selectedStreamNegotiator;
-        try {
-            selectedStreamNegotiator = getNegotiator(streamMethodField);
-        }
-        catch (XMPPException e) {
-            IQ iqPacket = createIQ(si.getPacketID(), si.getFrom(), si.getTo(),
-                    IQ.Type.ERROR);
-            iqPacket.setError(e.getXMPPError());
-            connection.sendPacket(iqPacket);
-            throw e;
-        }
-
-        // return the appropriate negotiator
-
-        return selectedStreamNegotiator;
-    }
-
-    private FormField getStreamMethodField(DataForm form) {
-        FormField field = null;
-        for (Iterator<FormField> it = form.getFields(); it.hasNext();) {
-            field = it.next();
-            if (field.getVariable().equals(STREAM_DATA_FIELD_NAME)) {
-                break;
-            }
-            field = null;
-        }
-        return field;
-    }
-
-    private StreamNegotiator getNegotiator(final FormField field)
-            throws XMPPException {
-        String variable;
-        boolean isByteStream = false;
-        boolean isIBB = false;
-        for (Iterator<FormField.Option> it = field.getOptions(); it.hasNext();) {
-            variable = it.next().getValue();
-            if (variable.equals(Socks5BytestreamManager.NAMESPACE) && !IBB_ONLY) {
-                isByteStream = true;
-            }
-            else if (variable.equals(InBandBytestreamManager.NAMESPACE)) {
-                isIBB = true;
-            }
-        }
-
-        if (!isByteStream && !isIBB) {
-            XMPPError error = new XMPPError(XMPPError.Condition.bad_request,
-                    "No acceptable transfer mechanism");
-            throw new XMPPException(error.getMessage(), error);
-        }
-
-       //if (isByteStream && isIBB && field.getType().equals(FormField.TYPE_LIST_MULTI)) {
-        if (isByteStream && isIBB) { 
-            return new FaultTolerantNegotiator(connection,
-                    byteStreamTransferManager,
-                    inbandTransferManager);
-        }
-        else if (isByteStream) {
-            return byteStreamTransferManager;
-        }
-        else {
-            return inbandTransferManager;
-        }
-    }
-
-    /**
-     * Reject a stream initiation request from a remote user.
-     *
-     * @param si The Stream Initiation request to reject.
-     */
-    public void rejectStream(final StreamInitiation si) {
-        XMPPError error = new XMPPError(XMPPError.Condition.forbidden, "Offer Declined");
-        IQ iqPacket = createIQ(si.getPacketID(), si.getFrom(), si.getTo(),
-                IQ.Type.ERROR);
-        iqPacket.setError(error);
-        connection.sendPacket(iqPacket);
-    }
-
-    /**
-     * Returns a new, unique, stream ID to identify a file transfer.
-     *
-     * @return Returns a new, unique, stream ID to identify a file transfer.
-     */
-    public String getNextStreamID() {
-        StringBuilder buffer = new StringBuilder();
-        buffer.append(STREAM_INIT_PREFIX);
-        buffer.append(Math.abs(randomGenerator.nextLong()));
-
-        return buffer.toString();
-    }
-
-    /**
-     * Send a request to another user to send them a file. The other user has
-     * the option of, accepting, rejecting, or not responding to a received file
-     * transfer request.
-     * <p/>
-     * If they accept, the packet will contain the other user's chosen stream
-     * type to send the file across. The two choices this implementation
-     * provides to the other user for file transfer are <a
-     * href="http://www.jabber.org/jeps/jep-0065.html">SOCKS5 Bytestreams</a>,
-     * which is the preferred method of transfer, and <a
-     * href="http://www.jabber.org/jeps/jep-0047.html">In-Band Bytestreams</a>,
-     * which is the fallback mechanism.
-     * <p/>
-     * The other user may choose to decline the file request if they do not
-     * desire the file, their client does not support JEP-0096, or if there are
-     * no acceptable means to transfer the file.
-     * <p/>
-     * Finally, if the other user does not respond this method will return null
-     * after the specified timeout.
-     *
-     * @param userID          The userID of the user to whom the file will be sent.
-     * @param streamID        The unique identifier for this file transfer.
-     * @param fileName        The name of this file. Preferably it should include an
-     *                        extension as it is used to determine what type of file it is.
-     * @param size            The size, in bytes, of the file.
-     * @param desc            A description of the file.
-     * @param responseTimeout The amount of time, in milliseconds, to wait for the remote
-     *                        user to respond. If they do not respond in time, this
-     * @return Returns the stream negotiator selected by the peer.
-     * @throws XMPPException Thrown if there is an error negotiating the file transfer.
-     */
-    public StreamNegotiator negotiateOutgoingTransfer(final String userID,
-            final String streamID, final String fileName, final long size,
-            final String desc, int responseTimeout) throws XMPPException {
-        StreamInitiation si = new StreamInitiation();
-        si.setSesssionID(streamID);
-        si.setMimeType(URLConnection.guessContentTypeFromName(fileName));
-
-        StreamInitiation.File siFile = new StreamInitiation.File(fileName, size);
-        siFile.setDesc(desc);
-        si.setFile(siFile);
-
-        si.setFeatureNegotiationForm(createDefaultInitiationForm());
-
-        si.setFrom(connection.getUser());
-        si.setTo(userID);
-        si.setType(IQ.Type.SET);
-
-        PacketCollector collector = connection
-                .createPacketCollector(new PacketIDFilter(si.getPacketID()));
-        connection.sendPacket(si);
-        Packet siResponse = collector.nextResult(responseTimeout);
-        collector.cancel();
-
-        if (siResponse instanceof IQ) {
-            IQ iqResponse = (IQ) siResponse;
-            if (iqResponse.getType().equals(IQ.Type.RESULT)) {
-                StreamInitiation response = (StreamInitiation) siResponse;
-                return getOutgoingNegotiator(getStreamMethodField(response
-                        .getFeatureNegotiationForm()));
-
-            }
-            else if (iqResponse.getType().equals(IQ.Type.ERROR)) {
-                throw new XMPPException(iqResponse.getError());
-            }
-            else {
-                throw new XMPPException("File transfer response unreadable");
-            }
-        }
-        else {
-            return null;
-        }
-    }
-
-    private StreamNegotiator getOutgoingNegotiator(final FormField field)
-            throws XMPPException {
-        String variable;
-        boolean isByteStream = false;
-        boolean isIBB = false;
-        for (Iterator<String> it = field.getValues(); it.hasNext();) {
-            variable = it.next();
-            if (variable.equals(Socks5BytestreamManager.NAMESPACE) && !IBB_ONLY) {
-                isByteStream = true;
-            }
-            else if (variable.equals(InBandBytestreamManager.NAMESPACE)) {
-                isIBB = true;
-            }
-        }
-
-        if (!isByteStream && !isIBB) {
-            XMPPError error = new XMPPError(XMPPError.Condition.bad_request,
-                    "No acceptable transfer mechanism");
-            throw new XMPPException(error.getMessage(), error);
-        }
-
-        if (isByteStream && isIBB) {
-            return new FaultTolerantNegotiator(connection,
-                    byteStreamTransferManager, inbandTransferManager);
-        }
-        else if (isByteStream) {
-            return byteStreamTransferManager;
-        }
-        else {
-            return inbandTransferManager;
-        }
-    }
-
-    private DataForm createDefaultInitiationForm() {
-        DataForm form = new DataForm(Form.TYPE_FORM);
-        FormField field = new FormField(STREAM_DATA_FIELD_NAME);
-        field.setType(FormField.TYPE_LIST_SINGLE);
-        if (!IBB_ONLY) {
-            field.addOption(new FormField.Option(Socks5BytestreamManager.NAMESPACE));
-        }
-        field.addOption(new FormField.Option(InBandBytestreamManager.NAMESPACE));
-        form.addField(field);
-        return form;
-    }
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2006 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.filetransfer;
+
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.ConnectionListener;
+import org.jivesoftware.smack.PacketCollector;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.filter.PacketIDFilter;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.packet.XMPPError;
+import org.jivesoftware.smackx.Form;
+import org.jivesoftware.smackx.FormField;
+import org.jivesoftware.smackx.ServiceDiscoveryManager;
+import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
+import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager;
+import org.jivesoftware.smackx.packet.DataForm;
+import org.jivesoftware.smackx.packet.StreamInitiation;
+
+/**
+ * Manages the negotiation of file transfers according to JEP-0096. If a file is
+ * being sent the remote user chooses the type of stream under which the file
+ * will be sent.
+ *
+ * @author Alexander Wenckus
+ * @see <a href="http://xmpp.org/extensions/xep-0096.html">XEP-0096: SI File Transfer</a>
+ */
+public class FileTransferNegotiator {
+
+    // Static
+
+    private static final String[] NAMESPACE = {
+            "http://jabber.org/protocol/si/profile/file-transfer",
+            "http://jabber.org/protocol/si"};
+
+    private static final Map<Connection, FileTransferNegotiator> transferObject =
+            new ConcurrentHashMap<Connection, FileTransferNegotiator>();
+
+    private static final String STREAM_INIT_PREFIX = "jsi_";
+
+    protected static final String STREAM_DATA_FIELD_NAME = "stream-method";
+
+    private static final Random randomGenerator = new Random();
+
+    /**
+     * A static variable to use only offer IBB for file transfer. It is generally recommend to only
+     * set this variable to true for testing purposes as IBB is the backup file transfer method
+     * and shouldn't be used as the only transfer method in production systems.
+     */
+    public static boolean IBB_ONLY = (System.getProperty("ibb") != null);//true;
+
+    /**
+     * Returns the file transfer negotiator related to a particular connection.
+     * When this class is requested on a particular connection the file transfer
+     * service is automatically enabled.
+     *
+     * @param connection The connection for which the transfer manager is desired
+     * @return The IMFileTransferManager
+     */
+    public static FileTransferNegotiator getInstanceFor(
+            final Connection connection) {
+        if (connection == null) {
+            throw new IllegalArgumentException("Connection cannot be null");
+        }
+        if (!connection.isConnected()) {
+            return null;
+        }
+
+        if (transferObject.containsKey(connection)) {
+            return transferObject.get(connection);
+        }
+        else {
+            FileTransferNegotiator transfer = new FileTransferNegotiator(
+                    connection);
+            setServiceEnabled(connection, true);
+            transferObject.put(connection, transfer);
+            return transfer;
+        }
+    }
+
+    /**
+     * Enable the Jabber services related to file transfer on the particular
+     * connection.
+     *
+     * @param connection The connection on which to enable or disable the services.
+     * @param isEnabled  True to enable, false to disable.
+     */
+    public static void setServiceEnabled(final Connection connection,
+            final boolean isEnabled) {
+        ServiceDiscoveryManager manager = ServiceDiscoveryManager
+                .getInstanceFor(connection);
+
+        List<String> namespaces = new ArrayList<String>();
+        namespaces.addAll(Arrays.asList(NAMESPACE));
+        namespaces.add(InBandBytestreamManager.NAMESPACE);
+        if (!IBB_ONLY) {
+            namespaces.add(Socks5BytestreamManager.NAMESPACE);
+        }
+
+        for (String namespace : namespaces) {
+            if (isEnabled) {
+                if (!manager.includesFeature(namespace)) {
+                    manager.addFeature(namespace);
+                }
+            } else {
+                manager.removeFeature(namespace);
+            }
+        }
+        
+    }
+
+    /**
+     * Checks to see if all file transfer related services are enabled on the
+     * connection.
+     *
+     * @param connection The connection to check
+     * @return True if all related services are enabled, false if they are not.
+     */
+    public static boolean isServiceEnabled(final Connection connection) {
+        ServiceDiscoveryManager manager = ServiceDiscoveryManager
+                .getInstanceFor(connection);
+
+        List<String> namespaces = new ArrayList<String>();
+        namespaces.addAll(Arrays.asList(NAMESPACE));
+        namespaces.add(InBandBytestreamManager.NAMESPACE);
+        if (!IBB_ONLY) {
+            namespaces.add(Socks5BytestreamManager.NAMESPACE);
+        }
+
+        for (String namespace : namespaces) {
+            if (!manager.includesFeature(namespace)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * A convenience method to create an IQ packet.
+     *
+     * @param ID   The packet ID of the
+     * @param to   To whom the packet is addressed.
+     * @param from From whom the packet is sent.
+     * @param type The IQ type of the packet.
+     * @return The created IQ packet.
+     */
+    public static IQ createIQ(final String ID, final String to,
+            final String from, final IQ.Type type) {
+        IQ iqPacket = new IQ() {
+            public String getChildElementXML() {
+                return null;
+            }
+        };
+        iqPacket.setPacketID(ID);
+        iqPacket.setTo(to);
+        iqPacket.setFrom(from);
+        iqPacket.setType(type);
+
+        return iqPacket;
+    }
+
+    /**
+     * Returns a collection of the supported transfer protocols.
+     *
+     * @return Returns a collection of the supported transfer protocols.
+     */
+    public static Collection<String> getSupportedProtocols() {
+        List<String> protocols = new ArrayList<String>();
+        protocols.add(InBandBytestreamManager.NAMESPACE);
+        if (!IBB_ONLY) {
+            protocols.add(Socks5BytestreamManager.NAMESPACE);
+        }
+        return Collections.unmodifiableList(protocols);
+    }
+
+    // non-static
+
+    private final Connection connection;
+
+    private final StreamNegotiator byteStreamTransferManager;
+
+    private final StreamNegotiator inbandTransferManager;
+
+    private FileTransferNegotiator(final Connection connection) {
+        configureConnection(connection);
+
+        this.connection = connection;
+        byteStreamTransferManager = new Socks5TransferNegotiator(connection);
+        inbandTransferManager = new IBBTransferNegotiator(connection);
+    }
+
+    private void configureConnection(final Connection connection) {
+        connection.addConnectionListener(new ConnectionListener() {
+            public void connectionClosed() {
+                cleanup(connection);
+            }
+
+            public void connectionClosedOnError(Exception e) {
+                cleanup(connection);
+            }
+
+            public void reconnectionFailed(Exception e) {
+                // ignore
+            }
+
+            public void reconnectionSuccessful() {
+                // ignore
+            }
+
+            public void reconnectingIn(int seconds) {
+                // ignore
+            }
+        });
+    }
+
+    private void cleanup(final Connection connection) {
+        if (transferObject.remove(connection) != null) {
+            inbandTransferManager.cleanup();
+        }
+    }
+
+    /**
+     * Selects an appropriate stream negotiator after examining the incoming file transfer request.
+     *
+     * @param request The related file transfer request.
+     * @return The file transfer object that handles the transfer
+     * @throws XMPPException If there are either no stream methods contained in the packet, or
+     *                       there is not an appropriate stream method.
+     */
+    public StreamNegotiator selectStreamNegotiator(
+            FileTransferRequest request) throws XMPPException {
+        StreamInitiation si = request.getStreamInitiation();
+        FormField streamMethodField = getStreamMethodField(si
+                .getFeatureNegotiationForm());
+
+        if (streamMethodField == null) {
+            String errorMessage = "No stream methods contained in packet.";
+            XMPPError error = new XMPPError(XMPPError.Condition.bad_request, errorMessage);
+            IQ iqPacket = createIQ(si.getPacketID(), si.getFrom(), si.getTo(),
+                    IQ.Type.ERROR);
+            iqPacket.setError(error);
+            connection.sendPacket(iqPacket);
+            throw new XMPPException(errorMessage, error);
+        }
+
+        // select the appropriate protocol
+
+        StreamNegotiator selectedStreamNegotiator;
+        try {
+            selectedStreamNegotiator = getNegotiator(streamMethodField);
+        }
+        catch (XMPPException e) {
+            IQ iqPacket = createIQ(si.getPacketID(), si.getFrom(), si.getTo(),
+                    IQ.Type.ERROR);
+            iqPacket.setError(e.getXMPPError());
+            connection.sendPacket(iqPacket);
+            throw e;
+        }
+
+        // return the appropriate negotiator
+
+        return selectedStreamNegotiator;
+    }
+
+    private FormField getStreamMethodField(DataForm form) {
+        FormField field = null;
+        for (Iterator<FormField> it = form.getFields(); it.hasNext();) {
+            field = it.next();
+            if (field.getVariable().equals(STREAM_DATA_FIELD_NAME)) {
+                break;
+            }
+            field = null;
+        }
+        return field;
+    }
+
+    private StreamNegotiator getNegotiator(final FormField field)
+            throws XMPPException {
+        String variable;
+        boolean isByteStream = false;
+        boolean isIBB = false;
+        for (Iterator<FormField.Option> it = field.getOptions(); it.hasNext();) {
+            variable = it.next().getValue();
+            if (variable.equals(Socks5BytestreamManager.NAMESPACE) && !IBB_ONLY) {
+                isByteStream = true;
+            }
+            else if (variable.equals(InBandBytestreamManager.NAMESPACE)) {
+                isIBB = true;
+            }
+        }
+
+        if (!isByteStream && !isIBB) {
+            XMPPError error = new XMPPError(XMPPError.Condition.bad_request,
+                    "No acceptable transfer mechanism");
+            throw new XMPPException(error.getMessage(), error);
+        }
+
+       //if (isByteStream && isIBB && field.getType().equals(FormField.TYPE_LIST_MULTI)) {
+        if (isByteStream && isIBB) { 
+            return new FaultTolerantNegotiator(connection,
+                    byteStreamTransferManager,
+                    inbandTransferManager);
+        }
+        else if (isByteStream) {
+            return byteStreamTransferManager;
+        }
+        else {
+            return inbandTransferManager;
+        }
+    }
+
+    /**
+     * Reject a stream initiation request from a remote user.
+     *
+     * @param si The Stream Initiation request to reject.
+     */
+    public void rejectStream(final StreamInitiation si) {
+        XMPPError error = new XMPPError(XMPPError.Condition.forbidden, "Offer Declined");
+        IQ iqPacket = createIQ(si.getPacketID(), si.getFrom(), si.getTo(),
+                IQ.Type.ERROR);
+        iqPacket.setError(error);
+        connection.sendPacket(iqPacket);
+    }
+
+    /**
+     * Returns a new, unique, stream ID to identify a file transfer.
+     *
+     * @return Returns a new, unique, stream ID to identify a file transfer.
+     */
+    public String getNextStreamID() {
+        StringBuilder buffer = new StringBuilder();
+        buffer.append(STREAM_INIT_PREFIX);
+        buffer.append(Math.abs(randomGenerator.nextLong()));
+
+        return buffer.toString();
+    }
+
+    /**
+     * Send a request to another user to send them a file. The other user has
+     * the option of, accepting, rejecting, or not responding to a received file
+     * transfer request.
+     * <p/>
+     * If they accept, the packet will contain the other user's chosen stream
+     * type to send the file across. The two choices this implementation
+     * provides to the other user for file transfer are <a
+     * href="http://www.jabber.org/jeps/jep-0065.html">SOCKS5 Bytestreams</a>,
+     * which is the preferred method of transfer, and <a
+     * href="http://www.jabber.org/jeps/jep-0047.html">In-Band Bytestreams</a>,
+     * which is the fallback mechanism.
+     * <p/>
+     * The other user may choose to decline the file request if they do not
+     * desire the file, their client does not support JEP-0096, or if there are
+     * no acceptable means to transfer the file.
+     * <p/>
+     * Finally, if the other user does not respond this method will return null
+     * after the specified timeout.
+     *
+     * @param userID          The userID of the user to whom the file will be sent.
+     * @param streamID        The unique identifier for this file transfer.
+     * @param fileName        The name of this file. Preferably it should include an
+     *                        extension as it is used to determine what type of file it is.
+     * @param size            The size, in bytes, of the file.
+     * @param desc            A description of the file.
+     * @param responseTimeout The amount of time, in milliseconds, to wait for the remote
+     *                        user to respond. If they do not respond in time, this
+     * @return Returns the stream negotiator selected by the peer.
+     * @throws XMPPException Thrown if there is an error negotiating the file transfer.
+     */
+    public StreamNegotiator negotiateOutgoingTransfer(final String userID,
+            final String streamID, final String fileName, final long size,
+            final String desc, int responseTimeout) throws XMPPException {
+        StreamInitiation si = new StreamInitiation();
+        si.setSesssionID(streamID);
+        si.setMimeType(URLConnection.guessContentTypeFromName(fileName));
+
+        StreamInitiation.File siFile = new StreamInitiation.File(fileName, size);
+        siFile.setDesc(desc);
+        si.setFile(siFile);
+
+        si.setFeatureNegotiationForm(createDefaultInitiationForm());
+
+        si.setFrom(connection.getUser());
+        si.setTo(userID);
+        si.setType(IQ.Type.SET);
+
+        PacketCollector collector = connection
+                .createPacketCollector(new PacketIDFilter(si.getPacketID()));
+        connection.sendPacket(si);
+        Packet siResponse = collector.nextResult(responseTimeout);
+        collector.cancel();
+
+        if (siResponse instanceof IQ) {
+            IQ iqResponse = (IQ) siResponse;
+            if (iqResponse.getType().equals(IQ.Type.RESULT)) {
+                StreamInitiation response = (StreamInitiation) siResponse;
+                return getOutgoingNegotiator(getStreamMethodField(response
+                        .getFeatureNegotiationForm()));
+
+            }
+            else if (iqResponse.getType().equals(IQ.Type.ERROR)) {
+                throw new XMPPException(iqResponse.getError());
+            }
+            else {
+                throw new XMPPException("File transfer response unreadable");
+            }
+        }
+        else {
+            return null;
+        }
+    }
+
+    private StreamNegotiator getOutgoingNegotiator(final FormField field)
+            throws XMPPException {
+        String variable;
+        boolean isByteStream = false;
+        boolean isIBB = false;
+        for (Iterator<String> it = field.getValues(); it.hasNext();) {
+            variable = it.next();
+            if (variable.equals(Socks5BytestreamManager.NAMESPACE) && !IBB_ONLY) {
+                isByteStream = true;
+            }
+            else if (variable.equals(InBandBytestreamManager.NAMESPACE)) {
+                isIBB = true;
+            }
+        }
+
+        if (!isByteStream && !isIBB) {
+            XMPPError error = new XMPPError(XMPPError.Condition.bad_request,
+                    "No acceptable transfer mechanism");
+            throw new XMPPException(error.getMessage(), error);
+        }
+
+        if (isByteStream && isIBB) {
+            return new FaultTolerantNegotiator(connection,
+                    byteStreamTransferManager, inbandTransferManager);
+        }
+        else if (isByteStream) {
+            return byteStreamTransferManager;
+        }
+        else {
+            return inbandTransferManager;
+        }
+    }
+
+    private DataForm createDefaultInitiationForm() {
+        DataForm form = new DataForm(Form.TYPE_FORM);
+        FormField field = new FormField(STREAM_DATA_FIELD_NAME);
+        field.setType(FormField.TYPE_LIST_SINGLE);
+        if (!IBB_ONLY) {
+            field.addOption(new FormField.Option(Socks5BytestreamManager.NAMESPACE));
+        }
+        field.addOption(new FormField.Option(InBandBytestreamManager.NAMESPACE));
+        form.addField(field);
+        return form;
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferRequest.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferRequest.java
index 6b5ccd8..69a073f 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferRequest.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferRequest.java
@@ -1,138 +1,138 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2006 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.filetransfer;
-
-import org.jivesoftware.smackx.packet.StreamInitiation;
-
-/**
- * A request to send a file recieved from another user.
- * 
- * @author Alexander Wenckus
- * 
- */
-public class FileTransferRequest {
-	private final StreamInitiation streamInitiation;
-
-	private final FileTransferManager manager;
-
-	/**
-	 * A recieve request is constructed from the Stream Initiation request
-	 * received from the initator.
-	 * 
-	 * @param manager
-	 *            The manager handling this file transfer
-	 * 
-	 * @param si
-	 *            The Stream initiaton recieved from the initiator.
-	 */
-	public FileTransferRequest(FileTransferManager manager, StreamInitiation si) {
-		this.streamInitiation = si;
-		this.manager = manager;
-	}
-
-	/**
-	 * Returns the name of the file.
-	 * 
-	 * @return Returns the name of the file.
-	 */
-	public String getFileName() {
-		return streamInitiation.getFile().getName();
-	}
-
-	/**
-	 * Returns the size in bytes of the file.
-	 * 
-	 * @return Returns the size in bytes of the file.
-	 */
-	public long getFileSize() {
-		return streamInitiation.getFile().getSize();
-	}
-
-	/**
-	 * Returns the description of the file provided by the requestor.
-	 * 
-	 * @return Returns the description of the file provided by the requestor.
-	 */
-	public String getDescription() {
-		return streamInitiation.getFile().getDesc();
-	}
-
-	/**
-	 * Returns the mime-type of the file.
-	 * 
-	 * @return Returns the mime-type of the file.
-	 */
-	public String getMimeType() {
-		return streamInitiation.getMimeType();
-	}
-
-	/**
-	 * Returns the fully-qualified jabber ID of the user that requested this
-	 * file transfer.
-	 * 
-	 * @return Returns the fully-qualified jabber ID of the user that requested
-	 *         this file transfer.
-	 */
-	public String getRequestor() {
-		return streamInitiation.getFrom();
-	}
-
-	/**
-	 * Returns the stream ID that uniquely identifies this file transfer.
-	 * 
-	 * @return Returns the stream ID that uniquely identifies this file
-	 *         transfer.
-	 */
-	public String getStreamID() {
-		return streamInitiation.getSessionID();
-	}
-
-	/**
-	 * Returns the stream initiation packet that was sent by the requestor which
-	 * contains the parameters of the file transfer being transfer and also the
-	 * methods available to transfer the file.
-	 * 
-	 * @return Returns the stream initiation packet that was sent by the
-	 *         requestor which contains the parameters of the file transfer
-	 *         being transfer and also the methods available to transfer the
-	 *         file.
-	 */
-	protected StreamInitiation getStreamInitiation() {
-		return streamInitiation;
-	}
-
-	/**
-	 * Accepts this file transfer and creates the incoming file transfer.
-	 * 
-	 * @return Returns the <b><i>IncomingFileTransfer</b></i> on which the
-	 *         file transfer can be carried out.
-	 */
-	public IncomingFileTransfer accept() {
-		return manager.createIncomingFileTransfer(this);
-	}
-
-	/**
-	 * Rejects the file transfer request.
-	 */
-	public void reject() {
-		manager.rejectIncomingFileTransfer(this);
-	}
-
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2006 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.filetransfer;
+
+import org.jivesoftware.smackx.packet.StreamInitiation;
+
+/**
+ * A request to send a file recieved from another user.
+ * 
+ * @author Alexander Wenckus
+ * 
+ */
+public class FileTransferRequest {
+	private final StreamInitiation streamInitiation;
+
+	private final FileTransferManager manager;
+
+	/**
+	 * A recieve request is constructed from the Stream Initiation request
+	 * received from the initator.
+	 * 
+	 * @param manager
+	 *            The manager handling this file transfer
+	 * 
+	 * @param si
+	 *            The Stream initiaton recieved from the initiator.
+	 */
+	public FileTransferRequest(FileTransferManager manager, StreamInitiation si) {
+		this.streamInitiation = si;
+		this.manager = manager;
+	}
+
+	/**
+	 * Returns the name of the file.
+	 * 
+	 * @return Returns the name of the file.
+	 */
+	public String getFileName() {
+		return streamInitiation.getFile().getName();
+	}
+
+	/**
+	 * Returns the size in bytes of the file.
+	 * 
+	 * @return Returns the size in bytes of the file.
+	 */
+	public long getFileSize() {
+		return streamInitiation.getFile().getSize();
+	}
+
+	/**
+	 * Returns the description of the file provided by the requestor.
+	 * 
+	 * @return Returns the description of the file provided by the requestor.
+	 */
+	public String getDescription() {
+		return streamInitiation.getFile().getDesc();
+	}
+
+	/**
+	 * Returns the mime-type of the file.
+	 * 
+	 * @return Returns the mime-type of the file.
+	 */
+	public String getMimeType() {
+		return streamInitiation.getMimeType();
+	}
+
+	/**
+	 * Returns the fully-qualified jabber ID of the user that requested this
+	 * file transfer.
+	 * 
+	 * @return Returns the fully-qualified jabber ID of the user that requested
+	 *         this file transfer.
+	 */
+	public String getRequestor() {
+		return streamInitiation.getFrom();
+	}
+
+	/**
+	 * Returns the stream ID that uniquely identifies this file transfer.
+	 * 
+	 * @return Returns the stream ID that uniquely identifies this file
+	 *         transfer.
+	 */
+	public String getStreamID() {
+		return streamInitiation.getSessionID();
+	}
+
+	/**
+	 * Returns the stream initiation packet that was sent by the requestor which
+	 * contains the parameters of the file transfer being transfer and also the
+	 * methods available to transfer the file.
+	 * 
+	 * @return Returns the stream initiation packet that was sent by the
+	 *         requestor which contains the parameters of the file transfer
+	 *         being transfer and also the methods available to transfer the
+	 *         file.
+	 */
+	protected StreamInitiation getStreamInitiation() {
+		return streamInitiation;
+	}
+
+	/**
+	 * Accepts this file transfer and creates the incoming file transfer.
+	 * 
+	 * @return Returns the <b><i>IncomingFileTransfer</b></i> on which the
+	 *         file transfer can be carried out.
+	 */
+	public IncomingFileTransfer accept() {
+		return manager.createIncomingFileTransfer(this);
+	}
+
+	/**
+	 * Rejects the file transfer request.
+	 */
+	public void reject() {
+		manager.rejectIncomingFileTransfer(this);
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/IBBTransferNegotiator.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/IBBTransferNegotiator.java
index b32f49a..7d5969c 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/IBBTransferNegotiator.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/IBBTransferNegotiator.java
@@ -1,152 +1,152 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2006 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.filetransfer;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.filter.AndFilter;
-import org.jivesoftware.smack.filter.FromContainsFilter;
-import org.jivesoftware.smack.filter.PacketFilter;
-import org.jivesoftware.smack.filter.PacketTypeFilter;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
-import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamRequest;
-import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamSession;
-import org.jivesoftware.smackx.bytestreams.ibb.packet.Open;
-import org.jivesoftware.smackx.packet.StreamInitiation;
-
-/**
- * The In-Band Bytestream file transfer method, or IBB for short, transfers the
- * file over the same XML Stream used by XMPP. It is the fall-back mechanism in
- * case the SOCKS5 bytestream method of transferring files is not available.
- * 
- * @author Alexander Wenckus
- * @author Henning Staib
- * @see <a href="http://xmpp.org/extensions/xep-0047.html">XEP-0047: In-Band
- *      Bytestreams (IBB)</a>
- */
-public class IBBTransferNegotiator extends StreamNegotiator {
-
-    private Connection connection;
-
-    private InBandBytestreamManager manager;
-
-    /**
-     * The default constructor for the In-Band Bytestream Negotiator.
-     * 
-     * @param connection The connection which this negotiator works on.
-     */
-    protected IBBTransferNegotiator(Connection connection) {
-        this.connection = connection;
-        this.manager = InBandBytestreamManager.getByteStreamManager(connection);
-    }
-
-    public OutputStream createOutgoingStream(String streamID, String initiator,
-                    String target) throws XMPPException {
-        InBandBytestreamSession session = this.manager.establishSession(target, streamID);
-        session.setCloseBothStreamsEnabled(true);
-        return session.getOutputStream();
-    }
-
-    public InputStream createIncomingStream(StreamInitiation initiation)
-                    throws XMPPException {
-        /*
-         * In-Band Bytestream initiation listener must ignore next in-band
-         * bytestream request with given session ID
-         */
-        this.manager.ignoreBytestreamRequestOnce(initiation.getSessionID());
-
-        Packet streamInitiation = initiateIncomingStream(this.connection, initiation);
-        return negotiateIncomingStream(streamInitiation);
-    }
-
-    public PacketFilter getInitiationPacketFilter(String from, String streamID) {
-        /*
-         * this method is always called prior to #negotiateIncomingStream() so
-         * the In-Band Bytestream initiation listener must ignore the next
-         * In-Band Bytestream request with the given session ID
-         */
-        this.manager.ignoreBytestreamRequestOnce(streamID);
-
-        return new AndFilter(new FromContainsFilter(from), new IBBOpenSidFilter(streamID));
-    }
-
-    public String[] getNamespaces() {
-        return new String[] { InBandBytestreamManager.NAMESPACE };
-    }
-
-    InputStream negotiateIncomingStream(Packet streamInitiation) throws XMPPException {
-        // build In-Band Bytestream request
-        InBandBytestreamRequest request = new ByteStreamRequest(this.manager,
-                        (Open) streamInitiation);
-
-        // always accept the request
-        InBandBytestreamSession session = request.accept();
-        session.setCloseBothStreamsEnabled(true);
-        return session.getInputStream();
-    }
-
-    public void cleanup() {
-    }
-
-    /**
-     * This PacketFilter accepts an incoming In-Band Bytestream open request
-     * with a specified session ID.
-     */
-    private static class IBBOpenSidFilter extends PacketTypeFilter {
-
-        private String sessionID;
-
-        public IBBOpenSidFilter(String sessionID) {
-            super(Open.class);
-            if (sessionID == null) {
-                throw new IllegalArgumentException("StreamID cannot be null");
-            }
-            this.sessionID = sessionID;
-        }
-
-        public boolean accept(Packet packet) {
-            if (super.accept(packet)) {
-                Open bytestream = (Open) packet;
-
-                // packet must by of type SET and contains the given session ID
-                return this.sessionID.equals(bytestream.getSessionID())
-                                && IQ.Type.SET.equals(bytestream.getType());
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Derive from InBandBytestreamRequest to access protected constructor.
-     */
-    private static class ByteStreamRequest extends InBandBytestreamRequest {
-
-        private ByteStreamRequest(InBandBytestreamManager manager, Open byteStreamRequest) {
-            super(manager, byteStreamRequest);
-        }
-
-    }
-
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2006 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.filetransfer;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.filter.AndFilter;
+import org.jivesoftware.smack.filter.FromContainsFilter;
+import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.filter.PacketTypeFilter;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
+import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamRequest;
+import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamSession;
+import org.jivesoftware.smackx.bytestreams.ibb.packet.Open;
+import org.jivesoftware.smackx.packet.StreamInitiation;
+
+/**
+ * The In-Band Bytestream file transfer method, or IBB for short, transfers the
+ * file over the same XML Stream used by XMPP. It is the fall-back mechanism in
+ * case the SOCKS5 bytestream method of transferring files is not available.
+ * 
+ * @author Alexander Wenckus
+ * @author Henning Staib
+ * @see <a href="http://xmpp.org/extensions/xep-0047.html">XEP-0047: In-Band
+ *      Bytestreams (IBB)</a>
+ */
+public class IBBTransferNegotiator extends StreamNegotiator {
+
+    private Connection connection;
+
+    private InBandBytestreamManager manager;
+
+    /**
+     * The default constructor for the In-Band Bytestream Negotiator.
+     * 
+     * @param connection The connection which this negotiator works on.
+     */
+    protected IBBTransferNegotiator(Connection connection) {
+        this.connection = connection;
+        this.manager = InBandBytestreamManager.getByteStreamManager(connection);
+    }
+
+    public OutputStream createOutgoingStream(String streamID, String initiator,
+                    String target) throws XMPPException {
+        InBandBytestreamSession session = this.manager.establishSession(target, streamID);
+        session.setCloseBothStreamsEnabled(true);
+        return session.getOutputStream();
+    }
+
+    public InputStream createIncomingStream(StreamInitiation initiation)
+                    throws XMPPException {
+        /*
+         * In-Band Bytestream initiation listener must ignore next in-band
+         * bytestream request with given session ID
+         */
+        this.manager.ignoreBytestreamRequestOnce(initiation.getSessionID());
+
+        Packet streamInitiation = initiateIncomingStream(this.connection, initiation);
+        return negotiateIncomingStream(streamInitiation);
+    }
+
+    public PacketFilter getInitiationPacketFilter(String from, String streamID) {
+        /*
+         * this method is always called prior to #negotiateIncomingStream() so
+         * the In-Band Bytestream initiation listener must ignore the next
+         * In-Band Bytestream request with the given session ID
+         */
+        this.manager.ignoreBytestreamRequestOnce(streamID);
+
+        return new AndFilter(new FromContainsFilter(from), new IBBOpenSidFilter(streamID));
+    }
+
+    public String[] getNamespaces() {
+        return new String[] { InBandBytestreamManager.NAMESPACE };
+    }
+
+    InputStream negotiateIncomingStream(Packet streamInitiation) throws XMPPException {
+        // build In-Band Bytestream request
+        InBandBytestreamRequest request = new ByteStreamRequest(this.manager,
+                        (Open) streamInitiation);
+
+        // always accept the request
+        InBandBytestreamSession session = request.accept();
+        session.setCloseBothStreamsEnabled(true);
+        return session.getInputStream();
+    }
+
+    public void cleanup() {
+    }
+
+    /**
+     * This PacketFilter accepts an incoming In-Band Bytestream open request
+     * with a specified session ID.
+     */
+    private static class IBBOpenSidFilter extends PacketTypeFilter {
+
+        private String sessionID;
+
+        public IBBOpenSidFilter(String sessionID) {
+            super(Open.class);
+            if (sessionID == null) {
+                throw new IllegalArgumentException("StreamID cannot be null");
+            }
+            this.sessionID = sessionID;
+        }
+
+        public boolean accept(Packet packet) {
+            if (super.accept(packet)) {
+                Open bytestream = (Open) packet;
+
+                // packet must by of type SET and contains the given session ID
+                return this.sessionID.equals(bytestream.getSessionID())
+                                && IQ.Type.SET.equals(bytestream.getType());
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Derive from InBandBytestreamRequest to access protected constructor.
+     */
+    private static class ByteStreamRequest extends InBandBytestreamRequest {
+
+        private ByteStreamRequest(InBandBytestreamManager manager, Open byteStreamRequest) {
+            super(manager, byteStreamRequest);
+        }
+
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/IncomingFileTransfer.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/IncomingFileTransfer.java
index 91a5a0d..fc15b63 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/IncomingFileTransfer.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/IncomingFileTransfer.java
@@ -1,215 +1,215 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2006 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.filetransfer;
-
-import org.jivesoftware.smack.XMPPException;
-
-import java.io.*;
-import java.util.concurrent.*;
-
-/**
- * An incoming file transfer is created when the
- * {@link FileTransferManager#createIncomingFileTransfer(FileTransferRequest)}
- * method is invoked. It is a file being sent to the local user from another
- * user on the jabber network. There are two stages of the file transfer to be
- * concerned with and they can be handled in different ways depending upon the
- * method that is invoked on this class.
- * <p/>
- * The first way that a file is recieved is by calling the
- * {@link #recieveFile()} method. This method, negotiates the appropriate stream
- * method and then returns the <b><i>InputStream</b></i> to read the file
- * data from.
- * <p/>
- * The second way that a file can be recieved through this class is by invoking
- * the {@link #recieveFile(File)} method. This method returns immediatly and
- * takes as its parameter a file on the local file system where the file
- * recieved from the transfer will be put.
- *
- * @author Alexander Wenckus
- */
-public class IncomingFileTransfer extends FileTransfer {
-
-    private FileTransferRequest recieveRequest;
-
-    private InputStream inputStream;
-
-    protected IncomingFileTransfer(FileTransferRequest request,
-            FileTransferNegotiator transferNegotiator) {
-        super(request.getRequestor(), request.getStreamID(), transferNegotiator);
-        this.recieveRequest = request;
-    }
-
-    /**
-     * Negotiates the stream method to transfer the file over and then returns
-     * the negotiated stream.
-     *
-     * @return The negotiated InputStream from which to read the data.
-     * @throws XMPPException If there is an error in the negotiation process an exception
-     *                       is thrown.
-     */
-    public InputStream recieveFile() throws XMPPException {
-        if (inputStream != null) {
-            throw new IllegalStateException("Transfer already negotiated!");
-        }
-
-        try {
-            inputStream = negotiateStream();
-        }
-        catch (XMPPException e) {
-            setException(e);
-            throw e;
-        }
-
-        return inputStream;
-    }
-
-    /**
-     * This method negotitates the stream and then transfer's the file over the
-     * negotiated stream. The transfered file will be saved at the provided
-     * location.
-     * <p/>
-     * This method will return immedialtly, file transfer progress can be
-     * monitored through several methods:
-     * <p/>
-     * <UL>
-     * <LI>{@link FileTransfer#getStatus()}
-     * <LI>{@link FileTransfer#getProgress()}
-     * <LI>{@link FileTransfer#isDone()}
-     * </UL>
-     *
-     * @param file The location to save the file.
-     * @throws XMPPException            when the file transfer fails
-     * @throws IllegalArgumentException This exception is thrown when the the provided file is
-     *                                  either null, or cannot be written to.
-     */
-    public void recieveFile(final File file) throws XMPPException {
-        if (file != null) {
-            if (!file.exists()) {
-                try {
-                    file.createNewFile();
-                }
-                catch (IOException e) {
-                    throw new XMPPException(
-                            "Could not create file to write too", e);
-                }
-            }
-            if (!file.canWrite()) {
-                throw new IllegalArgumentException("Cannot write to provided file");
-            }
-        }
-        else {
-            throw new IllegalArgumentException("File cannot be null");
-        }
-
-        Thread transferThread = new Thread(new Runnable() {
-            public void run() {
-                try {
-                    inputStream = negotiateStream();
-                }
-                catch (XMPPException e) {
-                    handleXMPPException(e);
-                    return;
-                }
-
-                OutputStream outputStream = null;
-                try {
-                    outputStream = new FileOutputStream(file);
-                    setStatus(Status.in_progress);
-                    writeToStream(inputStream, outputStream);
-                }
-                catch (XMPPException e) {
-                    setStatus(Status.error);
-                    setError(Error.stream);
-                    setException(e);
-                }
-                catch (FileNotFoundException e) {
-                    setStatus(Status.error);
-                    setError(Error.bad_file);
-                    setException(e);
-                }
-
-                if (getStatus().equals(Status.in_progress)) {
-                    setStatus(Status.complete);
-                }
-                if (inputStream != null) {
-                    try {
-                        inputStream.close();
-                    }
-                    catch (Throwable io) {
-                        /* Ignore */
-                    }
-                }
-                if (outputStream != null) {
-                    try {
-                        outputStream.close();
-                    }
-                    catch (Throwable io) {
-                        /* Ignore */
-                    }
-                }
-            }
-        }, "File Transfer " + streamID);
-        transferThread.start();
-    }
-
-    private void handleXMPPException(XMPPException e) {
-        setStatus(FileTransfer.Status.error);
-        setException(e);
-    }
-
-    private InputStream negotiateStream() throws XMPPException {
-        setStatus(Status.negotiating_transfer);
-        final StreamNegotiator streamNegotiator = negotiator
-                .selectStreamNegotiator(recieveRequest);
-        setStatus(Status.negotiating_stream);
-        FutureTask<InputStream> streamNegotiatorTask = new FutureTask<InputStream>(
-                new Callable<InputStream>() {
-
-                    public InputStream call() throws Exception {
-                        return streamNegotiator
-                                .createIncomingStream(recieveRequest.getStreamInitiation());
-                    }
-                });
-        streamNegotiatorTask.run();
-        InputStream inputStream;
-        try {
-            inputStream = streamNegotiatorTask.get(15, TimeUnit.SECONDS);
-        }
-        catch (InterruptedException e) {
-            throw new XMPPException("Interruption while executing", e);
-        }
-        catch (ExecutionException e) {
-            throw new XMPPException("Error in execution", e);
-        }
-        catch (TimeoutException e) {
-            throw new XMPPException("Request timed out", e);
-        }
-        finally {
-            streamNegotiatorTask.cancel(true);
-        }
-        setStatus(Status.negotiated);
-        return inputStream;
-    }
-
-    public void cancel() {
-        setStatus(Status.cancelled);
-    }
-
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2006 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.filetransfer;
+
+import org.jivesoftware.smack.XMPPException;
+
+import java.io.*;
+import java.util.concurrent.*;
+
+/**
+ * An incoming file transfer is created when the
+ * {@link FileTransferManager#createIncomingFileTransfer(FileTransferRequest)}
+ * method is invoked. It is a file being sent to the local user from another
+ * user on the jabber network. There are two stages of the file transfer to be
+ * concerned with and they can be handled in different ways depending upon the
+ * method that is invoked on this class.
+ * <p/>
+ * The first way that a file is recieved is by calling the
+ * {@link #recieveFile()} method. This method, negotiates the appropriate stream
+ * method and then returns the <b><i>InputStream</b></i> to read the file
+ * data from.
+ * <p/>
+ * The second way that a file can be recieved through this class is by invoking
+ * the {@link #recieveFile(File)} method. This method returns immediatly and
+ * takes as its parameter a file on the local file system where the file
+ * recieved from the transfer will be put.
+ *
+ * @author Alexander Wenckus
+ */
+public class IncomingFileTransfer extends FileTransfer {
+
+    private FileTransferRequest recieveRequest;
+
+    private InputStream inputStream;
+
+    protected IncomingFileTransfer(FileTransferRequest request,
+            FileTransferNegotiator transferNegotiator) {
+        super(request.getRequestor(), request.getStreamID(), transferNegotiator);
+        this.recieveRequest = request;
+    }
+
+    /**
+     * Negotiates the stream method to transfer the file over and then returns
+     * the negotiated stream.
+     *
+     * @return The negotiated InputStream from which to read the data.
+     * @throws XMPPException If there is an error in the negotiation process an exception
+     *                       is thrown.
+     */
+    public InputStream recieveFile() throws XMPPException {
+        if (inputStream != null) {
+            throw new IllegalStateException("Transfer already negotiated!");
+        }
+
+        try {
+            inputStream = negotiateStream();
+        }
+        catch (XMPPException e) {
+            setException(e);
+            throw e;
+        }
+
+        return inputStream;
+    }
+
+    /**
+     * This method negotitates the stream and then transfer's the file over the
+     * negotiated stream. The transfered file will be saved at the provided
+     * location.
+     * <p/>
+     * This method will return immedialtly, file transfer progress can be
+     * monitored through several methods:
+     * <p/>
+     * <UL>
+     * <LI>{@link FileTransfer#getStatus()}
+     * <LI>{@link FileTransfer#getProgress()}
+     * <LI>{@link FileTransfer#isDone()}
+     * </UL>
+     *
+     * @param file The location to save the file.
+     * @throws XMPPException            when the file transfer fails
+     * @throws IllegalArgumentException This exception is thrown when the the provided file is
+     *                                  either null, or cannot be written to.
+     */
+    public void recieveFile(final File file) throws XMPPException {
+        if (file != null) {
+            if (!file.exists()) {
+                try {
+                    file.createNewFile();
+                }
+                catch (IOException e) {
+                    throw new XMPPException(
+                            "Could not create file to write too", e);
+                }
+            }
+            if (!file.canWrite()) {
+                throw new IllegalArgumentException("Cannot write to provided file");
+            }
+        }
+        else {
+            throw new IllegalArgumentException("File cannot be null");
+        }
+
+        Thread transferThread = new Thread(new Runnable() {
+            public void run() {
+                try {
+                    inputStream = negotiateStream();
+                }
+                catch (XMPPException e) {
+                    handleXMPPException(e);
+                    return;
+                }
+
+                OutputStream outputStream = null;
+                try {
+                    outputStream = new FileOutputStream(file);
+                    setStatus(Status.in_progress);
+                    writeToStream(inputStream, outputStream);
+                }
+                catch (XMPPException e) {
+                    setStatus(Status.error);
+                    setError(Error.stream);
+                    setException(e);
+                }
+                catch (FileNotFoundException e) {
+                    setStatus(Status.error);
+                    setError(Error.bad_file);
+                    setException(e);
+                }
+
+                if (getStatus().equals(Status.in_progress)) {
+                    setStatus(Status.complete);
+                }
+                if (inputStream != null) {
+                    try {
+                        inputStream.close();
+                    }
+                    catch (Throwable io) {
+                        /* Ignore */
+                    }
+                }
+                if (outputStream != null) {
+                    try {
+                        outputStream.close();
+                    }
+                    catch (Throwable io) {
+                        /* Ignore */
+                    }
+                }
+            }
+        }, "File Transfer " + streamID);
+        transferThread.start();
+    }
+
+    private void handleXMPPException(XMPPException e) {
+        setStatus(FileTransfer.Status.error);
+        setException(e);
+    }
+
+    private InputStream negotiateStream() throws XMPPException {
+        setStatus(Status.negotiating_transfer);
+        final StreamNegotiator streamNegotiator = negotiator
+                .selectStreamNegotiator(recieveRequest);
+        setStatus(Status.negotiating_stream);
+        FutureTask<InputStream> streamNegotiatorTask = new FutureTask<InputStream>(
+                new Callable<InputStream>() {
+
+                    public InputStream call() throws Exception {
+                        return streamNegotiator
+                                .createIncomingStream(recieveRequest.getStreamInitiation());
+                    }
+                });
+        streamNegotiatorTask.run();
+        InputStream inputStream;
+        try {
+            inputStream = streamNegotiatorTask.get(15, TimeUnit.SECONDS);
+        }
+        catch (InterruptedException e) {
+            throw new XMPPException("Interruption while executing", e);
+        }
+        catch (ExecutionException e) {
+            throw new XMPPException("Error in execution", e);
+        }
+        catch (TimeoutException e) {
+            throw new XMPPException("Request timed out", e);
+        }
+        finally {
+            streamNegotiatorTask.cancel(true);
+        }
+        setStatus(Status.negotiated);
+        return inputStream;
+    }
+
+    public void cancel() {
+        setStatus(Status.cancelled);
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java
index 13b8a57..ded096e 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java
@@ -1,449 +1,449 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2006 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.filetransfer;
-
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.packet.XMPPError;
-
-import java.io.*;
-
-/**
- * Handles the sending of a file to another user. File transfer's in jabber have
- * several steps and there are several methods in this class that handle these
- * steps differently.
- *
- * @author Alexander Wenckus
- *
- */
-public class OutgoingFileTransfer extends FileTransfer {
-
-	private static int RESPONSE_TIMEOUT = 60 * 1000;
-    private NegotiationProgress callback;
-
-    /**
-     * Returns the time in milliseconds after which the file transfer
-     * negotiation process will timeout if the other user has not responded.
-     *
-     * @return Returns the time in milliseconds after which the file transfer
-     *         negotiation process will timeout if the remote user has not
-     *         responded.
-     */
-    public static int getResponseTimeout() {
-        return RESPONSE_TIMEOUT;
-    }
-
-	/**
-	 * Sets the time in milliseconds after which the file transfer negotiation
-	 * process will timeout if the other user has not responded.
-	 *
-	 * @param responseTimeout
-	 *            The timeout time in milliseconds.
-	 */
-	public static void setResponseTimeout(int responseTimeout) {
-		RESPONSE_TIMEOUT = responseTimeout;
-	}
-
-	private OutputStream outputStream;
-
-	private String initiator;
-
-	private Thread transferThread;
-
-	protected OutgoingFileTransfer(String initiator, String target,
-			String streamID, FileTransferNegotiator transferNegotiator) {
-		super(target, streamID, transferNegotiator);
-		this.initiator = initiator;
-	}
-
-	protected void setOutputStream(OutputStream stream) {
-		if (outputStream == null) {
-			this.outputStream = stream;
-		}
-	}
-
-	/**
-	 * Returns the output stream connected to the peer to transfer the file. It
-	 * is only available after it has been successfully negotiated by the
-	 * {@link StreamNegotiator}.
-	 *
-	 * @return Returns the output stream connected to the peer to transfer the
-	 *         file.
-	 */
-	protected OutputStream getOutputStream() {
-		if (getStatus().equals(FileTransfer.Status.negotiated)) {
-			return outputStream;
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * This method handles the negotiation of the file transfer and the stream,
-	 * it only returns the created stream after the negotiation has been completed.
-	 *
-	 * @param fileName
-	 *            The name of the file that will be transmitted. It is
-	 *            preferable for this name to have an extension as it will be
-	 *            used to determine the type of file it is.
-	 * @param fileSize
-	 *            The size in bytes of the file that will be transmitted.
-	 * @param description
-	 *            A description of the file that will be transmitted.
-	 * @return The OutputStream that is connected to the peer to transmit the
-	 *         file.
-	 * @throws XMPPException
-	 *             Thrown if an error occurs during the file transfer
-	 *             negotiation process.
-	 */
-	public synchronized OutputStream sendFile(String fileName, long fileSize,
-			String description) throws XMPPException {
-		if (isDone() || outputStream != null) {
-			throw new IllegalStateException(
-					"The negotation process has already"
-							+ " been attempted on this file transfer");
-		}
-		try {
-			setFileInfo(fileName, fileSize);
-			this.outputStream = negotiateStream(fileName, fileSize, description);
-		} catch (XMPPException e) {
-			handleXMPPException(e);
-			throw e;
-		}
-		return outputStream;
-	}
-
-	/**
-	 * This methods handles the transfer and stream negotiation process. It
-	 * returns immediately and its progress will be updated through the
-	 * {@link NegotiationProgress} callback.
-	 *
-	 * @param fileName
-	 *            The name of the file that will be transmitted. It is
-	 *            preferable for this name to have an extension as it will be
-	 *            used to determine the type of file it is.
-	 * @param fileSize
-	 *            The size in bytes of the file that will be transmitted.
-	 * @param description
-	 *            A description of the file that will be transmitted.
-	 * @param progress
-	 *            A callback to monitor the progress of the file transfer
-	 *            negotiation process and to retrieve the OutputStream when it
-	 *            is complete.
-	 */
-	public synchronized void sendFile(final String fileName,
-			final long fileSize, final String description,
-			final NegotiationProgress progress)
-    {
-        if(progress == null) {
-            throw new IllegalArgumentException("Callback progress cannot be null.");
-        }
-        checkTransferThread();
-		if (isDone() || outputStream != null) {
-			throw new IllegalStateException(
-					"The negotation process has already"
-							+ " been attempted for this file transfer");
-		}
-        setFileInfo(fileName, fileSize);
-        this.callback = progress;
-        transferThread = new Thread(new Runnable() {
-			public void run() {
-				try {
-					OutgoingFileTransfer.this.outputStream = negotiateStream(
-							fileName, fileSize, description);
-                    progress.outputStreamEstablished(OutgoingFileTransfer.this.outputStream);
-                }
-                catch (XMPPException e) {
-					handleXMPPException(e);
-				}
-			}
-		}, "File Transfer Negotiation " + streamID);
-		transferThread.start();
-	}
-
-	private void checkTransferThread() {
-		if (transferThread != null && transferThread.isAlive() || isDone()) {
-			throw new IllegalStateException(
-					"File transfer in progress or has already completed.");
-		}
-	}
-
-    /**
-	 * This method handles the stream negotiation process and transmits the file
-	 * to the remote user. It returns immediately and the progress of the file
-	 * transfer can be monitored through several methods:
-	 *
-	 * <UL>
-	 * <LI>{@link FileTransfer#getStatus()}
-	 * <LI>{@link FileTransfer#getProgress()}
-	 * <LI>{@link FileTransfer#isDone()}
-	 * </UL>
-	 *
-     * @param file the file to transfer to the remote entity.
-     * @param description a description for the file to transfer.
-	 * @throws XMPPException
-	 *             If there is an error during the negotiation process or the
-	 *             sending of the file.
-	 */
-	public synchronized void sendFile(final File file, final String description)
-			throws XMPPException {
-		checkTransferThread();
-		if (file == null || !file.exists() || !file.canRead()) {
-			throw new IllegalArgumentException("Could not read file");
-		} else {
-			setFileInfo(file.getAbsolutePath(), file.getName(), file.length());
-		}
-
-		transferThread = new Thread(new Runnable() {
-			public void run() {
-				try {
-					outputStream = negotiateStream(file.getName(), file
-							.length(), description);
-				} catch (XMPPException e) {
-					handleXMPPException(e);
-					return;
-				}
-				if (outputStream == null) {
-					return;
-				}
-
-                if (!updateStatus(Status.negotiated, Status.in_progress)) {
-					return;
-				}
-
-				InputStream inputStream = null;
-				try {
-					inputStream = new FileInputStream(file);
-					writeToStream(inputStream, outputStream);
-				} catch (FileNotFoundException e) {
-					setStatus(FileTransfer.Status.error);
-					setError(Error.bad_file);
-					setException(e);
-				} catch (XMPPException e) {
-					setStatus(FileTransfer.Status.error);
-					setException(e);
-				} finally {
-					try {
-						if (inputStream != null) {
-							inputStream.close();
-						}
-
-						outputStream.flush();
-						outputStream.close();
-					} catch (IOException e) {
-                        /* Do Nothing */
-					}
-				}
-                updateStatus(Status.in_progress, FileTransfer.Status.complete);
-				}
-
-		}, "File Transfer " + streamID);
-		transferThread.start();
-	}
-
-    /**
-	 * This method handles the stream negotiation process and transmits the file
-	 * to the remote user. It returns immediately and the progress of the file
-	 * transfer can be monitored through several methods:
-	 *
-	 * <UL>
-	 * <LI>{@link FileTransfer#getStatus()}
-	 * <LI>{@link FileTransfer#getProgress()}
-	 * <LI>{@link FileTransfer#isDone()}
-	 * </UL>
-	 *
-     * @param in the stream to transfer to the remote entity.
-     * @param fileName the name of the file that is transferred
-     * @param fileSize the size of the file that is transferred
-     * @param description a description for the file to transfer.
-	 */
-	public synchronized void sendStream(final InputStream in, final String fileName, final long fileSize, final String description){
-		checkTransferThread();
-
-		setFileInfo(fileName, fileSize);
-		transferThread = new Thread(new Runnable() {
-			public void run() {
-                //Create packet filter
-                try {
-					outputStream = negotiateStream(fileName, fileSize, description);
-				} catch (XMPPException e) {
-					handleXMPPException(e);
-					return;
-				}
-				if (outputStream == null) {
-					return;
-				}
-
-                if (!updateStatus(Status.negotiated, Status.in_progress)) {
-					return;
-				}
-				try {
-					writeToStream(in, outputStream);
-				} catch (XMPPException e) {
-					setStatus(FileTransfer.Status.error);
-					setException(e);
-				} finally {
-					try {
-						if (in != null) {
-							in.close();
-						}
-
-						outputStream.flush();
-						outputStream.close();
-					} catch (IOException e) {
-                        /* Do Nothing */
-					}
-				}
-                updateStatus(Status.in_progress, FileTransfer.Status.complete);
-				}
-
-		}, "File Transfer " + streamID);
-		transferThread.start();
-	}
-
-	private void handleXMPPException(XMPPException e) {
-		XMPPError error = e.getXMPPError();
-		if (error != null) {
-			int code = error.getCode();
-			if (code == 403) {
-				setStatus(Status.refused);
-				return;
-			}
-            else if (code == 400) {
-				setStatus(Status.error);
-				setError(Error.not_acceptable);
-            }
-            else {
-                setStatus(FileTransfer.Status.error);
-            }
-        }
-
-        setException(e);
-	}
-
-	/**
-	 * Returns the amount of bytes that have been sent for the file transfer. Or
-	 * -1 if the file transfer has not started.
-	 * <p>
-	 * Note: This method is only useful when the {@link #sendFile(File, String)}
-	 * method is called, as it is the only method that actually transmits the
-	 * file.
-	 *
-	 * @return Returns the amount of bytes that have been sent for the file
-	 *         transfer. Or -1 if the file transfer has not started.
-	 */
-	public long getBytesSent() {
-		return amountWritten;
-	}
-
-	private OutputStream negotiateStream(String fileName, long fileSize,
-			String description) throws XMPPException {
-		// Negotiate the file transfer profile
-
-        if (!updateStatus(Status.initial, Status.negotiating_transfer)) {
-            throw new XMPPException("Illegal state change");
-        }
-		StreamNegotiator streamNegotiator = negotiator.negotiateOutgoingTransfer(
-				getPeer(), streamID, fileName, fileSize, description,
-				RESPONSE_TIMEOUT);
-
-		if (streamNegotiator == null) {
-			setStatus(Status.error);
-			setError(Error.no_response);
-			return null;
-		}
-
-        // Negotiate the stream
-        if (!updateStatus(Status.negotiating_transfer, Status.negotiating_stream)) {
-            throw new XMPPException("Illegal state change");
-        }
-		outputStream = streamNegotiator.createOutgoingStream(streamID,
-                initiator, getPeer());
-
-        if (!updateStatus(Status.negotiating_stream, Status.negotiated)) {
-            throw new XMPPException("Illegal state change");
-		}
-		return outputStream;
-	}
-
-	public void cancel() {
-		setStatus(Status.cancelled);
-	}
-
-    @Override
-    protected boolean updateStatus(Status oldStatus, Status newStatus) {
-        boolean isUpdated = super.updateStatus(oldStatus, newStatus);
-        if(callback != null && isUpdated) {
-            callback.statusUpdated(oldStatus, newStatus);
-        }
-        return isUpdated;
-    }
-
-    @Override
-    protected void setStatus(Status status) {
-        Status oldStatus = getStatus();
-        super.setStatus(status);
-        if(callback != null) {
-            callback.statusUpdated(oldStatus, status);
-        }
-    }
-
-    @Override
-    protected void setException(Exception exception) {
-        super.setException(exception);
-        if(callback != null) {
-            callback.errorEstablishingStream(exception);
-        }
-    }
-
-    /**
-	 * A callback class to retrieve the status of an outgoing transfer
-	 * negotiation process.
-	 *
-	 * @author Alexander Wenckus
-	 *
-	 */
-	public interface NegotiationProgress {
-
-		/**
-		 * Called when the status changes
-         *
-         * @param oldStatus the previous status of the file transfer.
-         * @param newStatus the new status of the file transfer.
-         */
-		void statusUpdated(Status oldStatus, Status newStatus);
-
-		/**
-		 * Once the negotiation process is completed the output stream can be
-		 * retrieved.
-         *
-         * @param stream the established stream which can be used to transfer the file to the remote
-         * entity
-		 */
-		void outputStreamEstablished(OutputStream stream);
-
-        /**
-         * Called when an exception occurs during the negotiation progress.
-         *
-         * @param e the exception that occurred.
-         */
-        void errorEstablishingStream(Exception e);
-    }
-
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2006 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.filetransfer;
+
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.packet.XMPPError;
+
+import java.io.*;
+
+/**
+ * Handles the sending of a file to another user. File transfer's in jabber have
+ * several steps and there are several methods in this class that handle these
+ * steps differently.
+ *
+ * @author Alexander Wenckus
+ *
+ */
+public class OutgoingFileTransfer extends FileTransfer {
+
+	private static int RESPONSE_TIMEOUT = 60 * 1000;
+    private NegotiationProgress callback;
+
+    /**
+     * Returns the time in milliseconds after which the file transfer
+     * negotiation process will timeout if the other user has not responded.
+     *
+     * @return Returns the time in milliseconds after which the file transfer
+     *         negotiation process will timeout if the remote user has not
+     *         responded.
+     */
+    public static int getResponseTimeout() {
+        return RESPONSE_TIMEOUT;
+    }
+
+	/**
+	 * Sets the time in milliseconds after which the file transfer negotiation
+	 * process will timeout if the other user has not responded.
+	 *
+	 * @param responseTimeout
+	 *            The timeout time in milliseconds.
+	 */
+	public static void setResponseTimeout(int responseTimeout) {
+		RESPONSE_TIMEOUT = responseTimeout;
+	}
+
+	private OutputStream outputStream;
+
+	private String initiator;
+
+	private Thread transferThread;
+
+	protected OutgoingFileTransfer(String initiator, String target,
+			String streamID, FileTransferNegotiator transferNegotiator) {
+		super(target, streamID, transferNegotiator);
+		this.initiator = initiator;
+	}
+
+	protected void setOutputStream(OutputStream stream) {
+		if (outputStream == null) {
+			this.outputStream = stream;
+		}
+	}
+
+	/**
+	 * Returns the output stream connected to the peer to transfer the file. It
+	 * is only available after it has been successfully negotiated by the
+	 * {@link StreamNegotiator}.
+	 *
+	 * @return Returns the output stream connected to the peer to transfer the
+	 *         file.
+	 */
+	protected OutputStream getOutputStream() {
+		if (getStatus().equals(FileTransfer.Status.negotiated)) {
+			return outputStream;
+		} else {
+			return null;
+		}
+	}
+
+	/**
+	 * This method handles the negotiation of the file transfer and the stream,
+	 * it only returns the created stream after the negotiation has been completed.
+	 *
+	 * @param fileName
+	 *            The name of the file that will be transmitted. It is
+	 *            preferable for this name to have an extension as it will be
+	 *            used to determine the type of file it is.
+	 * @param fileSize
+	 *            The size in bytes of the file that will be transmitted.
+	 * @param description
+	 *            A description of the file that will be transmitted.
+	 * @return The OutputStream that is connected to the peer to transmit the
+	 *         file.
+	 * @throws XMPPException
+	 *             Thrown if an error occurs during the file transfer
+	 *             negotiation process.
+	 */
+	public synchronized OutputStream sendFile(String fileName, long fileSize,
+			String description) throws XMPPException {
+		if (isDone() || outputStream != null) {
+			throw new IllegalStateException(
+					"The negotation process has already"
+							+ " been attempted on this file transfer");
+		}
+		try {
+			setFileInfo(fileName, fileSize);
+			this.outputStream = negotiateStream(fileName, fileSize, description);
+		} catch (XMPPException e) {
+			handleXMPPException(e);
+			throw e;
+		}
+		return outputStream;
+	}
+
+	/**
+	 * This methods handles the transfer and stream negotiation process. It
+	 * returns immediately and its progress will be updated through the
+	 * {@link NegotiationProgress} callback.
+	 *
+	 * @param fileName
+	 *            The name of the file that will be transmitted. It is
+	 *            preferable for this name to have an extension as it will be
+	 *            used to determine the type of file it is.
+	 * @param fileSize
+	 *            The size in bytes of the file that will be transmitted.
+	 * @param description
+	 *            A description of the file that will be transmitted.
+	 * @param progress
+	 *            A callback to monitor the progress of the file transfer
+	 *            negotiation process and to retrieve the OutputStream when it
+	 *            is complete.
+	 */
+	public synchronized void sendFile(final String fileName,
+			final long fileSize, final String description,
+			final NegotiationProgress progress)
+    {
+        if(progress == null) {
+            throw new IllegalArgumentException("Callback progress cannot be null.");
+        }
+        checkTransferThread();
+		if (isDone() || outputStream != null) {
+			throw new IllegalStateException(
+					"The negotation process has already"
+							+ " been attempted for this file transfer");
+		}
+        setFileInfo(fileName, fileSize);
+        this.callback = progress;
+        transferThread = new Thread(new Runnable() {
+			public void run() {
+				try {
+					OutgoingFileTransfer.this.outputStream = negotiateStream(
+							fileName, fileSize, description);
+                    progress.outputStreamEstablished(OutgoingFileTransfer.this.outputStream);
+                }
+                catch (XMPPException e) {
+					handleXMPPException(e);
+				}
+			}
+		}, "File Transfer Negotiation " + streamID);
+		transferThread.start();
+	}
+
+	private void checkTransferThread() {
+		if (transferThread != null && transferThread.isAlive() || isDone()) {
+			throw new IllegalStateException(
+					"File transfer in progress or has already completed.");
+		}
+	}
+
+    /**
+	 * This method handles the stream negotiation process and transmits the file
+	 * to the remote user. It returns immediately and the progress of the file
+	 * transfer can be monitored through several methods:
+	 *
+	 * <UL>
+	 * <LI>{@link FileTransfer#getStatus()}
+	 * <LI>{@link FileTransfer#getProgress()}
+	 * <LI>{@link FileTransfer#isDone()}
+	 * </UL>
+	 *
+     * @param file the file to transfer to the remote entity.
+     * @param description a description for the file to transfer.
+	 * @throws XMPPException
+	 *             If there is an error during the negotiation process or the
+	 *             sending of the file.
+	 */
+	public synchronized void sendFile(final File file, final String description)
+			throws XMPPException {
+		checkTransferThread();
+		if (file == null || !file.exists() || !file.canRead()) {
+			throw new IllegalArgumentException("Could not read file");
+		} else {
+			setFileInfo(file.getAbsolutePath(), file.getName(), file.length());
+		}
+
+		transferThread = new Thread(new Runnable() {
+			public void run() {
+				try {
+					outputStream = negotiateStream(file.getName(), file
+							.length(), description);
+				} catch (XMPPException e) {
+					handleXMPPException(e);
+					return;
+				}
+				if (outputStream == null) {
+					return;
+				}
+
+                if (!updateStatus(Status.negotiated, Status.in_progress)) {
+					return;
+				}
+
+				InputStream inputStream = null;
+				try {
+					inputStream = new FileInputStream(file);
+					writeToStream(inputStream, outputStream);
+				} catch (FileNotFoundException e) {
+					setStatus(FileTransfer.Status.error);
+					setError(Error.bad_file);
+					setException(e);
+				} catch (XMPPException e) {
+					setStatus(FileTransfer.Status.error);
+					setException(e);
+				} finally {
+					try {
+						if (inputStream != null) {
+							inputStream.close();
+						}
+
+						outputStream.flush();
+						outputStream.close();
+					} catch (IOException e) {
+                        /* Do Nothing */
+					}
+				}
+                updateStatus(Status.in_progress, FileTransfer.Status.complete);
+				}
+
+		}, "File Transfer " + streamID);
+		transferThread.start();
+	}
+
+    /**
+	 * This method handles the stream negotiation process and transmits the file
+	 * to the remote user. It returns immediately and the progress of the file
+	 * transfer can be monitored through several methods:
+	 *
+	 * <UL>
+	 * <LI>{@link FileTransfer#getStatus()}
+	 * <LI>{@link FileTransfer#getProgress()}
+	 * <LI>{@link FileTransfer#isDone()}
+	 * </UL>
+	 *
+     * @param in the stream to transfer to the remote entity.
+     * @param fileName the name of the file that is transferred
+     * @param fileSize the size of the file that is transferred
+     * @param description a description for the file to transfer.
+	 */
+	public synchronized void sendStream(final InputStream in, final String fileName, final long fileSize, final String description){
+		checkTransferThread();
+
+		setFileInfo(fileName, fileSize);
+		transferThread = new Thread(new Runnable() {
+			public void run() {
+                //Create packet filter
+                try {
+					outputStream = negotiateStream(fileName, fileSize, description);
+				} catch (XMPPException e) {
+					handleXMPPException(e);
+					return;
+				}
+				if (outputStream == null) {
+					return;
+				}
+
+                if (!updateStatus(Status.negotiated, Status.in_progress)) {
+					return;
+				}
+				try {
+					writeToStream(in, outputStream);
+				} catch (XMPPException e) {
+					setStatus(FileTransfer.Status.error);
+					setException(e);
+				} finally {
+					try {
+						if (in != null) {
+							in.close();
+						}
+
+						outputStream.flush();
+						outputStream.close();
+					} catch (IOException e) {
+                        /* Do Nothing */
+					}
+				}
+                updateStatus(Status.in_progress, FileTransfer.Status.complete);
+				}
+
+		}, "File Transfer " + streamID);
+		transferThread.start();
+	}
+
+	private void handleXMPPException(XMPPException e) {
+		XMPPError error = e.getXMPPError();
+		if (error != null) {
+			int code = error.getCode();
+			if (code == 403) {
+				setStatus(Status.refused);
+				return;
+			}
+            else if (code == 400) {
+				setStatus(Status.error);
+				setError(Error.not_acceptable);
+            }
+            else {
+                setStatus(FileTransfer.Status.error);
+            }
+        }
+
+        setException(e);
+	}
+
+	/**
+	 * Returns the amount of bytes that have been sent for the file transfer. Or
+	 * -1 if the file transfer has not started.
+	 * <p>
+	 * Note: This method is only useful when the {@link #sendFile(File, String)}
+	 * method is called, as it is the only method that actually transmits the
+	 * file.
+	 *
+	 * @return Returns the amount of bytes that have been sent for the file
+	 *         transfer. Or -1 if the file transfer has not started.
+	 */
+	public long getBytesSent() {
+		return amountWritten;
+	}
+
+	private OutputStream negotiateStream(String fileName, long fileSize,
+			String description) throws XMPPException {
+		// Negotiate the file transfer profile
+
+        if (!updateStatus(Status.initial, Status.negotiating_transfer)) {
+            throw new XMPPException("Illegal state change");
+        }
+		StreamNegotiator streamNegotiator = negotiator.negotiateOutgoingTransfer(
+				getPeer(), streamID, fileName, fileSize, description,
+				RESPONSE_TIMEOUT);
+
+		if (streamNegotiator == null) {
+			setStatus(Status.error);
+			setError(Error.no_response);
+			return null;
+		}
+
+        // Negotiate the stream
+        if (!updateStatus(Status.negotiating_transfer, Status.negotiating_stream)) {
+            throw new XMPPException("Illegal state change");
+        }
+		outputStream = streamNegotiator.createOutgoingStream(streamID,
+                initiator, getPeer());
+
+        if (!updateStatus(Status.negotiating_stream, Status.negotiated)) {
+            throw new XMPPException("Illegal state change");
+		}
+		return outputStream;
+	}
+
+	public void cancel() {
+		setStatus(Status.cancelled);
+	}
+
+    @Override
+    protected boolean updateStatus(Status oldStatus, Status newStatus) {
+        boolean isUpdated = super.updateStatus(oldStatus, newStatus);
+        if(callback != null && isUpdated) {
+            callback.statusUpdated(oldStatus, newStatus);
+        }
+        return isUpdated;
+    }
+
+    @Override
+    protected void setStatus(Status status) {
+        Status oldStatus = getStatus();
+        super.setStatus(status);
+        if(callback != null) {
+            callback.statusUpdated(oldStatus, status);
+        }
+    }
+
+    @Override
+    protected void setException(Exception exception) {
+        super.setException(exception);
+        if(callback != null) {
+            callback.errorEstablishingStream(exception);
+        }
+    }
+
+    /**
+	 * A callback class to retrieve the status of an outgoing transfer
+	 * negotiation process.
+	 *
+	 * @author Alexander Wenckus
+	 *
+	 */
+	public interface NegotiationProgress {
+
+		/**
+		 * Called when the status changes
+         *
+         * @param oldStatus the previous status of the file transfer.
+         * @param newStatus the new status of the file transfer.
+         */
+		void statusUpdated(Status oldStatus, Status newStatus);
+
+		/**
+		 * Once the negotiation process is completed the output stream can be
+		 * retrieved.
+         *
+         * @param stream the established stream which can be used to transfer the file to the remote
+         * entity
+		 */
+		void outputStreamEstablished(OutputStream stream);
+
+        /**
+         * Called when an exception occurs during the negotiation progress.
+         *
+         * @param e the exception that occurred.
+         */
+        void errorEstablishingStream(Exception e);
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiator.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiator.java
index 3c07fdc..8db0929 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiator.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiator.java
@@ -1,164 +1,164 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.filetransfer;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PushbackInputStream;
-
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.filter.AndFilter;
-import org.jivesoftware.smack.filter.FromMatchesFilter;
-import org.jivesoftware.smack.filter.PacketFilter;
-import org.jivesoftware.smack.filter.PacketTypeFilter;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager;
-import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest;
-import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession;
-import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
-import org.jivesoftware.smackx.packet.StreamInitiation;
-
-/**
- * Negotiates a SOCKS5 Bytestream to be used for file transfers. The implementation is based on the
- * {@link Socks5BytestreamManager} and the {@link Socks5BytestreamRequest}.
- * 
- * @author Henning Staib
- * @see <a href="http://xmpp.org/extensions/xep-0065.html">XEP-0065: SOCKS5 Bytestreams</a>
- */
-public class Socks5TransferNegotiator extends StreamNegotiator {
-
-    private Connection connection;
-
-    private Socks5BytestreamManager manager;
-
-    Socks5TransferNegotiator(Connection connection) {
-        this.connection = connection;
-        this.manager = Socks5BytestreamManager.getBytestreamManager(this.connection);
-    }
-
-    @Override
-    public OutputStream createOutgoingStream(String streamID, String initiator, String target)
-                    throws XMPPException {
-        try {
-            return this.manager.establishSession(target, streamID).getOutputStream();
-        }
-        catch (IOException e) {
-            throw new XMPPException("error establishing SOCKS5 Bytestream", e);
-        }
-        catch (InterruptedException e) {
-            throw new XMPPException("error establishing SOCKS5 Bytestream", e);
-        }
-    }
-
-    @Override
-    public InputStream createIncomingStream(StreamInitiation initiation) throws XMPPException,
-                    InterruptedException {
-        /*
-         * SOCKS5 initiation listener must ignore next SOCKS5 Bytestream request with given session
-         * ID
-         */
-        this.manager.ignoreBytestreamRequestOnce(initiation.getSessionID());
-
-        Packet streamInitiation = initiateIncomingStream(this.connection, initiation);
-        return negotiateIncomingStream(streamInitiation);
-    }
-
-    @Override
-    public PacketFilter getInitiationPacketFilter(final String from, String streamID) {
-        /*
-         * this method is always called prior to #negotiateIncomingStream() so the SOCKS5
-         * InitiationListener must ignore the next SOCKS5 Bytestream request with the given session
-         * ID
-         */
-        this.manager.ignoreBytestreamRequestOnce(streamID);
-
-        return new AndFilter(new FromMatchesFilter(from), new BytestreamSIDFilter(streamID));
-    }
-
-    @Override
-    public String[] getNamespaces() {
-        return new String[] { Socks5BytestreamManager.NAMESPACE };
-    }
-
-    @Override
-    InputStream negotiateIncomingStream(Packet streamInitiation) throws XMPPException,
-                    InterruptedException {
-        // build SOCKS5 Bytestream request
-        Socks5BytestreamRequest request = new ByteStreamRequest(this.manager,
-                        (Bytestream) streamInitiation);
-
-        // always accept the request
-        Socks5BytestreamSession session = request.accept();
-
-        // test input stream
-        try {
-            PushbackInputStream stream = new PushbackInputStream(session.getInputStream());
-            int firstByte = stream.read();
-            stream.unread(firstByte);
-            return stream;
-        }
-        catch (IOException e) {
-            throw new XMPPException("Error establishing input stream", e);
-        }
-    }
-
-    @Override
-    public void cleanup() {
-        /* do nothing */
-    }
-
-    /**
-     * This PacketFilter accepts an incoming SOCKS5 Bytestream request with a specified session ID.
-     */
-    private static class BytestreamSIDFilter extends PacketTypeFilter {
-
-        private String sessionID;
-
-        public BytestreamSIDFilter(String sessionID) {
-            super(Bytestream.class);
-            if (sessionID == null) {
-                throw new IllegalArgumentException("StreamID cannot be null");
-            }
-            this.sessionID = sessionID;
-        }
-
-        @Override
-        public boolean accept(Packet packet) {
-            if (super.accept(packet)) {
-                Bytestream bytestream = (Bytestream) packet;
-
-                // packet must by of type SET and contains the given session ID
-                return this.sessionID.equals(bytestream.getSessionID())
-                                && IQ.Type.SET.equals(bytestream.getType());
-            }
-            return false;
-        }
-
-    }
-
-    /**
-     * Derive from Socks5BytestreamRequest to access protected constructor.
-     */
-    private static class ByteStreamRequest extends Socks5BytestreamRequest {
-
-        private ByteStreamRequest(Socks5BytestreamManager manager, Bytestream byteStreamRequest) {
-            super(manager, byteStreamRequest);
-        }
-
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.filetransfer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PushbackInputStream;
+
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.filter.AndFilter;
+import org.jivesoftware.smack.filter.FromMatchesFilter;
+import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.filter.PacketTypeFilter;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager;
+import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest;
+import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession;
+import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
+import org.jivesoftware.smackx.packet.StreamInitiation;
+
+/**
+ * Negotiates a SOCKS5 Bytestream to be used for file transfers. The implementation is based on the
+ * {@link Socks5BytestreamManager} and the {@link Socks5BytestreamRequest}.
+ * 
+ * @author Henning Staib
+ * @see <a href="http://xmpp.org/extensions/xep-0065.html">XEP-0065: SOCKS5 Bytestreams</a>
+ */
+public class Socks5TransferNegotiator extends StreamNegotiator {
+
+    private Connection connection;
+
+    private Socks5BytestreamManager manager;
+
+    Socks5TransferNegotiator(Connection connection) {
+        this.connection = connection;
+        this.manager = Socks5BytestreamManager.getBytestreamManager(this.connection);
+    }
+
+    @Override
+    public OutputStream createOutgoingStream(String streamID, String initiator, String target)
+                    throws XMPPException {
+        try {
+            return this.manager.establishSession(target, streamID).getOutputStream();
+        }
+        catch (IOException e) {
+            throw new XMPPException("error establishing SOCKS5 Bytestream", e);
+        }
+        catch (InterruptedException e) {
+            throw new XMPPException("error establishing SOCKS5 Bytestream", e);
+        }
+    }
+
+    @Override
+    public InputStream createIncomingStream(StreamInitiation initiation) throws XMPPException,
+                    InterruptedException {
+        /*
+         * SOCKS5 initiation listener must ignore next SOCKS5 Bytestream request with given session
+         * ID
+         */
+        this.manager.ignoreBytestreamRequestOnce(initiation.getSessionID());
+
+        Packet streamInitiation = initiateIncomingStream(this.connection, initiation);
+        return negotiateIncomingStream(streamInitiation);
+    }
+
+    @Override
+    public PacketFilter getInitiationPacketFilter(final String from, String streamID) {
+        /*
+         * this method is always called prior to #negotiateIncomingStream() so the SOCKS5
+         * InitiationListener must ignore the next SOCKS5 Bytestream request with the given session
+         * ID
+         */
+        this.manager.ignoreBytestreamRequestOnce(streamID);
+
+        return new AndFilter(new FromMatchesFilter(from), new BytestreamSIDFilter(streamID));
+    }
+
+    @Override
+    public String[] getNamespaces() {
+        return new String[] { Socks5BytestreamManager.NAMESPACE };
+    }
+
+    @Override
+    InputStream negotiateIncomingStream(Packet streamInitiation) throws XMPPException,
+                    InterruptedException {
+        // build SOCKS5 Bytestream request
+        Socks5BytestreamRequest request = new ByteStreamRequest(this.manager,
+                        (Bytestream) streamInitiation);
+
+        // always accept the request
+        Socks5BytestreamSession session = request.accept();
+
+        // test input stream
+        try {
+            PushbackInputStream stream = new PushbackInputStream(session.getInputStream());
+            int firstByte = stream.read();
+            stream.unread(firstByte);
+            return stream;
+        }
+        catch (IOException e) {
+            throw new XMPPException("Error establishing input stream", e);
+        }
+    }
+
+    @Override
+    public void cleanup() {
+        /* do nothing */
+    }
+
+    /**
+     * This PacketFilter accepts an incoming SOCKS5 Bytestream request with a specified session ID.
+     */
+    private static class BytestreamSIDFilter extends PacketTypeFilter {
+
+        private String sessionID;
+
+        public BytestreamSIDFilter(String sessionID) {
+            super(Bytestream.class);
+            if (sessionID == null) {
+                throw new IllegalArgumentException("StreamID cannot be null");
+            }
+            this.sessionID = sessionID;
+        }
+
+        @Override
+        public boolean accept(Packet packet) {
+            if (super.accept(packet)) {
+                Bytestream bytestream = (Bytestream) packet;
+
+                // packet must by of type SET and contains the given session ID
+                return this.sessionID.equals(bytestream.getSessionID())
+                                && IQ.Type.SET.equals(bytestream.getType());
+            }
+            return false;
+        }
+
+    }
+
+    /**
+     * Derive from Socks5BytestreamRequest to access protected constructor.
+     */
+    private static class ByteStreamRequest extends Socks5BytestreamRequest {
+
+        private ByteStreamRequest(Socks5BytestreamManager manager, Bytestream byteStreamRequest) {
+            super(manager, byteStreamRequest);
+        }
+
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java
index 5eefe43..fb60ee1 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java
@@ -1,167 +1,167 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2006 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.filetransfer;
-
-import org.jivesoftware.smack.PacketCollector;
-import org.jivesoftware.smack.SmackConfiguration;
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.filter.PacketFilter;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smack.packet.XMPPError;
-import org.jivesoftware.smackx.Form;
-import org.jivesoftware.smackx.FormField;
-import org.jivesoftware.smackx.packet.DataForm;
-import org.jivesoftware.smackx.packet.StreamInitiation;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * After the file transfer negotiation process is completed according to
- * JEP-0096, the negotiation process is passed off to a particular stream
- * negotiator. The stream negotiator will then negotiate the chosen stream and
- * return the stream to transfer the file.
- *
- * @author Alexander Wenckus
- */
-public abstract class StreamNegotiator {
-
-    /**
-     * Creates the initiation acceptance packet to forward to the stream
-     * initiator.
-     *
-     * @param streamInitiationOffer The offer from the stream initiator to connect for a stream.
-     * @param namespaces            The namespace that relates to the accepted means of transfer.
-     * @return The response to be forwarded to the initiator.
-     */
-    public StreamInitiation createInitiationAccept(
-            StreamInitiation streamInitiationOffer, String[] namespaces)
-    {
-        StreamInitiation response = new StreamInitiation();
-        response.setTo(streamInitiationOffer.getFrom());
-        response.setFrom(streamInitiationOffer.getTo());
-        response.setType(IQ.Type.RESULT);
-        response.setPacketID(streamInitiationOffer.getPacketID());
-
-        DataForm form = new DataForm(Form.TYPE_SUBMIT);
-        FormField field = new FormField(
-                FileTransferNegotiator.STREAM_DATA_FIELD_NAME);
-        for (String namespace : namespaces) {
-            field.addValue(namespace);
-        }
-        form.addField(field);
-
-        response.setFeatureNegotiationForm(form);
-        return response;
-    }
-
-
-    public IQ createError(String from, String to, String packetID, XMPPError xmppError) {
-        IQ iq = FileTransferNegotiator.createIQ(packetID, to, from, IQ.Type.ERROR);
-        iq.setError(xmppError);
-        return iq;
-    }
-
-    Packet initiateIncomingStream(Connection connection, StreamInitiation initiation) throws XMPPException {
-        StreamInitiation response = createInitiationAccept(initiation,
-                getNamespaces());
-
-        // establish collector to await response
-        PacketCollector collector = connection
-                .createPacketCollector(getInitiationPacketFilter(initiation.getFrom(), initiation.getSessionID()));
-        connection.sendPacket(response);
-
-        Packet streamMethodInitiation = collector
-                .nextResult(SmackConfiguration.getPacketReplyTimeout());
-        collector.cancel();
-        if (streamMethodInitiation == null) {
-            throw new XMPPException("No response from file transfer initiator");
-        }
-
-        return streamMethodInitiation;
-    }
-
-    /**
-     * Returns the packet filter that will return the initiation packet for the appropriate stream
-     * initiation.
-     *
-     * @param from     The initiator of the file transfer.
-     * @param streamID The stream ID related to the transfer.
-     * @return The <b><i>PacketFilter</b></i> that will return the packet relatable to the stream
-     *         initiation.
-     */
-    public abstract PacketFilter getInitiationPacketFilter(String from, String streamID);
-
-
-    abstract InputStream negotiateIncomingStream(Packet streamInitiation) throws XMPPException,
-            InterruptedException;
-
-    /**
-     * This method handles the file stream download negotiation process. The
-     * appropriate stream negotiator's initiate incoming stream is called after
-     * an appropriate file transfer method is selected. The manager will respond
-     * to the initiator with the selected means of transfer, then it will handle
-     * any negotiation specific to the particular transfer method. This method
-     * returns the InputStream, ready to transfer the file.
-     *
-     * @param initiation The initiation that triggered this download.
-     * @return After the negotiation process is complete, the InputStream to
-     *         write a file to is returned.
-     * @throws XMPPException If an error occurs during this process an XMPPException is
-     *                       thrown.
-     * @throws InterruptedException If thread is interrupted.
-     */
-    public abstract InputStream createIncomingStream(StreamInitiation initiation)
-            throws XMPPException, InterruptedException;
-
-    /**
-     * This method handles the file upload stream negotiation process. The
-     * particular stream negotiator is determined during the file transfer
-     * negotiation process. This method returns the OutputStream to transmit the
-     * file to the remote user.
-     *
-     * @param streamID  The streamID that uniquely identifies the file transfer.
-     * @param initiator The fully-qualified JID of the initiator of the file transfer.
-     * @param target    The fully-qualified JID of the target or receiver of the file
-     *                  transfer.
-     * @return The negotiated stream ready for data.
-     * @throws XMPPException If an error occurs during the negotiation process an
-     *                       exception will be thrown.
-     */
-    public abstract OutputStream createOutgoingStream(String streamID,
-            String initiator, String target) throws XMPPException;
-
-    /**
-     * Returns the XMPP namespace reserved for this particular type of file
-     * transfer.
-     *
-     * @return Returns the XMPP namespace reserved for this particular type of
-     *         file transfer.
-     */
-    public abstract String[] getNamespaces();
-
-    /**
-     * Cleanup any and all resources associated with this negotiator.
-     */
-    public abstract void cleanup();
-
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2006 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.filetransfer;
+
+import org.jivesoftware.smack.PacketCollector;
+import org.jivesoftware.smack.SmackConfiguration;
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.packet.XMPPError;
+import org.jivesoftware.smackx.Form;
+import org.jivesoftware.smackx.FormField;
+import org.jivesoftware.smackx.packet.DataForm;
+import org.jivesoftware.smackx.packet.StreamInitiation;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * After the file transfer negotiation process is completed according to
+ * JEP-0096, the negotiation process is passed off to a particular stream
+ * negotiator. The stream negotiator will then negotiate the chosen stream and
+ * return the stream to transfer the file.
+ *
+ * @author Alexander Wenckus
+ */
+public abstract class StreamNegotiator {
+
+    /**
+     * Creates the initiation acceptance packet to forward to the stream
+     * initiator.
+     *
+     * @param streamInitiationOffer The offer from the stream initiator to connect for a stream.
+     * @param namespaces            The namespace that relates to the accepted means of transfer.
+     * @return The response to be forwarded to the initiator.
+     */
+    public StreamInitiation createInitiationAccept(
+            StreamInitiation streamInitiationOffer, String[] namespaces)
+    {
+        StreamInitiation response = new StreamInitiation();
+        response.setTo(streamInitiationOffer.getFrom());
+        response.setFrom(streamInitiationOffer.getTo());
+        response.setType(IQ.Type.RESULT);
+        response.setPacketID(streamInitiationOffer.getPacketID());
+
+        DataForm form = new DataForm(Form.TYPE_SUBMIT);
+        FormField field = new FormField(
+                FileTransferNegotiator.STREAM_DATA_FIELD_NAME);
+        for (String namespace : namespaces) {
+            field.addValue(namespace);
+        }
+        form.addField(field);
+
+        response.setFeatureNegotiationForm(form);
+        return response;
+    }
+
+
+    public IQ createError(String from, String to, String packetID, XMPPError xmppError) {
+        IQ iq = FileTransferNegotiator.createIQ(packetID, to, from, IQ.Type.ERROR);
+        iq.setError(xmppError);
+        return iq;
+    }
+
+    Packet initiateIncomingStream(Connection connection, StreamInitiation initiation) throws XMPPException {
+        StreamInitiation response = createInitiationAccept(initiation,
+                getNamespaces());
+
+        // establish collector to await response
+        PacketCollector collector = connection
+                .createPacketCollector(getInitiationPacketFilter(initiation.getFrom(), initiation.getSessionID()));
+        connection.sendPacket(response);
+
+        Packet streamMethodInitiation = collector
+                .nextResult(SmackConfiguration.getPacketReplyTimeout());
+        collector.cancel();
+        if (streamMethodInitiation == null) {
+            throw new XMPPException("No response from file transfer initiator");
+        }
+
+        return streamMethodInitiation;
+    }
+
+    /**
+     * Returns the packet filter that will return the initiation packet for the appropriate stream
+     * initiation.
+     *
+     * @param from     The initiator of the file transfer.
+     * @param streamID The stream ID related to the transfer.
+     * @return The <b><i>PacketFilter</b></i> that will return the packet relatable to the stream
+     *         initiation.
+     */
+    public abstract PacketFilter getInitiationPacketFilter(String from, String streamID);
+
+
+    abstract InputStream negotiateIncomingStream(Packet streamInitiation) throws XMPPException,
+            InterruptedException;
+
+    /**
+     * This method handles the file stream download negotiation process. The
+     * appropriate stream negotiator's initiate incoming stream is called after
+     * an appropriate file transfer method is selected. The manager will respond
+     * to the initiator with the selected means of transfer, then it will handle
+     * any negotiation specific to the particular transfer method. This method
+     * returns the InputStream, ready to transfer the file.
+     *
+     * @param initiation The initiation that triggered this download.
+     * @return After the negotiation process is complete, the InputStream to
+     *         write a file to is returned.
+     * @throws XMPPException If an error occurs during this process an XMPPException is
+     *                       thrown.
+     * @throws InterruptedException If thread is interrupted.
+     */
+    public abstract InputStream createIncomingStream(StreamInitiation initiation)
+            throws XMPPException, InterruptedException;
+
+    /**
+     * This method handles the file upload stream negotiation process. The
+     * particular stream negotiator is determined during the file transfer
+     * negotiation process. This method returns the OutputStream to transmit the
+     * file to the remote user.
+     *
+     * @param streamID  The streamID that uniquely identifies the file transfer.
+     * @param initiator The fully-qualified JID of the initiator of the file transfer.
+     * @param target    The fully-qualified JID of the target or receiver of the file
+     *                  transfer.
+     * @return The negotiated stream ready for data.
+     * @throws XMPPException If an error occurs during the negotiation process an
+     *                       exception will be thrown.
+     */
+    public abstract OutputStream createOutgoingStream(String streamID,
+            String initiator, String target) throws XMPPException;
+
+    /**
+     * Returns the XMPP namespace reserved for this particular type of file
+     * transfer.
+     *
+     * @return Returns the XMPP namespace reserved for this particular type of
+     *         file transfer.
+     */
+    public abstract String[] getNamespaces();
+
+    /**
+     * Cleanup any and all resources associated with this negotiator.
+     */
+    public abstract void cleanup();
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/AdHocCommandData.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/AdHocCommandData.java
index bceffcd..37ba14d 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/AdHocCommandData.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/AdHocCommandData.java
@@ -1,279 +1,279 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2005-2008 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.packet;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smackx.commands.AdHocCommand;
-import org.jivesoftware.smackx.commands.AdHocCommand.Action;
-import org.jivesoftware.smackx.commands.AdHocCommand.SpecificErrorCondition;
-import org.jivesoftware.smackx.commands.AdHocCommandNote;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Represents the state and the request of the execution of an adhoc command.
- * 
- * @author Gabriel Guardincerri
- */
-public class AdHocCommandData extends IQ {
-
-    /* JID of the command host */
-    private String id;
-
-    /* Command name */
-    private String name;
-
-    /* Command identifier */
-    private String node;
-
-    /* Unique ID of the execution */
-    private String sessionID;
-
-    private List<AdHocCommandNote> notes = new ArrayList<AdHocCommandNote>();
-
-    private DataForm form;
-
-    /* Action request to be executed */
-    private AdHocCommand.Action action;
-
-    /* Current execution status */
-    private AdHocCommand.Status status;
-
-    private ArrayList<AdHocCommand.Action> actions = new ArrayList<AdHocCommand.Action>();
-
-    private AdHocCommand.Action executeAction;
-
-    private String lang;
-
-    public AdHocCommandData() {
-    }
-
-    @Override
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<command xmlns=\"http://jabber.org/protocol/commands\"");
-        buf.append(" node=\"").append(node).append("\"");
-        if (sessionID != null) {
-            if (!sessionID.equals("")) {
-                buf.append(" sessionid=\"").append(sessionID).append("\"");
-            }
-        }
-        if (status != null) {
-            buf.append(" status=\"").append(status).append("\"");
-        }
-        if (action != null) {
-            buf.append(" action=\"").append(action).append("\"");
-        }
-
-        if (lang != null) {
-            if (!lang.equals("")) {
-                buf.append(" lang=\"").append(lang).append("\"");
-            }
-        }
-        buf.append(">");
-
-        if (getType() == Type.RESULT) {
-            buf.append("<actions");
-
-            if (executeAction != null) {
-                buf.append(" execute=\"").append(executeAction).append("\"");
-            }
-            if (actions.size() == 0) {
-                buf.append("/>");
-            } else {
-                buf.append(">");
-
-                for (AdHocCommand.Action action : actions) {
-                    buf.append("<").append(action).append("/>");
-                }
-                buf.append("</actions>");
-            }
-        }
-
-        if (form != null) {
-            buf.append(form.toXML());
-        }
-
-        for (AdHocCommandNote note : notes) {
-            buf.append("<note type=\"").append(note.getType().toString()).append("\">");
-            buf.append(note.getValue());
-            buf.append("</note>");
-        }
-
-        // TODO ERRORS
-//        if (getError() != null) {
-//            buf.append(getError().toXML());
-//        }
-
-        buf.append("</command>");
-        return buf.toString();
-    }
-
-    /**
-     * Returns the JID of the command host.
-     *
-     * @return the JID of the command host.
-     */
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    /**
-     * Returns the human name of the command
-     *
-     * @return the name of the command.
-     */
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    /**
-     * Returns the identifier of the command
-     *
-     * @return the node.
-     */
-    public String getNode() {
-        return node;
-    }
-
-    public void setNode(String node) {
-        this.node = node;
-    }
-
-    /**
-     * Returns the list of notes that the command has.
-     *
-     * @return the notes.
-     */
-    public List<AdHocCommandNote> getNotes() {
-        return notes;
-    }
-
-    public void addNote(AdHocCommandNote note) {
-        this.notes.add(note);
-    }
-
-    public void remveNote(AdHocCommandNote note) {
-        this.notes.remove(note);
-    }
-
-    /**
-     * Returns the form of the command.
-     *
-     * @return the data form associated with the command.
-     */
-    public DataForm getForm() {
-        return form;
-    }
-
-    public void setForm(DataForm form) {
-        this.form = form;
-    }
-
-    /**
-     * Returns the action to execute. The action is set only on a request.
-     *
-     * @return the action to execute.
-     */
-    public AdHocCommand.Action getAction() {
-        return action;
-    }
-
-    public void setAction(AdHocCommand.Action action) {
-        this.action = action;
-    }
-
-    /**
-     * Returns the status of the execution.
-     *
-     * @return the status.
-     */
-    public AdHocCommand.Status getStatus() {
-        return status;
-    }
-
-    public void setStatus(AdHocCommand.Status status) {
-        this.status = status;
-    }
-
-    public List<Action> getActions() {
-        return actions;
-    }
-
-    public void addAction(Action action) {
-        actions.add(action);
-    }
-
-    public void setExecuteAction(Action executeAction) {
-        this.executeAction = executeAction;
-    }
-
-    public Action getExecuteAction() {
-        return executeAction;
-    }
-
-    public void setSessionID(String sessionID) {
-        this.sessionID = sessionID;
-    }
-
-    public String getSessionID() {
-        return sessionID;
-    }
-
-    public static class SpecificError implements PacketExtension {
-
-        public static final String namespace = "http://jabber.org/protocol/commands";
-        
-        public SpecificErrorCondition condition;
-        
-        public SpecificError(SpecificErrorCondition condition) {
-            this.condition = condition;
-        }
-        
-        public String getElementName() {
-            return condition.toString();
-        }
-        public String getNamespace() {
-            return namespace;
-        }
-
-        public SpecificErrorCondition getCondition() {
-            return condition;
-        }
-        
-        public String toXML() {
-            StringBuilder buf = new StringBuilder();
-            buf.append("<").append(getElementName());
-            buf.append(" xmlns=\"").append(getNamespace()).append("\"/>");
-            return buf.toString();
-        }
-    }
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2005-2008 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.packet;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smackx.commands.AdHocCommand;
+import org.jivesoftware.smackx.commands.AdHocCommand.Action;
+import org.jivesoftware.smackx.commands.AdHocCommand.SpecificErrorCondition;
+import org.jivesoftware.smackx.commands.AdHocCommandNote;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents the state and the request of the execution of an adhoc command.
+ * 
+ * @author Gabriel Guardincerri
+ */
+public class AdHocCommandData extends IQ {
+
+    /* JID of the command host */
+    private String id;
+
+    /* Command name */
+    private String name;
+
+    /* Command identifier */
+    private String node;
+
+    /* Unique ID of the execution */
+    private String sessionID;
+
+    private List<AdHocCommandNote> notes = new ArrayList<AdHocCommandNote>();
+
+    private DataForm form;
+
+    /* Action request to be executed */
+    private AdHocCommand.Action action;
+
+    /* Current execution status */
+    private AdHocCommand.Status status;
+
+    private ArrayList<AdHocCommand.Action> actions = new ArrayList<AdHocCommand.Action>();
+
+    private AdHocCommand.Action executeAction;
+
+    private String lang;
+
+    public AdHocCommandData() {
+    }
+
+    @Override
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("<command xmlns=\"http://jabber.org/protocol/commands\"");
+        buf.append(" node=\"").append(node).append("\"");
+        if (sessionID != null) {
+            if (!sessionID.equals("")) {
+                buf.append(" sessionid=\"").append(sessionID).append("\"");
+            }
+        }
+        if (status != null) {
+            buf.append(" status=\"").append(status).append("\"");
+        }
+        if (action != null) {
+            buf.append(" action=\"").append(action).append("\"");
+        }
+
+        if (lang != null) {
+            if (!lang.equals("")) {
+                buf.append(" lang=\"").append(lang).append("\"");
+            }
+        }
+        buf.append(">");
+
+        if (getType() == Type.RESULT) {
+            buf.append("<actions");
+
+            if (executeAction != null) {
+                buf.append(" execute=\"").append(executeAction).append("\"");
+            }
+            if (actions.size() == 0) {
+                buf.append("/>");
+            } else {
+                buf.append(">");
+
+                for (AdHocCommand.Action action : actions) {
+                    buf.append("<").append(action).append("/>");
+                }
+                buf.append("</actions>");
+            }
+        }
+
+        if (form != null) {
+            buf.append(form.toXML());
+        }
+
+        for (AdHocCommandNote note : notes) {
+            buf.append("<note type=\"").append(note.getType().toString()).append("\">");
+            buf.append(note.getValue());
+            buf.append("</note>");
+        }
+
+        // TODO ERRORS
+//        if (getError() != null) {
+//            buf.append(getError().toXML());
+//        }
+
+        buf.append("</command>");
+        return buf.toString();
+    }
+
+    /**
+     * Returns the JID of the command host.
+     *
+     * @return the JID of the command host.
+     */
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * Returns the human name of the command
+     *
+     * @return the name of the command.
+     */
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Returns the identifier of the command
+     *
+     * @return the node.
+     */
+    public String getNode() {
+        return node;
+    }
+
+    public void setNode(String node) {
+        this.node = node;
+    }
+
+    /**
+     * Returns the list of notes that the command has.
+     *
+     * @return the notes.
+     */
+    public List<AdHocCommandNote> getNotes() {
+        return notes;
+    }
+
+    public void addNote(AdHocCommandNote note) {
+        this.notes.add(note);
+    }
+
+    public void remveNote(AdHocCommandNote note) {
+        this.notes.remove(note);
+    }
+
+    /**
+     * Returns the form of the command.
+     *
+     * @return the data form associated with the command.
+     */
+    public DataForm getForm() {
+        return form;
+    }
+
+    public void setForm(DataForm form) {
+        this.form = form;
+    }
+
+    /**
+     * Returns the action to execute. The action is set only on a request.
+     *
+     * @return the action to execute.
+     */
+    public AdHocCommand.Action getAction() {
+        return action;
+    }
+
+    public void setAction(AdHocCommand.Action action) {
+        this.action = action;
+    }
+
+    /**
+     * Returns the status of the execution.
+     *
+     * @return the status.
+     */
+    public AdHocCommand.Status getStatus() {
+        return status;
+    }
+
+    public void setStatus(AdHocCommand.Status status) {
+        this.status = status;
+    }
+
+    public List<Action> getActions() {
+        return actions;
+    }
+
+    public void addAction(Action action) {
+        actions.add(action);
+    }
+
+    public void setExecuteAction(Action executeAction) {
+        this.executeAction = executeAction;
+    }
+
+    public Action getExecuteAction() {
+        return executeAction;
+    }
+
+    public void setSessionID(String sessionID) {
+        this.sessionID = sessionID;
+    }
+
+    public String getSessionID() {
+        return sessionID;
+    }
+
+    public static class SpecificError implements PacketExtension {
+
+        public static final String namespace = "http://jabber.org/protocol/commands";
+        
+        public SpecificErrorCondition condition;
+        
+        public SpecificError(SpecificErrorCondition condition) {
+            this.condition = condition;
+        }
+        
+        public String getElementName() {
+            return condition.toString();
+        }
+        public String getNamespace() {
+            return namespace;
+        }
+
+        public SpecificErrorCondition getCondition() {
+            return condition;
+        }
+        
+        public String toXML() {
+            StringBuilder buf = new StringBuilder();
+            buf.append("<").append(getElementName());
+            buf.append(" xmlns=\"").append(getNamespace()).append("\"/>");
+            return buf.toString();
+        }
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/AttentionExtension.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/AttentionExtension.java
index d86fa41..ad40851 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/AttentionExtension.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/AttentionExtension.java
@@ -1,100 +1,100 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2010 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.packet;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * A PacketExtension that implements XEP-0224: Attention
- * 
- * This extension is expected to be added to message stanzas of type 'headline.'
- * Please refer to the XEP for more implementation guidelines.
- * 
- * @author Guus der Kinderen, guus.der.kinderen@gmail.com
- * @see <a
- *      href="http://xmpp.org/extensions/xep-0224.html">XEP-0224:&nbsp;Attention</a>
- */
-public class AttentionExtension implements PacketExtension {
-
-    /**
-     * The XML element name of an 'attention' extension.
-     */
-    public static final String ELEMENT_NAME = "attention";
-
-    /**
-     * The namespace that qualifies the XML element of an 'attention' extension.
-     */
-    public static final String NAMESPACE = "urn:xmpp:attention:0";
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.jivesoftware.smack.packet.PacketExtension#getElementName()
-     */
-    public String getElementName() {
-        return ELEMENT_NAME;
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.jivesoftware.smack.packet.PacketExtension#getNamespace()
-     */
-    public String getNamespace() {
-        return NAMESPACE;
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.jivesoftware.smack.packet.PacketExtension#toXML()
-     */
-    public String toXML() {
-        final StringBuilder sb = new StringBuilder();
-        sb.append("<").append(getElementName()).append(" xmlns=\"").append(
-                getNamespace()).append("\"/>");
-        return sb.toString();
-    }
-
-    /**
-     * A {@link PacketExtensionProvider} for the {@link AttentionExtension}. As
-     * Attention elements have no state/information other than the element name
-     * and namespace, this implementation simply returns new instances of
-     * {@link AttentionExtension}.
-     * 
-     * @author Guus der Kinderen, guus.der.kinderen@gmail.com
-s     */
-    public static class Provider implements PacketExtensionProvider {
-
-        /*
-         * (non-Javadoc)
-         * 
-         * @see
-         * org.jivesoftware.smack.provider.PacketExtensionProvider#parseExtension
-         * (org.xmlpull.v1.XmlPullParser)
-         */
-        public PacketExtension parseExtension(XmlPullParser arg0)
-                throws Exception {
-            return new AttentionExtension();
-        }
-    }
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2010 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.packet;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * A PacketExtension that implements XEP-0224: Attention
+ * 
+ * This extension is expected to be added to message stanzas of type 'headline.'
+ * Please refer to the XEP for more implementation guidelines.
+ * 
+ * @author Guus der Kinderen, guus.der.kinderen@gmail.com
+ * @see <a
+ *      href="http://xmpp.org/extensions/xep-0224.html">XEP-0224:&nbsp;Attention</a>
+ */
+public class AttentionExtension implements PacketExtension {
+
+    /**
+     * The XML element name of an 'attention' extension.
+     */
+    public static final String ELEMENT_NAME = "attention";
+
+    /**
+     * The namespace that qualifies the XML element of an 'attention' extension.
+     */
+    public static final String NAMESPACE = "urn:xmpp:attention:0";
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.jivesoftware.smack.packet.PacketExtension#getElementName()
+     */
+    public String getElementName() {
+        return ELEMENT_NAME;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.jivesoftware.smack.packet.PacketExtension#getNamespace()
+     */
+    public String getNamespace() {
+        return NAMESPACE;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.jivesoftware.smack.packet.PacketExtension#toXML()
+     */
+    public String toXML() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("<").append(getElementName()).append(" xmlns=\"").append(
+                getNamespace()).append("\"/>");
+        return sb.toString();
+    }
+
+    /**
+     * A {@link PacketExtensionProvider} for the {@link AttentionExtension}. As
+     * Attention elements have no state/information other than the element name
+     * and namespace, this implementation simply returns new instances of
+     * {@link AttentionExtension}.
+     * 
+     * @author Guus der Kinderen, guus.der.kinderen@gmail.com
+s     */
+    public static class Provider implements PacketExtensionProvider {
+
+        /*
+         * (non-Javadoc)
+         * 
+         * @see
+         * org.jivesoftware.smack.provider.PacketExtensionProvider#parseExtension
+         * (org.xmlpull.v1.XmlPullParser)
+         */
+        public PacketExtension parseExtension(XmlPullParser arg0)
+                throws Exception {
+            return new AttentionExtension();
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/ChatStateExtension.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/ChatStateExtension.java
index ecc6acc..a9fbbb4 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/ChatStateExtension.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/ChatStateExtension.java
@@ -1,73 +1,73 @@
-/**
- * $RCSfile$
- * $Revision: 2407 $
- * $Date: 2004-11-02 15:37:00 -0800 (Tue, 02 Nov 2004) $
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.packet;
-
-import org.jivesoftware.smackx.ChatState;
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * Represents a chat state which is an extension to message packets which is used to indicate
- * the current status of a chat participant.
- *
- * @author Alexander Wenckus
- * @see org.jivesoftware.smackx.ChatState
- */
-public class ChatStateExtension implements PacketExtension {
-
-    private ChatState state;
-
-    /**
-     * Default constructor. The argument provided is the state that the extension will represent.
-     *
-     * @param state the state that the extension represents.
-     */
-    public ChatStateExtension(ChatState state) {
-        this.state = state;
-    }
-
-    public String getElementName() {
-        return state.name();
-    }
-
-    public String getNamespace() {
-        return "http://jabber.org/protocol/chatstates";
-    }
-
-    public String toXML() {
-        return "<" + getElementName() + " xmlns=\"" + getNamespace() + "\" />";
-    }
-
-    public static class Provider implements PacketExtensionProvider {
-
-        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
-            ChatState state;
-            try {
-                state = ChatState.valueOf(parser.getName());
-            }
-            catch (Exception ex) {
-                state = ChatState.active;
-            }
-            return new ChatStateExtension(state);
-        }
-    }
-}
+/**
+ * $RCSfile$
+ * $Revision: 2407 $
+ * $Date: 2004-11-02 15:37:00 -0800 (Tue, 02 Nov 2004) $
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.packet;
+
+import org.jivesoftware.smackx.ChatState;
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * Represents a chat state which is an extension to message packets which is used to indicate
+ * the current status of a chat participant.
+ *
+ * @author Alexander Wenckus
+ * @see org.jivesoftware.smackx.ChatState
+ */
+public class ChatStateExtension implements PacketExtension {
+
+    private ChatState state;
+
+    /**
+     * Default constructor. The argument provided is the state that the extension will represent.
+     *
+     * @param state the state that the extension represents.
+     */
+    public ChatStateExtension(ChatState state) {
+        this.state = state;
+    }
+
+    public String getElementName() {
+        return state.name();
+    }
+
+    public String getNamespace() {
+        return "http://jabber.org/protocol/chatstates";
+    }
+
+    public String toXML() {
+        return "<" + getElementName() + " xmlns=\"" + getNamespace() + "\" />";
+    }
+
+    public static class Provider implements PacketExtensionProvider {
+
+        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
+            ChatState state;
+            try {
+                state = ChatState.valueOf(parser.getName());
+            }
+            catch (Exception ex) {
+                state = ChatState.active;
+            }
+            return new ChatStateExtension(state);
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/DelayInfo.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/DelayInfo.java
index f5ba78f..5e8f11a 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/DelayInfo.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/DelayInfo.java
@@ -1,105 +1,105 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.packet;
-
-import java.util.Date;
-
-import org.jivesoftware.smack.util.StringUtils;
-
-/**
- * A decorator for the {@link DelayInformation} class to transparently support
- * both the new <b>Delay Delivery</b> specification <a href="http://xmpp.org/extensions/xep-0203.html">XEP-0203</a> and 
- * the old one <a href="http://xmpp.org/extensions/xep-0091.html">XEP-0091</a>.
- * 
- * Existing code can be backward compatible. 
- * 
- * @author Robin Collier
- */
-public class DelayInfo extends DelayInformation
-{
-    
-	DelayInformation wrappedInfo;
-
-        /**
-         * Creates a new instance with given delay information. 
-         * @param delay the delay information
-         */
-	public DelayInfo(DelayInformation delay)
-	{
-		super(delay.getStamp());
-		wrappedInfo = delay;
-	}
-	
-	@Override
-	public String getFrom()
-	{
-		return wrappedInfo.getFrom();
-	}
-
-	@Override
-	public String getReason()
-	{
-		return wrappedInfo.getReason();
-	}
-
-	@Override
-	public Date getStamp()
-	{
-		return wrappedInfo.getStamp();
-	}
-
-	@Override
-	public void setFrom(String from)
-	{
-		wrappedInfo.setFrom(from);
-	}
-
-	@Override
-	public void setReason(String reason)
-	{
-		wrappedInfo.setReason(reason);
-	}
-
-	@Override
-	public String getElementName()
-	{
-		return "delay";
-	}
-
-	@Override
-	public String getNamespace()
-	{
-		return "urn:xmpp:delay";
-	}
-
-	@Override
-    public String toXML() {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append(
-                "\"");
-        buf.append(" stamp=\"");
-        buf.append(StringUtils.formatXEP0082Date(getStamp()));
-        buf.append("\"");
-        if (getFrom() != null && getFrom().length() > 0) {
-            buf.append(" from=\"").append(getFrom()).append("\"");
-        }
-        buf.append(">");
-        if (getReason() != null && getReason().length() > 0) {
-            buf.append(getReason());
-        }
-        buf.append("</").append(getElementName()).append(">");
-        return buf.toString();
-    }
-	
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.packet;
+
+import java.util.Date;
+
+import org.jivesoftware.smack.util.StringUtils;
+
+/**
+ * A decorator for the {@link DelayInformation} class to transparently support
+ * both the new <b>Delay Delivery</b> specification <a href="http://xmpp.org/extensions/xep-0203.html">XEP-0203</a> and 
+ * the old one <a href="http://xmpp.org/extensions/xep-0091.html">XEP-0091</a>.
+ * 
+ * Existing code can be backward compatible. 
+ * 
+ * @author Robin Collier
+ */
+public class DelayInfo extends DelayInformation
+{
+    
+	DelayInformation wrappedInfo;
+
+        /**
+         * Creates a new instance with given delay information. 
+         * @param delay the delay information
+         */
+	public DelayInfo(DelayInformation delay)
+	{
+		super(delay.getStamp());
+		wrappedInfo = delay;
+	}
+	
+	@Override
+	public String getFrom()
+	{
+		return wrappedInfo.getFrom();
+	}
+
+	@Override
+	public String getReason()
+	{
+		return wrappedInfo.getReason();
+	}
+
+	@Override
+	public Date getStamp()
+	{
+		return wrappedInfo.getStamp();
+	}
+
+	@Override
+	public void setFrom(String from)
+	{
+		wrappedInfo.setFrom(from);
+	}
+
+	@Override
+	public void setReason(String reason)
+	{
+		wrappedInfo.setReason(reason);
+	}
+
+	@Override
+	public String getElementName()
+	{
+		return "delay";
+	}
+
+	@Override
+	public String getNamespace()
+	{
+		return "urn:xmpp:delay";
+	}
+
+	@Override
+    public String toXML() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append(
+                "\"");
+        buf.append(" stamp=\"");
+        buf.append(StringUtils.formatXEP0082Date(getStamp()));
+        buf.append("\"");
+        if (getFrom() != null && getFrom().length() > 0) {
+            buf.append(" from=\"").append(getFrom()).append("\"");
+        }
+        buf.append(">");
+        if (getReason() != null && getReason().length() > 0) {
+            buf.append(getReason());
+        }
+        buf.append("</").append(getElementName()).append(">");
+        return buf.toString();
+    }
+	
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/Header.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/Header.java
index 3fa8386..44533f8 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/Header.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/Header.java
@@ -1,59 +1,59 @@
-/*
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.packet;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-
-/**
- * Represents a <b>Header</b> entry as specified by the <a href="http://xmpp.org/extensions/xep-031.html">Stanza Headers and Internet Metadata (SHIM)</a>
-
- * @author Robin Collier
- */
-public class Header implements PacketExtension
-{
-	private String name;
-	private String value;
-	
-	public Header(String name, String value)
-	{
-		this.name = name;
-		this.value = value;
-	}
-	
-	public String getName()
-	{
-		return name;
-	}
-
-	public String getValue()
-	{
-		return value;
-	}
-
-	public String getElementName()
-	{
-		return "header";
-	}
-
-	public String getNamespace()
-	{
-		return HeadersExtension.NAMESPACE;
-	}
-
-	public String toXML()
-	{
-		return "<header name='" + name + "'>" + value + "</header>";
-	}
-
-}
+/*
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.packet;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+
+/**
+ * Represents a <b>Header</b> entry as specified by the <a href="http://xmpp.org/extensions/xep-031.html">Stanza Headers and Internet Metadata (SHIM)</a>
+
+ * @author Robin Collier
+ */
+public class Header implements PacketExtension
+{
+	private String name;
+	private String value;
+	
+	public Header(String name, String value)
+	{
+		this.name = name;
+		this.value = value;
+	}
+	
+	public String getName()
+	{
+		return name;
+	}
+
+	public String getValue()
+	{
+		return value;
+	}
+
+	public String getElementName()
+	{
+		return "header";
+	}
+
+	public String getNamespace()
+	{
+		return HeadersExtension.NAMESPACE;
+	}
+
+	public String toXML()
+	{
+		return "<header name='" + name + "'>" + value + "</header>";
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/HeadersExtension.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/HeadersExtension.java
index 78564db..03fde17 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/HeadersExtension.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/HeadersExtension.java
@@ -1,69 +1,69 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.packet;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-
-/**
- * Extension representing a list of headers as specified in <a href="http://xmpp.org/extensions/xep-0131">Stanza Headers and Internet Metadata (SHIM)</a>
- * 
- * @see Header
- * 
- * @author Robin Collier
- */
-public class HeadersExtension implements PacketExtension
-{
-	public static final String NAMESPACE = "http://jabber.org/protocol/shim";
-	
-	private Collection<Header> headers = Collections.EMPTY_LIST;
-	
-	public HeadersExtension(Collection<Header> headerList)
-	{
-		if (headerList != null)
-			headers = headerList;
-	}
-	
-	public Collection<Header> getHeaders()
-	{
-		return headers;
-	}
-
-	public String getElementName()
-	{
-		return "headers";
-	}
-
-	public String getNamespace()
-	{
-		return NAMESPACE;
-	}
-
-	public String toXML()
-	{
-		StringBuilder builder = new StringBuilder("<" + getElementName() + " xmlns='" + getNamespace() + "'>");
-		
-		for (Header header : headers)
-		{
-			builder.append(header.toXML());
-		}
-		builder.append("</" + getElementName() + '>');
-
-		return builder.toString();
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.packet;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+
+/**
+ * Extension representing a list of headers as specified in <a href="http://xmpp.org/extensions/xep-0131">Stanza Headers and Internet Metadata (SHIM)</a>
+ * 
+ * @see Header
+ * 
+ * @author Robin Collier
+ */
+public class HeadersExtension implements PacketExtension
+{
+	public static final String NAMESPACE = "http://jabber.org/protocol/shim";
+	
+	private Collection<Header> headers = Collections.EMPTY_LIST;
+	
+	public HeadersExtension(Collection<Header> headerList)
+	{
+		if (headerList != null)
+			headers = headerList;
+	}
+	
+	public Collection<Header> getHeaders()
+	{
+		return headers;
+	}
+
+	public String getElementName()
+	{
+		return "headers";
+	}
+
+	public String getNamespace()
+	{
+		return NAMESPACE;
+	}
+
+	public String toXML()
+	{
+		StringBuilder builder = new StringBuilder("<" + getElementName() + " xmlns='" + getNamespace() + "'>");
+		
+		for (Header header : headers)
+		{
+			builder.append(header.toXML());
+		}
+		builder.append("</" + getElementName() + '>');
+
+		return builder.toString();
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/Nick.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/Nick.java
index 9a64eaa..61d7912 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/Nick.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/Nick.java
@@ -1,112 +1,112 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.packet;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * A minimalistic implementation of a {@link PacketExtension} for nicknames.
- * 
- * @author Guus der Kinderen, guus.der.kinderen@gmail.com
- * @see <a href="http://xmpp.org/extensions/xep-0172.html">XEP-0172: User Nickname</a>
- */
-public class Nick implements PacketExtension {
-
-	public static final String NAMESPACE = "http://jabber.org/protocol/nick";
-
-	public static final String ELEMENT_NAME = "nick";
-
-	private String name = null;
-
-	public Nick(String name) {
-		this.name = name;
-	}
-
-	/**
-	 * The value of this nickname
-	 * 
-	 * @return the nickname
-	 */
-	public String getName() {
-		return name;
-	}
-
-	/**
-	 * Sets the value of this nickname
-	 * 
-	 * @param name
-	 *            the name to set
-	 */
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.jivesoftware.smack.packet.PacketExtension#getElementName()
-	 */
-	public String getElementName() {
-		return ELEMENT_NAME;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.jivesoftware.smack.packet.PacketExtension#getNamespace()
-	 */
-	public String getNamespace() {
-		return NAMESPACE;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.jivesoftware.smack.packet.PacketExtension#toXML()
-	 */
-	public String toXML() {
-		final StringBuilder buf = new StringBuilder();
-
-		buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(
-				NAMESPACE).append("\">");
-		buf.append(getName());
-		buf.append("</").append(ELEMENT_NAME).append('>');
-
-		return buf.toString();
-	}
-
-	public static class Provider implements PacketExtensionProvider {
-
-		public PacketExtension parseExtension(XmlPullParser parser)
-				throws Exception {
-			
-            parser.next();
-			final String name = parser.getText();
-
-			// Advance to end of extension.
-			while(parser.getEventType() != XmlPullParser.END_TAG) {
-				parser.next();
-			}
-
-			return new Nick(name);
-		}
-	}
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.packet;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * A minimalistic implementation of a {@link PacketExtension} for nicknames.
+ * 
+ * @author Guus der Kinderen, guus.der.kinderen@gmail.com
+ * @see <a href="http://xmpp.org/extensions/xep-0172.html">XEP-0172: User Nickname</a>
+ */
+public class Nick implements PacketExtension {
+
+	public static final String NAMESPACE = "http://jabber.org/protocol/nick";
+
+	public static final String ELEMENT_NAME = "nick";
+
+	private String name = null;
+
+	public Nick(String name) {
+		this.name = name;
+	}
+
+	/**
+	 * The value of this nickname
+	 * 
+	 * @return the nickname
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * Sets the value of this nickname
+	 * 
+	 * @param name
+	 *            the name to set
+	 */
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jivesoftware.smack.packet.PacketExtension#getElementName()
+	 */
+	public String getElementName() {
+		return ELEMENT_NAME;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jivesoftware.smack.packet.PacketExtension#getNamespace()
+	 */
+	public String getNamespace() {
+		return NAMESPACE;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jivesoftware.smack.packet.PacketExtension#toXML()
+	 */
+	public String toXML() {
+		final StringBuilder buf = new StringBuilder();
+
+		buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(
+				NAMESPACE).append("\">");
+		buf.append(getName());
+		buf.append("</").append(ELEMENT_NAME).append('>');
+
+		return buf.toString();
+	}
+
+	public static class Provider implements PacketExtensionProvider {
+
+		public PacketExtension parseExtension(XmlPullParser parser)
+				throws Exception {
+			
+            parser.next();
+			final String name = parser.getText();
+
+			// Advance to end of extension.
+			while(parser.getEventType() != XmlPullParser.END_TAG) {
+				parser.next();
+			}
+
+			return new Nick(name);
+		}
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/SharedGroupsInfo.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/SharedGroupsInfo.java
index 59bd98e..f4f1c82 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/SharedGroupsInfo.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/SharedGroupsInfo.java
@@ -17,76 +17,76 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jivesoftware.smackx.packet;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * IQ packet used for discovering the user's shared groups and for getting the answer back
- * from the server.<p>
- *
- * Important note: This functionality is not part of the XMPP spec and it will only work
- * with Wildfire.
- *
- * @author Gaston Dombiak
- */
-public class SharedGroupsInfo extends IQ {
-
-    private List<String> groups = new ArrayList<String>();
-
-    /**
-     * Returns a collection with the shared group names returned from the server.
-     *
-     * @return collection with the shared group names returned from the server.
-     */
-    public List<String> getGroups() {
-        return groups;
-    }
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<sharedgroup xmlns=\"http://www.jivesoftware.org/protocol/sharedgroup\">");
-        for (Iterator<String> it=groups.iterator(); it.hasNext();) {
-            buf.append("<group>").append(it.next()).append("</group>");
-        }
-        buf.append("</sharedgroup>");
-        return buf.toString();
-    }
-
-    /**
-     * Internal Search service Provider.
-     */
-    public static class Provider implements IQProvider {
-
-        /**
-         * Provider Constructor.
-         */
-        public Provider() {
-            super();
-        }
-
-        public IQ parseIQ(XmlPullParser parser) throws Exception {
-            SharedGroupsInfo groupsInfo = new SharedGroupsInfo();
-
-            boolean done = false;
-            while (!done) {
-                int eventType = parser.next();
-                if (eventType == XmlPullParser.START_TAG && parser.getName().equals("group")) {
-                    groupsInfo.getGroups().add(parser.nextText());
-                }
-                else if (eventType == XmlPullParser.END_TAG) {
-                    if (parser.getName().equals("sharedgroup")) {
-                        done = true;
-                    }
-                }
-            }
-            return groupsInfo;
-        }
-    }
-}
+package org.jivesoftware.smackx.packet;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * IQ packet used for discovering the user's shared groups and for getting the answer back
+ * from the server.<p>
+ *
+ * Important note: This functionality is not part of the XMPP spec and it will only work
+ * with Wildfire.
+ *
+ * @author Gaston Dombiak
+ */
+public class SharedGroupsInfo extends IQ {
+
+    private List<String> groups = new ArrayList<String>();
+
+    /**
+     * Returns a collection with the shared group names returned from the server.
+     *
+     * @return collection with the shared group names returned from the server.
+     */
+    public List<String> getGroups() {
+        return groups;
+    }
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("<sharedgroup xmlns=\"http://www.jivesoftware.org/protocol/sharedgroup\">");
+        for (Iterator<String> it=groups.iterator(); it.hasNext();) {
+            buf.append("<group>").append(it.next()).append("</group>");
+        }
+        buf.append("</sharedgroup>");
+        return buf.toString();
+    }
+
+    /**
+     * Internal Search service Provider.
+     */
+    public static class Provider implements IQProvider {
+
+        /**
+         * Provider Constructor.
+         */
+        public Provider() {
+            super();
+        }
+
+        public IQ parseIQ(XmlPullParser parser) throws Exception {
+            SharedGroupsInfo groupsInfo = new SharedGroupsInfo();
+
+            boolean done = false;
+            while (!done) {
+                int eventType = parser.next();
+                if (eventType == XmlPullParser.START_TAG && parser.getName().equals("group")) {
+                    groupsInfo.getGroups().add(parser.nextText());
+                }
+                else if (eventType == XmlPullParser.END_TAG) {
+                    if (parser.getName().equals("sharedgroup")) {
+                        done = true;
+                    }
+                }
+            }
+            return groupsInfo;
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/StreamInitiation.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/StreamInitiation.java
index 7856c1b..e9b6681 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/StreamInitiation.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/StreamInitiation.java
@@ -1,419 +1,419 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2006 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.packet;
-
-import java.util.Date;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.util.StringUtils;
-
-/**
- * The process by which two entities initiate a stream.
- *
- * @author Alexander Wenckus
- */
-public class StreamInitiation extends IQ {
-
-    private String id;
-
-    private String mimeType;
-
-    private File file;
-
-    private Feature featureNegotiation;
-
-    /**
-     * The "id" attribute is an opaque identifier. This attribute MUST be
-     * present on type='set', and MUST be a valid string. This SHOULD NOT be
-     * sent back on type='result', since the <iq/> "id" attribute provides the
-     * only context needed. This value is generated by the Sender, and the same
-     * value MUST be used throughout a session when talking to the Receiver.
-     *
-     * @param id The "id" attribute.
-     */
-    public void setSesssionID(final String id) {
-        this.id = id;
-    }
-
-    /**
-     * Uniquely identifies a stream initiation to the recipient.
-     *
-     * @return The "id" attribute.
-     * @see #setSesssionID(String)
-     */
-    public String getSessionID() {
-        return id;
-    }
-
-    /**
-     * The "mime-type" attribute identifies the MIME-type for the data across
-     * the stream. This attribute MUST be a valid MIME-type as registered with
-     * the Internet Assigned Numbers Authority (IANA) [3] (specifically, as
-     * listed at <http://www.iana.org/assignments/media-types>). During
-     * negotiation, this attribute SHOULD be present, and is otherwise not
-     * required. If not included during negotiation, its value is assumed to be
-     * "binary/octect-stream".
-     *
-     * @param mimeType The valid mime-type.
-     */
-    public void setMimeType(final String mimeType) {
-        this.mimeType = mimeType;
-    }
-
-    /**
-     * Identifies the type of file that is desired to be transfered.
-     *
-     * @return The mime-type.
-     * @see #setMimeType(String)
-     */
-    public String getMimeType() {
-        return mimeType;
-    }
-
-    /**
-     * Sets the file which contains the information pertaining to the file to be
-     * transfered.
-     *
-     * @param file The file identified by the stream initiator to be sent.
-     */
-    public void setFile(final File file) {
-        this.file = file;
-    }
-
-    /**
-     * Returns the file containing the information about the request.
-     *
-     * @return Returns the file containing the information about the request.
-     */
-    public File getFile() {
-        return file;
-    }
-
-    /**
-     * Sets the data form which contains the valid methods of stream neotiation
-     * and transfer.
-     *
-     * @param form The dataform containing the methods.
-     */
-    public void setFeatureNegotiationForm(final DataForm form) {
-        this.featureNegotiation = new Feature(form);
-    }
-
-    /**
-     * Returns the data form which contains the valid methods of stream
-     * neotiation and transfer.
-     *
-     * @return Returns the data form which contains the valid methods of stream
-     *         neotiation and transfer.
-     */
-    public DataForm getFeatureNegotiationForm() {
-        return featureNegotiation.getData();
-    }
-
-    /*
-      * (non-Javadoc)
-      *
-      * @see org.jivesoftware.smack.packet.IQ#getChildElementXML()
-      */
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-        if (this.getType().equals(IQ.Type.SET)) {
-            buf.append("<si xmlns=\"http://jabber.org/protocol/si\" ");
-            if (getSessionID() != null) {
-                buf.append("id=\"").append(getSessionID()).append("\" ");
-            }
-            if (getMimeType() != null) {
-                buf.append("mime-type=\"").append(getMimeType()).append("\" ");
-            }
-            buf
-                    .append("profile=\"http://jabber.org/protocol/si/profile/file-transfer\">");
-
-            // Add the file section if there is one.
-            String fileXML = file.toXML();
-            if (fileXML != null) {
-                buf.append(fileXML);
-            }
-        }
-        else if (this.getType().equals(IQ.Type.RESULT)) {
-            buf.append("<si xmlns=\"http://jabber.org/protocol/si\">");
-        }
-        else {
-            throw new IllegalArgumentException("IQ Type not understood");
-        }
-        if (featureNegotiation != null) {
-            buf.append(featureNegotiation.toXML());
-        }
-        buf.append("</si>");
-        return buf.toString();
-    }
-
-    /**
-     * <ul>
-     * <li>size: The size, in bytes, of the data to be sent.</li>
-     * <li>name: The name of the file that the Sender wishes to send.</li>
-     * <li>date: The last modification time of the file. This is specified
-     * using the DateTime profile as described in Jabber Date and Time Profiles.</li>
-     * <li>hash: The MD5 sum of the file contents.</li>
-     * </ul>
-     * <p/>
-     * <p/>
-     * &lt;desc&gt; is used to provide a sender-generated description of the
-     * file so the receiver can better understand what is being sent. It MUST
-     * NOT be sent in the result.
-     * <p/>
-     * <p/>
-     * When &lt;range&gt; is sent in the offer, it should have no attributes.
-     * This signifies that the sender can do ranged transfers. When a Stream
-     * Initiation result is sent with the <range> element, it uses these
-     * attributes:
-     * <p/>
-     * <ul>
-     * <li>offset: Specifies the position, in bytes, to start transferring the
-     * file data from. This defaults to zero (0) if not specified.</li>
-     * <li>length - Specifies the number of bytes to retrieve starting at
-     * offset. This defaults to the length of the file from offset to the end.</li>
-     * </ul>
-     * <p/>
-     * <p/>
-     * Both attributes are OPTIONAL on the &lt;range&gt; element. Sending no
-     * attributes is synonymous with not sending the &lt;range&gt; element. When
-     * no &lt;range&gt; element is sent in the Stream Initiation result, the
-     * Sender MUST send the complete file starting at offset 0. More generally,
-     * data is sent over the stream byte for byte starting at the offset
-     * position for the length specified.
-     *
-     * @author Alexander Wenckus
-     */
-    public static class File implements PacketExtension {
-
-        private final String name;
-
-        private final long size;
-
-        private String hash;
-
-        private Date date;
-
-        private String desc;
-
-        private boolean isRanged;
-
-        /**
-         * Constructor providing the name of the file and its size.
-         *
-         * @param name The name of the file.
-         * @param size The size of the file in bytes.
-         */
-        public File(final String name, final long size) {
-            if (name == null) {
-                throw new NullPointerException("name cannot be null");
-            }
-
-            this.name = name;
-            this.size = size;
-        }
-
-        /**
-         * Returns the file's name.
-         *
-         * @return Returns the file's name.
-         */
-        public String getName() {
-            return name;
-        }
-
-        /**
-         * Returns the file's size.
-         *
-         * @return Returns the file's size.
-         */
-        public long getSize() {
-            return size;
-        }
-
-        /**
-         * Sets the MD5 sum of the file's contents
-         *
-         * @param hash The MD5 sum of the file's contents.
-         */
-        public void setHash(final String hash) {
-            this.hash = hash;
-        }
-
-        /**
-         * Returns the MD5 sum of the file's contents
-         *
-         * @return Returns the MD5 sum of the file's contents
-         */
-        public String getHash() {
-            return hash;
-        }
-
-        /**
-         * Sets the date that the file was last modified.
-         *
-         * @param date The date that the file was last modified.
-         */
-        public void setDate(Date date) {
-            this.date = date;
-        }
-
-        /**
-         * Returns the date that the file was last modified.
-         *
-         * @return Returns the date that the file was last modified.
-         */
-        public Date getDate() {
-            return date;
-        }
-
-        /**
-         * Sets the description of the file.
-         *
-         * @param desc The description of the file so that the file reciever can
-         *             know what file it is.
-         */
-        public void setDesc(final String desc) {
-            this.desc = desc;
-        }
-
-        /**
-         * Returns the description of the file.
-         *
-         * @return Returns the description of the file.
-         */
-        public String getDesc() {
-            return desc;
-        }
-
-        /**
-         * True if a range can be provided and false if it cannot.
-         *
-         * @param isRanged True if a range can be provided and false if it cannot.
-         */
-        public void setRanged(final boolean isRanged) {
-            this.isRanged = isRanged;
-        }
-
-        /**
-         * Returns whether or not the initiator can support a range for the file
-         * tranfer.
-         *
-         * @return Returns whether or not the initiator can support a range for
-         *         the file tranfer.
-         */
-        public boolean isRanged() {
-            return isRanged;
-        }
-
-        public String getElementName() {
-            return "file";
-        }
-
-        public String getNamespace() {
-            return "http://jabber.org/protocol/si/profile/file-transfer";
-        }
-
-        public String toXML() {
-            StringBuilder buffer = new StringBuilder();
-
-            buffer.append("<").append(getElementName()).append(" xmlns=\"")
-                    .append(getNamespace()).append("\" ");
-
-            if (getName() != null) {
-                buffer.append("name=\"").append(StringUtils.escapeForXML(getName())).append("\" ");
-            }
-
-            if (getSize() > 0) {
-                buffer.append("size=\"").append(getSize()).append("\" ");
-            }
-
-            if (getDate() != null) {
-                buffer.append("date=\"").append(StringUtils.formatXEP0082Date(date)).append("\" ");
-            }
-
-            if (getHash() != null) {
-                buffer.append("hash=\"").append(getHash()).append("\" ");
-            }
-
-            if ((desc != null && desc.length() > 0) || isRanged) {
-                buffer.append(">");
-                if (getDesc() != null && desc.length() > 0) {
-                    buffer.append("<desc>").append(StringUtils.escapeForXML(getDesc())).append("</desc>");
-                }
-                if (isRanged()) {
-                    buffer.append("<range/>");
-                }
-                buffer.append("</").append(getElementName()).append(">");
-            }
-            else {
-                buffer.append("/>");
-            }
-            return buffer.toString();
-        }
-    }
-
-    /**
-     * The feature negotiation portion of the StreamInitiation packet.
-     *
-     * @author Alexander Wenckus
-     *
-     */
-    public class Feature implements PacketExtension {
-
-        private final DataForm data;
-
-        /**
-         * The dataform can be provided as part of the constructor.
-         *
-         * @param data The dataform.
-         */
-        public Feature(final DataForm data) {
-            this.data = data;
-        }
-
-        /**
-         * Returns the dataform associated with the feature negotiation.
-         *
-         * @return Returns the dataform associated with the feature negotiation.
-         */
-        public DataForm getData() {
-            return data;
-        }
-
-        public String getNamespace() {
-            return "http://jabber.org/protocol/feature-neg";
-        }
-
-        public String getElementName() {
-            return "feature";
-        }
-
-        public String toXML() {
-            StringBuilder buf = new StringBuilder();
-            buf
-                    .append("<feature xmlns=\"http://jabber.org/protocol/feature-neg\">");
-			buf.append(data.toXML());
-			buf.append("</feature>");
-			return buf.toString();
-		}
-	}
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2006 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.packet;
+
+import java.util.Date;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.util.StringUtils;
+
+/**
+ * The process by which two entities initiate a stream.
+ *
+ * @author Alexander Wenckus
+ */
+public class StreamInitiation extends IQ {
+
+    private String id;
+
+    private String mimeType;
+
+    private File file;
+
+    private Feature featureNegotiation;
+
+    /**
+     * The "id" attribute is an opaque identifier. This attribute MUST be
+     * present on type='set', and MUST be a valid string. This SHOULD NOT be
+     * sent back on type='result', since the <iq/> "id" attribute provides the
+     * only context needed. This value is generated by the Sender, and the same
+     * value MUST be used throughout a session when talking to the Receiver.
+     *
+     * @param id The "id" attribute.
+     */
+    public void setSesssionID(final String id) {
+        this.id = id;
+    }
+
+    /**
+     * Uniquely identifies a stream initiation to the recipient.
+     *
+     * @return The "id" attribute.
+     * @see #setSesssionID(String)
+     */
+    public String getSessionID() {
+        return id;
+    }
+
+    /**
+     * The "mime-type" attribute identifies the MIME-type for the data across
+     * the stream. This attribute MUST be a valid MIME-type as registered with
+     * the Internet Assigned Numbers Authority (IANA) [3] (specifically, as
+     * listed at <http://www.iana.org/assignments/media-types>). During
+     * negotiation, this attribute SHOULD be present, and is otherwise not
+     * required. If not included during negotiation, its value is assumed to be
+     * "binary/octect-stream".
+     *
+     * @param mimeType The valid mime-type.
+     */
+    public void setMimeType(final String mimeType) {
+        this.mimeType = mimeType;
+    }
+
+    /**
+     * Identifies the type of file that is desired to be transfered.
+     *
+     * @return The mime-type.
+     * @see #setMimeType(String)
+     */
+    public String getMimeType() {
+        return mimeType;
+    }
+
+    /**
+     * Sets the file which contains the information pertaining to the file to be
+     * transfered.
+     *
+     * @param file The file identified by the stream initiator to be sent.
+     */
+    public void setFile(final File file) {
+        this.file = file;
+    }
+
+    /**
+     * Returns the file containing the information about the request.
+     *
+     * @return Returns the file containing the information about the request.
+     */
+    public File getFile() {
+        return file;
+    }
+
+    /**
+     * Sets the data form which contains the valid methods of stream neotiation
+     * and transfer.
+     *
+     * @param form The dataform containing the methods.
+     */
+    public void setFeatureNegotiationForm(final DataForm form) {
+        this.featureNegotiation = new Feature(form);
+    }
+
+    /**
+     * Returns the data form which contains the valid methods of stream
+     * neotiation and transfer.
+     *
+     * @return Returns the data form which contains the valid methods of stream
+     *         neotiation and transfer.
+     */
+    public DataForm getFeatureNegotiationForm() {
+        return featureNegotiation.getData();
+    }
+
+    /*
+      * (non-Javadoc)
+      *
+      * @see org.jivesoftware.smack.packet.IQ#getChildElementXML()
+      */
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+        if (this.getType().equals(IQ.Type.SET)) {
+            buf.append("<si xmlns=\"http://jabber.org/protocol/si\" ");
+            if (getSessionID() != null) {
+                buf.append("id=\"").append(getSessionID()).append("\" ");
+            }
+            if (getMimeType() != null) {
+                buf.append("mime-type=\"").append(getMimeType()).append("\" ");
+            }
+            buf
+                    .append("profile=\"http://jabber.org/protocol/si/profile/file-transfer\">");
+
+            // Add the file section if there is one.
+            String fileXML = file.toXML();
+            if (fileXML != null) {
+                buf.append(fileXML);
+            }
+        }
+        else if (this.getType().equals(IQ.Type.RESULT)) {
+            buf.append("<si xmlns=\"http://jabber.org/protocol/si\">");
+        }
+        else {
+            throw new IllegalArgumentException("IQ Type not understood");
+        }
+        if (featureNegotiation != null) {
+            buf.append(featureNegotiation.toXML());
+        }
+        buf.append("</si>");
+        return buf.toString();
+    }
+
+    /**
+     * <ul>
+     * <li>size: The size, in bytes, of the data to be sent.</li>
+     * <li>name: The name of the file that the Sender wishes to send.</li>
+     * <li>date: The last modification time of the file. This is specified
+     * using the DateTime profile as described in Jabber Date and Time Profiles.</li>
+     * <li>hash: The MD5 sum of the file contents.</li>
+     * </ul>
+     * <p/>
+     * <p/>
+     * &lt;desc&gt; is used to provide a sender-generated description of the
+     * file so the receiver can better understand what is being sent. It MUST
+     * NOT be sent in the result.
+     * <p/>
+     * <p/>
+     * When &lt;range&gt; is sent in the offer, it should have no attributes.
+     * This signifies that the sender can do ranged transfers. When a Stream
+     * Initiation result is sent with the <range> element, it uses these
+     * attributes:
+     * <p/>
+     * <ul>
+     * <li>offset: Specifies the position, in bytes, to start transferring the
+     * file data from. This defaults to zero (0) if not specified.</li>
+     * <li>length - Specifies the number of bytes to retrieve starting at
+     * offset. This defaults to the length of the file from offset to the end.</li>
+     * </ul>
+     * <p/>
+     * <p/>
+     * Both attributes are OPTIONAL on the &lt;range&gt; element. Sending no
+     * attributes is synonymous with not sending the &lt;range&gt; element. When
+     * no &lt;range&gt; element is sent in the Stream Initiation result, the
+     * Sender MUST send the complete file starting at offset 0. More generally,
+     * data is sent over the stream byte for byte starting at the offset
+     * position for the length specified.
+     *
+     * @author Alexander Wenckus
+     */
+    public static class File implements PacketExtension {
+
+        private final String name;
+
+        private final long size;
+
+        private String hash;
+
+        private Date date;
+
+        private String desc;
+
+        private boolean isRanged;
+
+        /**
+         * Constructor providing the name of the file and its size.
+         *
+         * @param name The name of the file.
+         * @param size The size of the file in bytes.
+         */
+        public File(final String name, final long size) {
+            if (name == null) {
+                throw new NullPointerException("name cannot be null");
+            }
+
+            this.name = name;
+            this.size = size;
+        }
+
+        /**
+         * Returns the file's name.
+         *
+         * @return Returns the file's name.
+         */
+        public String getName() {
+            return name;
+        }
+
+        /**
+         * Returns the file's size.
+         *
+         * @return Returns the file's size.
+         */
+        public long getSize() {
+            return size;
+        }
+
+        /**
+         * Sets the MD5 sum of the file's contents
+         *
+         * @param hash The MD5 sum of the file's contents.
+         */
+        public void setHash(final String hash) {
+            this.hash = hash;
+        }
+
+        /**
+         * Returns the MD5 sum of the file's contents
+         *
+         * @return Returns the MD5 sum of the file's contents
+         */
+        public String getHash() {
+            return hash;
+        }
+
+        /**
+         * Sets the date that the file was last modified.
+         *
+         * @param date The date that the file was last modified.
+         */
+        public void setDate(Date date) {
+            this.date = date;
+        }
+
+        /**
+         * Returns the date that the file was last modified.
+         *
+         * @return Returns the date that the file was last modified.
+         */
+        public Date getDate() {
+            return date;
+        }
+
+        /**
+         * Sets the description of the file.
+         *
+         * @param desc The description of the file so that the file reciever can
+         *             know what file it is.
+         */
+        public void setDesc(final String desc) {
+            this.desc = desc;
+        }
+
+        /**
+         * Returns the description of the file.
+         *
+         * @return Returns the description of the file.
+         */
+        public String getDesc() {
+            return desc;
+        }
+
+        /**
+         * True if a range can be provided and false if it cannot.
+         *
+         * @param isRanged True if a range can be provided and false if it cannot.
+         */
+        public void setRanged(final boolean isRanged) {
+            this.isRanged = isRanged;
+        }
+
+        /**
+         * Returns whether or not the initiator can support a range for the file
+         * tranfer.
+         *
+         * @return Returns whether or not the initiator can support a range for
+         *         the file tranfer.
+         */
+        public boolean isRanged() {
+            return isRanged;
+        }
+
+        public String getElementName() {
+            return "file";
+        }
+
+        public String getNamespace() {
+            return "http://jabber.org/protocol/si/profile/file-transfer";
+        }
+
+        public String toXML() {
+            StringBuilder buffer = new StringBuilder();
+
+            buffer.append("<").append(getElementName()).append(" xmlns=\"")
+                    .append(getNamespace()).append("\" ");
+
+            if (getName() != null) {
+                buffer.append("name=\"").append(StringUtils.escapeForXML(getName())).append("\" ");
+            }
+
+            if (getSize() > 0) {
+                buffer.append("size=\"").append(getSize()).append("\" ");
+            }
+
+            if (getDate() != null) {
+                buffer.append("date=\"").append(StringUtils.formatXEP0082Date(date)).append("\" ");
+            }
+
+            if (getHash() != null) {
+                buffer.append("hash=\"").append(getHash()).append("\" ");
+            }
+
+            if ((desc != null && desc.length() > 0) || isRanged) {
+                buffer.append(">");
+                if (getDesc() != null && desc.length() > 0) {
+                    buffer.append("<desc>").append(StringUtils.escapeForXML(getDesc())).append("</desc>");
+                }
+                if (isRanged()) {
+                    buffer.append("<range/>");
+                }
+                buffer.append("</").append(getElementName()).append(">");
+            }
+            else {
+                buffer.append("/>");
+            }
+            return buffer.toString();
+        }
+    }
+
+    /**
+     * The feature negotiation portion of the StreamInitiation packet.
+     *
+     * @author Alexander Wenckus
+     *
+     */
+    public class Feature implements PacketExtension {
+
+        private final DataForm data;
+
+        /**
+         * The dataform can be provided as part of the constructor.
+         *
+         * @param data The dataform.
+         */
+        public Feature(final DataForm data) {
+            this.data = data;
+        }
+
+        /**
+         * Returns the dataform associated with the feature negotiation.
+         *
+         * @return Returns the dataform associated with the feature negotiation.
+         */
+        public DataForm getData() {
+            return data;
+        }
+
+        public String getNamespace() {
+            return "http://jabber.org/protocol/feature-neg";
+        }
+
+        public String getElementName() {
+            return "feature";
+        }
+
+        public String toXML() {
+            StringBuilder buf = new StringBuilder();
+            buf
+                    .append("<feature xmlns=\"http://jabber.org/protocol/feature-neg\">");
+			buf.append(data.toXML());
+			buf.append("</feature>");
+			return buf.toString();
+		}
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/AdHocCommandDataProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/AdHocCommandDataProvider.java
index 63d24ec..3bc445e 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/AdHocCommandDataProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/AdHocCommandDataProvider.java
@@ -1,155 +1,155 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2005-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.provider;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.packet.XMPPError;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.jivesoftware.smack.util.PacketParserUtils;
-import org.jivesoftware.smackx.commands.AdHocCommand;
-import org.jivesoftware.smackx.commands.AdHocCommand.Action;
-import org.jivesoftware.smackx.commands.AdHocCommandNote;
-import org.jivesoftware.smackx.packet.AdHocCommandData;
-import org.jivesoftware.smackx.packet.DataForm;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * The AdHocCommandDataProvider parses AdHocCommandData packets.
- * 
- * @author Gabriel Guardincerri
- */
-public class AdHocCommandDataProvider implements IQProvider {
-
-    public IQ parseIQ(XmlPullParser parser) throws Exception {
-        boolean done = false;
-        AdHocCommandData adHocCommandData = new AdHocCommandData();
-        DataFormProvider dataFormProvider = new DataFormProvider();
-
-        int eventType;
-        String elementName;
-        String namespace;
-        adHocCommandData.setSessionID(parser.getAttributeValue("", "sessionid"));
-        adHocCommandData.setNode(parser.getAttributeValue("", "node"));
-
-        // Status
-        String status = parser.getAttributeValue("", "status");
-        if (AdHocCommand.Status.executing.toString().equalsIgnoreCase(status)) {
-            adHocCommandData.setStatus(AdHocCommand.Status.executing);
-        }
-        else if (AdHocCommand.Status.completed.toString().equalsIgnoreCase(status)) {
-            adHocCommandData.setStatus(AdHocCommand.Status.completed);
-        }
-        else if (AdHocCommand.Status.canceled.toString().equalsIgnoreCase(status)) {
-            adHocCommandData.setStatus(AdHocCommand.Status.canceled);
-        }
-
-        // Action
-        String action = parser.getAttributeValue("", "action");
-        if (action != null) {
-            Action realAction = AdHocCommand.Action.valueOf(action);
-            if (realAction == null || realAction.equals(Action.unknown)) {
-                adHocCommandData.setAction(Action.unknown);
-            }
-            else {
-                adHocCommandData.setAction(realAction);
-            }
-        }
-        while (!done) {
-            eventType = parser.next();
-            elementName = parser.getName();
-            namespace = parser.getNamespace();
-            if (eventType == XmlPullParser.START_TAG) {
-                if (parser.getName().equals("actions")) {
-                    String execute = parser.getAttributeValue("", "execute");
-                    if (execute != null) {
-                        adHocCommandData.setExecuteAction(AdHocCommand.Action.valueOf(execute));
-                    }
-                }
-                else if (parser.getName().equals("next")) {
-                    adHocCommandData.addAction(AdHocCommand.Action.next);
-                }
-                else if (parser.getName().equals("complete")) {
-                    adHocCommandData.addAction(AdHocCommand.Action.complete);
-                }
-                else if (parser.getName().equals("prev")) {
-                    adHocCommandData.addAction(AdHocCommand.Action.prev);
-                }
-                else if (elementName.equals("x") && namespace.equals("jabber:x:data")) {
-                    adHocCommandData.setForm((DataForm) dataFormProvider.parseExtension(parser));
-                }
-                else if (parser.getName().equals("note")) {
-                    AdHocCommandNote.Type type = AdHocCommandNote.Type.valueOf(
-                            parser.getAttributeValue("", "type"));
-                    String value = parser.nextText();
-                    adHocCommandData.addNote(new AdHocCommandNote(type, value));
-                }
-                else if (parser.getName().equals("error")) {
-                    XMPPError error = PacketParserUtils.parseError(parser);
-                    adHocCommandData.setError(error);
-                }
-            }
-            else if (eventType == XmlPullParser.END_TAG) {
-                if (parser.getName().equals("command")) {
-                    done = true;
-                }
-            }
-        }
-        return adHocCommandData;
-    }
-
-    public static class BadActionError implements PacketExtensionProvider {
-        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
-            return new AdHocCommandData.SpecificError(AdHocCommand.SpecificErrorCondition.badAction);
-        }
-    }
-
-    public static class MalformedActionError implements PacketExtensionProvider {
-        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
-            return new AdHocCommandData.SpecificError(AdHocCommand.SpecificErrorCondition.malformedAction);
-        }
-    }
-
-    public static class BadLocaleError implements PacketExtensionProvider {
-        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
-            return new AdHocCommandData.SpecificError(AdHocCommand.SpecificErrorCondition.badLocale);
-        }
-    }
-
-    public static class BadPayloadError implements PacketExtensionProvider {
-        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
-            return new AdHocCommandData.SpecificError(AdHocCommand.SpecificErrorCondition.badPayload);
-        }
-    }
-
-    public static class BadSessionIDError implements PacketExtensionProvider {
-        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
-            return new AdHocCommandData.SpecificError(AdHocCommand.SpecificErrorCondition.badSessionid);
-        }
-    }
-
-    public static class SessionExpiredError implements PacketExtensionProvider {
-        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
-            return new AdHocCommandData.SpecificError(AdHocCommand.SpecificErrorCondition.sessionExpired);
-        }
-    }
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2005-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.provider;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.packet.XMPPError;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.jivesoftware.smack.util.PacketParserUtils;
+import org.jivesoftware.smackx.commands.AdHocCommand;
+import org.jivesoftware.smackx.commands.AdHocCommand.Action;
+import org.jivesoftware.smackx.commands.AdHocCommandNote;
+import org.jivesoftware.smackx.packet.AdHocCommandData;
+import org.jivesoftware.smackx.packet.DataForm;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * The AdHocCommandDataProvider parses AdHocCommandData packets.
+ * 
+ * @author Gabriel Guardincerri
+ */
+public class AdHocCommandDataProvider implements IQProvider {
+
+    public IQ parseIQ(XmlPullParser parser) throws Exception {
+        boolean done = false;
+        AdHocCommandData adHocCommandData = new AdHocCommandData();
+        DataFormProvider dataFormProvider = new DataFormProvider();
+
+        int eventType;
+        String elementName;
+        String namespace;
+        adHocCommandData.setSessionID(parser.getAttributeValue("", "sessionid"));
+        adHocCommandData.setNode(parser.getAttributeValue("", "node"));
+
+        // Status
+        String status = parser.getAttributeValue("", "status");
+        if (AdHocCommand.Status.executing.toString().equalsIgnoreCase(status)) {
+            adHocCommandData.setStatus(AdHocCommand.Status.executing);
+        }
+        else if (AdHocCommand.Status.completed.toString().equalsIgnoreCase(status)) {
+            adHocCommandData.setStatus(AdHocCommand.Status.completed);
+        }
+        else if (AdHocCommand.Status.canceled.toString().equalsIgnoreCase(status)) {
+            adHocCommandData.setStatus(AdHocCommand.Status.canceled);
+        }
+
+        // Action
+        String action = parser.getAttributeValue("", "action");
+        if (action != null) {
+            Action realAction = AdHocCommand.Action.valueOf(action);
+            if (realAction == null || realAction.equals(Action.unknown)) {
+                adHocCommandData.setAction(Action.unknown);
+            }
+            else {
+                adHocCommandData.setAction(realAction);
+            }
+        }
+        while (!done) {
+            eventType = parser.next();
+            elementName = parser.getName();
+            namespace = parser.getNamespace();
+            if (eventType == XmlPullParser.START_TAG) {
+                if (parser.getName().equals("actions")) {
+                    String execute = parser.getAttributeValue("", "execute");
+                    if (execute != null) {
+                        adHocCommandData.setExecuteAction(AdHocCommand.Action.valueOf(execute));
+                    }
+                }
+                else if (parser.getName().equals("next")) {
+                    adHocCommandData.addAction(AdHocCommand.Action.next);
+                }
+                else if (parser.getName().equals("complete")) {
+                    adHocCommandData.addAction(AdHocCommand.Action.complete);
+                }
+                else if (parser.getName().equals("prev")) {
+                    adHocCommandData.addAction(AdHocCommand.Action.prev);
+                }
+                else if (elementName.equals("x") && namespace.equals("jabber:x:data")) {
+                    adHocCommandData.setForm((DataForm) dataFormProvider.parseExtension(parser));
+                }
+                else if (parser.getName().equals("note")) {
+                    AdHocCommandNote.Type type = AdHocCommandNote.Type.valueOf(
+                            parser.getAttributeValue("", "type"));
+                    String value = parser.nextText();
+                    adHocCommandData.addNote(new AdHocCommandNote(type, value));
+                }
+                else if (parser.getName().equals("error")) {
+                    XMPPError error = PacketParserUtils.parseError(parser);
+                    adHocCommandData.setError(error);
+                }
+            }
+            else if (eventType == XmlPullParser.END_TAG) {
+                if (parser.getName().equals("command")) {
+                    done = true;
+                }
+            }
+        }
+        return adHocCommandData;
+    }
+
+    public static class BadActionError implements PacketExtensionProvider {
+        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
+            return new AdHocCommandData.SpecificError(AdHocCommand.SpecificErrorCondition.badAction);
+        }
+    }
+
+    public static class MalformedActionError implements PacketExtensionProvider {
+        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
+            return new AdHocCommandData.SpecificError(AdHocCommand.SpecificErrorCondition.malformedAction);
+        }
+    }
+
+    public static class BadLocaleError implements PacketExtensionProvider {
+        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
+            return new AdHocCommandData.SpecificError(AdHocCommand.SpecificErrorCondition.badLocale);
+        }
+    }
+
+    public static class BadPayloadError implements PacketExtensionProvider {
+        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
+            return new AdHocCommandData.SpecificError(AdHocCommand.SpecificErrorCondition.badPayload);
+        }
+    }
+
+    public static class BadSessionIDError implements PacketExtensionProvider {
+        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
+            return new AdHocCommandData.SpecificError(AdHocCommand.SpecificErrorCondition.badSessionid);
+        }
+    }
+
+    public static class SessionExpiredError implements PacketExtensionProvider {
+        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
+            return new AdHocCommandData.SpecificError(AdHocCommand.SpecificErrorCondition.sessionExpired);
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/DelayInfoProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/DelayInfoProvider.java
index 9d1dcd8..6fa52b7 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/DelayInfoProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/DelayInfoProvider.java
@@ -1,42 +1,42 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.provider;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smackx.packet.DelayInfo;
-import org.jivesoftware.smackx.packet.DelayInformation;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * This provider simply creates a {@link DelayInfo} decorator for the {@link DelayInformation} that
- * is returned by the superclass.  This allows the new code using
- * <a href="http://xmpp.org/extensions/xep-0203.html">Delay Information XEP-0203</a> to be
- * backward compatible with <a href="http://xmpp.org/extensions/xep-0091.html">XEP-0091</a>.  
- * 
- * <p>This provider must be registered in the <b>smack.properties</b> file for the element 
- * <b>delay</b> with namespace <b>urn:xmpp:delay</b></p>
- *  
- * @author Robin Collier
- */
-public class DelayInfoProvider extends DelayInformationProvider
-{
-
-	@Override
-	public PacketExtension parseExtension(XmlPullParser parser) throws Exception
-	{
-		return new DelayInfo((DelayInformation)super.parseExtension(parser));
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.provider;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smackx.packet.DelayInfo;
+import org.jivesoftware.smackx.packet.DelayInformation;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * This provider simply creates a {@link DelayInfo} decorator for the {@link DelayInformation} that
+ * is returned by the superclass.  This allows the new code using
+ * <a href="http://xmpp.org/extensions/xep-0203.html">Delay Information XEP-0203</a> to be
+ * backward compatible with <a href="http://xmpp.org/extensions/xep-0091.html">XEP-0091</a>.  
+ * 
+ * <p>This provider must be registered in the <b>smack.properties</b> file for the element 
+ * <b>delay</b> with namespace <b>urn:xmpp:delay</b></p>
+ *  
+ * @author Robin Collier
+ */
+public class DelayInfoProvider extends DelayInformationProvider
+{
+
+	@Override
+	public PacketExtension parseExtension(XmlPullParser parser) throws Exception
+	{
+		return new DelayInfo((DelayInformation)super.parseExtension(parser));
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/EmbeddedExtensionProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/EmbeddedExtensionProvider.java
index 3d5ceb4..55c6726 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/EmbeddedExtensionProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/EmbeddedExtensionProvider.java
@@ -1,111 +1,111 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.provider;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.jivesoftware.smack.util.PacketParserUtils;
-import org.jivesoftware.smackx.pubsub.provider.ItemProvider;
-import org.jivesoftware.smackx.pubsub.provider.ItemsProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * 
- * This class simplifies parsing of embedded elements by using the 
- * <a href="http://en.wikipedia.org/wiki/Template_method_pattern">Template Method Pattern</a>.  
- * After extracting the current element attributes and content of any child elements, the template method 
- * ({@link #createReturnExtension(String, String, Map, List)} is called.  Subclasses
- * then override this method to create the specific return type.
- * 
- * <p>To use this class, you simply register your subclasses as extension providers in the 
- * <b>smack.properties</b> file.  Then they will be automatically picked up and used to parse
- * any child elements.  
- * 
- * <pre>
- * For example, given the following message
- * 
- * &lt;message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo&gt;
- *    &lt;event xmlns='http://jabber.org/protocol/pubsub#event&gt;
- *       &lt;items node='princely_musings'&gt;
- *          &lt;item id='asdjkwei3i34234n356'&gt;
- *             &lt;entry xmlns='http://www.w3.org/2005/Atom'&gt;
- *                &lt;title&gt;Soliloquy&lt;/title&gt;
- *                &lt;link rel='alternative' type='text/html'/&gt;
- *                &lt;id>tag:denmark.lit,2003:entry-32397&lt;/id&gt;
- *             &lt;/entry&gt;
- *          &lt;/item&gt;
- *       &lt;/items&gt;
- *    &lt;/event&gt;
- * &lt;/message&gt;
- * 
- * I would have a classes
- * {@link ItemsProvider} extends {@link EmbeddedExtensionProvider}
- * {@link ItemProvider} extends {@link EmbeddedExtensionProvider}
- * and
- * AtomProvider extends {@link PacketExtensionProvider}
- * 
- * These classes are then registered in the meta-inf/smack.providers file
- * as follows.
- * 
- *   &lt;extensionProvider&gt;
- *      &lt;elementName&gt;items&lt;/elementName&gt;
- *      &lt;namespace&gt;http://jabber.org/protocol/pubsub#event&lt;/namespace&gt;
- *      &lt;className&gt;org.jivesoftware.smackx.provider.ItemsEventProvider&lt;/className&gt;
- *   &lt;/extensionProvider&gt;
- *   &lt;extensionProvider&gt;
- *       &lt;elementName&gt;item&lt;/elementName&gt;
- *       &lt;namespace&gt;http://jabber.org/protocol/pubsub#event&lt;/namespace&gt;
- *       &lt;className&gt;org.jivesoftware.smackx.provider.ItemProvider&lt;/className&gt;
- *   &lt;/extensionProvider&gt;
- * 
- * </pre>
- * 
- * @author Robin Collier
- * 
- * @deprecated This has been moved to {@link org.jivesoftware.smack.provider.EmbeddedExtensionProvider}
- */
-abstract public class EmbeddedExtensionProvider implements PacketExtensionProvider
-{
-
-	final public PacketExtension parseExtension(XmlPullParser parser) throws Exception
-	{
-        String namespace = parser.getNamespace();
-        String name = parser.getName();
-        Map<String, String> attMap = new HashMap<String, String>();
-        
-        for(int i=0; i<parser.getAttributeCount(); i++)
-        {
-        	attMap.put(parser.getAttributeName(i), parser.getAttributeValue(i));
-        }
-        List<PacketExtension> extensions = new ArrayList<PacketExtension>();
-        
-        do
-        {
-            int tag = parser.next();
-
-            if (tag == XmlPullParser.START_TAG) 
-            	extensions.add(PacketParserUtils.parsePacketExtension(parser.getName(), parser.getNamespace(), parser));
-        } while (!name.equals(parser.getName()));
-
-		return createReturnExtension(name, namespace, attMap, extensions);
-	}
-
-	abstract protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content);
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.provider;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.jivesoftware.smack.util.PacketParserUtils;
+import org.jivesoftware.smackx.pubsub.provider.ItemProvider;
+import org.jivesoftware.smackx.pubsub.provider.ItemsProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * 
+ * This class simplifies parsing of embedded elements by using the 
+ * <a href="http://en.wikipedia.org/wiki/Template_method_pattern">Template Method Pattern</a>.  
+ * After extracting the current element attributes and content of any child elements, the template method 
+ * ({@link #createReturnExtension(String, String, Map, List)} is called.  Subclasses
+ * then override this method to create the specific return type.
+ * 
+ * <p>To use this class, you simply register your subclasses as extension providers in the 
+ * <b>smack.properties</b> file.  Then they will be automatically picked up and used to parse
+ * any child elements.  
+ * 
+ * <pre>
+ * For example, given the following message
+ * 
+ * &lt;message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo&gt;
+ *    &lt;event xmlns='http://jabber.org/protocol/pubsub#event&gt;
+ *       &lt;items node='princely_musings'&gt;
+ *          &lt;item id='asdjkwei3i34234n356'&gt;
+ *             &lt;entry xmlns='http://www.w3.org/2005/Atom'&gt;
+ *                &lt;title&gt;Soliloquy&lt;/title&gt;
+ *                &lt;link rel='alternative' type='text/html'/&gt;
+ *                &lt;id>tag:denmark.lit,2003:entry-32397&lt;/id&gt;
+ *             &lt;/entry&gt;
+ *          &lt;/item&gt;
+ *       &lt;/items&gt;
+ *    &lt;/event&gt;
+ * &lt;/message&gt;
+ * 
+ * I would have a classes
+ * {@link ItemsProvider} extends {@link EmbeddedExtensionProvider}
+ * {@link ItemProvider} extends {@link EmbeddedExtensionProvider}
+ * and
+ * AtomProvider extends {@link PacketExtensionProvider}
+ * 
+ * These classes are then registered in the meta-inf/smack.providers file
+ * as follows.
+ * 
+ *   &lt;extensionProvider&gt;
+ *      &lt;elementName&gt;items&lt;/elementName&gt;
+ *      &lt;namespace&gt;http://jabber.org/protocol/pubsub#event&lt;/namespace&gt;
+ *      &lt;className&gt;org.jivesoftware.smackx.provider.ItemsEventProvider&lt;/className&gt;
+ *   &lt;/extensionProvider&gt;
+ *   &lt;extensionProvider&gt;
+ *       &lt;elementName&gt;item&lt;/elementName&gt;
+ *       &lt;namespace&gt;http://jabber.org/protocol/pubsub#event&lt;/namespace&gt;
+ *       &lt;className&gt;org.jivesoftware.smackx.provider.ItemProvider&lt;/className&gt;
+ *   &lt;/extensionProvider&gt;
+ * 
+ * </pre>
+ * 
+ * @author Robin Collier
+ * 
+ * @deprecated This has been moved to {@link org.jivesoftware.smack.provider.EmbeddedExtensionProvider}
+ */
+abstract public class EmbeddedExtensionProvider implements PacketExtensionProvider
+{
+
+	final public PacketExtension parseExtension(XmlPullParser parser) throws Exception
+	{
+        String namespace = parser.getNamespace();
+        String name = parser.getName();
+        Map<String, String> attMap = new HashMap<String, String>();
+        
+        for(int i=0; i<parser.getAttributeCount(); i++)
+        {
+        	attMap.put(parser.getAttributeName(i), parser.getAttributeValue(i));
+        }
+        List<PacketExtension> extensions = new ArrayList<PacketExtension>();
+        
+        do
+        {
+            int tag = parser.next();
+
+            if (tag == XmlPullParser.START_TAG) 
+            	extensions.add(PacketParserUtils.parsePacketExtension(parser.getName(), parser.getNamespace(), parser));
+        } while (!name.equals(parser.getName()));
+
+		return createReturnExtension(name, namespace, attMap, extensions);
+	}
+
+	abstract protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content);
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/HeaderProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/HeaderProvider.java
index 7344880..b6e55a3 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/HeaderProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/HeaderProvider.java
@@ -1,44 +1,44 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.provider;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.jivesoftware.smackx.packet.Header;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * Parses the header element as defined in <a href="http://xmpp.org/extensions/xep-0131">Stanza Headers and Internet Metadata (SHIM)</a>.
- * 
- * @author Robin Collier
- */
-public class HeaderProvider implements PacketExtensionProvider
-{
-	public PacketExtension parseExtension(XmlPullParser parser) throws Exception
-	{
-		String name = parser.getAttributeValue(null, "name");
-		String value = null;
-		
-		parser.next();
-		
-		if (parser.getEventType() == XmlPullParser.TEXT)
-			value = parser.getText();
-		
-		while(parser.getEventType() != XmlPullParser.END_TAG)
-			parser.next();
-		
-		return new Header(name, value);
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.provider;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.jivesoftware.smackx.packet.Header;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * Parses the header element as defined in <a href="http://xmpp.org/extensions/xep-0131">Stanza Headers and Internet Metadata (SHIM)</a>.
+ * 
+ * @author Robin Collier
+ */
+public class HeaderProvider implements PacketExtensionProvider
+{
+	public PacketExtension parseExtension(XmlPullParser parser) throws Exception
+	{
+		String name = parser.getAttributeValue(null, "name");
+		String value = null;
+		
+		parser.next();
+		
+		if (parser.getEventType() == XmlPullParser.TEXT)
+			value = parser.getText();
+		
+		while(parser.getEventType() != XmlPullParser.END_TAG)
+			parser.next();
+		
+		return new Header(name, value);
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/HeadersProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/HeadersProvider.java
index 056dd58..0c3158d 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/HeadersProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/HeadersProvider.java
@@ -1,37 +1,37 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.provider;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smackx.packet.Header;
-import org.jivesoftware.smackx.packet.HeadersExtension;
-
-/**
- * Parses the headers element as defined in <a href="http://xmpp.org/extensions/xep-0131">Stanza Headers and Internet Metadata (SHIM)</a>.
- * 
- * @author Robin Collier
- */
-public class HeadersProvider extends EmbeddedExtensionProvider
-{
-	@Override
-	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content)
-	{
-		return new HeadersExtension((Collection<Header>)content);
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.provider;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smackx.packet.Header;
+import org.jivesoftware.smackx.packet.HeadersExtension;
+
+/**
+ * Parses the headers element as defined in <a href="http://xmpp.org/extensions/xep-0131">Stanza Headers and Internet Metadata (SHIM)</a>.
+ * 
+ * @author Robin Collier
+ */
+public class HeadersProvider extends EmbeddedExtensionProvider
+{
+	@Override
+	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content)
+	{
+		return new HeadersExtension((Collection<Header>)content);
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/StreamInitiationProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/StreamInitiationProvider.java
index 11ab339..d599811 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/StreamInitiationProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/StreamInitiationProvider.java
@@ -1,124 +1,124 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2006 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.provider;
-
-import java.text.ParseException;
-import java.util.Date;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.jivesoftware.smack.util.StringUtils;
-import org.jivesoftware.smackx.packet.DataForm;
-import org.jivesoftware.smackx.packet.StreamInitiation;
-import org.jivesoftware.smackx.packet.StreamInitiation.File;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * The StreamInitiationProvider parses StreamInitiation packets.
- * 
- * @author Alexander Wenckus
- * 
- */
-public class StreamInitiationProvider implements IQProvider {
-
-	public IQ parseIQ(final XmlPullParser parser) throws Exception {
-		boolean done = false;
-
-		// si
-		String id = parser.getAttributeValue("", "id");
-		String mimeType = parser.getAttributeValue("", "mime-type");
-
-		StreamInitiation initiation = new StreamInitiation();
-
-		// file
-		String name = null;
-		String size = null;
-		String hash = null;
-		String date = null;
-		String desc = null;
-		boolean isRanged = false;
-
-		// feature
-		DataForm form = null;
-		DataFormProvider dataFormProvider = new DataFormProvider();
-
-		int eventType;
-		String elementName;
-		String namespace;
-		while (!done) {
-			eventType = parser.next();
-			elementName = parser.getName();
-			namespace = parser.getNamespace();
-			if (eventType == XmlPullParser.START_TAG) {
-				if (elementName.equals("file")) {
-					name = parser.getAttributeValue("", "name");
-					size = parser.getAttributeValue("", "size");
-					hash = parser.getAttributeValue("", "hash");
-					date = parser.getAttributeValue("", "date");
-				} else if (elementName.equals("desc")) {
-					desc = parser.nextText();
-				} else if (elementName.equals("range")) {
-					isRanged = true;
-				} else if (elementName.equals("x")
-						&& namespace.equals("jabber:x:data")) {
-					form = (DataForm) dataFormProvider.parseExtension(parser);
-				}
-			} else if (eventType == XmlPullParser.END_TAG) {
-				if (elementName.equals("si")) {
-					done = true;
-				} else if (elementName.equals("file")) {
-                    long fileSize = 0;
-                    if(size != null && size.trim().length() !=0){
-                        try {
-                            fileSize = Long.parseLong(size);
-                        }
-                        catch (NumberFormatException e) {
-                            e.printStackTrace();
-                        }
-                    }
-                    
-                    Date fileDate = new Date();
-                    if (date != null) {
-                        try {
-                            fileDate = StringUtils.parseXEP0082Date(date);
-                        } catch (ParseException e) {
-                            // couldn't parse date, use current date-time
-                        }
-                    }
-                    
-                    File file = new File(name, fileSize);
-					file.setHash(hash);
-					file.setDate(fileDate);
-					file.setDesc(desc);
-					file.setRanged(isRanged);
-					initiation.setFile(file);
-				}
-			}
-		}
-
-		initiation.setSesssionID(id);
-		initiation.setMimeType(mimeType);
-
-		initiation.setFeatureNegotiationForm(form);
-
-		return initiation;
-	}
-
-}
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2006 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.provider;
+
+import java.text.ParseException;
+import java.util.Date;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.jivesoftware.smack.util.StringUtils;
+import org.jivesoftware.smackx.packet.DataForm;
+import org.jivesoftware.smackx.packet.StreamInitiation;
+import org.jivesoftware.smackx.packet.StreamInitiation.File;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * The StreamInitiationProvider parses StreamInitiation packets.
+ * 
+ * @author Alexander Wenckus
+ * 
+ */
+public class StreamInitiationProvider implements IQProvider {
+
+	public IQ parseIQ(final XmlPullParser parser) throws Exception {
+		boolean done = false;
+
+		// si
+		String id = parser.getAttributeValue("", "id");
+		String mimeType = parser.getAttributeValue("", "mime-type");
+
+		StreamInitiation initiation = new StreamInitiation();
+
+		// file
+		String name = null;
+		String size = null;
+		String hash = null;
+		String date = null;
+		String desc = null;
+		boolean isRanged = false;
+
+		// feature
+		DataForm form = null;
+		DataFormProvider dataFormProvider = new DataFormProvider();
+
+		int eventType;
+		String elementName;
+		String namespace;
+		while (!done) {
+			eventType = parser.next();
+			elementName = parser.getName();
+			namespace = parser.getNamespace();
+			if (eventType == XmlPullParser.START_TAG) {
+				if (elementName.equals("file")) {
+					name = parser.getAttributeValue("", "name");
+					size = parser.getAttributeValue("", "size");
+					hash = parser.getAttributeValue("", "hash");
+					date = parser.getAttributeValue("", "date");
+				} else if (elementName.equals("desc")) {
+					desc = parser.nextText();
+				} else if (elementName.equals("range")) {
+					isRanged = true;
+				} else if (elementName.equals("x")
+						&& namespace.equals("jabber:x:data")) {
+					form = (DataForm) dataFormProvider.parseExtension(parser);
+				}
+			} else if (eventType == XmlPullParser.END_TAG) {
+				if (elementName.equals("si")) {
+					done = true;
+				} else if (elementName.equals("file")) {
+                    long fileSize = 0;
+                    if(size != null && size.trim().length() !=0){
+                        try {
+                            fileSize = Long.parseLong(size);
+                        }
+                        catch (NumberFormatException e) {
+                            e.printStackTrace();
+                        }
+                    }
+                    
+                    Date fileDate = new Date();
+                    if (date != null) {
+                        try {
+                            fileDate = StringUtils.parseXEP0082Date(date);
+                        } catch (ParseException e) {
+                            // couldn't parse date, use current date-time
+                        }
+                    }
+                    
+                    File file = new File(name, fileSize);
+					file.setHash(hash);
+					file.setDate(fileDate);
+					file.setDesc(desc);
+					file.setRanged(isRanged);
+					initiation.setFile(file);
+				}
+			}
+		}
+
+		initiation.setSesssionID(id);
+		initiation.setMimeType(mimeType);
+
+		initiation.setFeatureNegotiationForm(form);
+
+		return initiation;
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/AccessModel.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/AccessModel.java
index c1fa546..bd0294c 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/AccessModel.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/AccessModel.java
@@ -1,38 +1,38 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-/**
- * This enumeration represents the access models for the pubsub node
- * as defined in the pubsub specification section <a href="http://xmpp.org/extensions/xep-0060.html#registrar-formtypes-config">16.4.3</a>
- * 
- * @author Robin Collier
- */
-public enum AccessModel
-{
-	/** Anyone may subscribe and retrieve items	 */
-	open,
-
-	/** Subscription request must be approved and only subscribers may retrieve items */
-	authorize,
-	
-	/** Anyone with a presence subscription of both or from may subscribe and retrieve items */
-	presence,
-	
-	/** Anyone in the specified roster group(s) may subscribe and retrieve items */
-	roster,
-	
-	/** Only those on a whitelist may subscribe and retrieve items */
-	whitelist;
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+/**
+ * This enumeration represents the access models for the pubsub node
+ * as defined in the pubsub specification section <a href="http://xmpp.org/extensions/xep-0060.html#registrar-formtypes-config">16.4.3</a>
+ * 
+ * @author Robin Collier
+ */
+public enum AccessModel
+{
+	/** Anyone may subscribe and retrieve items	 */
+	open,
+
+	/** Subscription request must be approved and only subscribers may retrieve items */
+	authorize,
+	
+	/** Anyone with a presence subscription of both or from may subscribe and retrieve items */
+	presence,
+	
+	/** Anyone in the specified roster group(s) may subscribe and retrieve items */
+	roster,
+	
+	/** Only those on a whitelist may subscribe and retrieve items */
+	whitelist;
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/Affiliation.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/Affiliation.java
index d0fc7dc..c2208c1 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/Affiliation.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/Affiliation.java
@@ -1,90 +1,90 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.packet.PacketExtension;
-
-/**
- * Represents a affiliation between a user and a node, where the {@link #type} defines 
- * the type of affiliation.
- * 
- * Affiliations are retrieved from the {@link PubSubManager#getAffiliations()} method, which 
- * gets affiliations for the calling user, based on the identity that is associated with 
- * the {@link Connection}.
- * 
- * @author Robin Collier
- */
-public class Affiliation implements PacketExtension
-{
-	protected String node;
-	protected Type type;
-	
-	public enum Type
-	{
-		member, none, outcast, owner, publisher
-	}
-
-	/**
-	 * Constructs an affiliation.
-	 * 
-	 * @param nodeId The node the user is affiliated with.
-	 * @param affiliation The type of affiliation.
-	 */
-	public Affiliation(String nodeId, Type affiliation)
-	{
-		node = nodeId;
-		type = affiliation;
-	}
-	
-	public String getNodeId()
-	{
-		return node;
-	}
-	
-	public Type getType()
-	{
-		return type;
-	}
-	
-	public String getElementName()
-	{
-		return "subscription";
-	}
-
-	public String getNamespace()
-	{
-		return null;
-	}
-
-	public String toXML()
-	{
-		StringBuilder builder = new StringBuilder("<");
-		builder.append(getElementName());
-		appendAttribute(builder, "node", node);
-		appendAttribute(builder, "affiliation", type.toString());
-		
-		builder.append("/>");
-		return builder.toString();
-	}
-
-	private void appendAttribute(StringBuilder builder, String att, String value)
-	{
-		builder.append(" ");
-		builder.append(att);
-		builder.append("='");
-		builder.append(value);
-		builder.append("'");
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.packet.PacketExtension;
+
+/**
+ * Represents a affiliation between a user and a node, where the {@link #type} defines 
+ * the type of affiliation.
+ * 
+ * Affiliations are retrieved from the {@link PubSubManager#getAffiliations()} method, which 
+ * gets affiliations for the calling user, based on the identity that is associated with 
+ * the {@link Connection}.
+ * 
+ * @author Robin Collier
+ */
+public class Affiliation implements PacketExtension
+{
+	protected String node;
+	protected Type type;
+	
+	public enum Type
+	{
+		member, none, outcast, owner, publisher
+	}
+
+	/**
+	 * Constructs an affiliation.
+	 * 
+	 * @param nodeId The node the user is affiliated with.
+	 * @param affiliation The type of affiliation.
+	 */
+	public Affiliation(String nodeId, Type affiliation)
+	{
+		node = nodeId;
+		type = affiliation;
+	}
+	
+	public String getNodeId()
+	{
+		return node;
+	}
+	
+	public Type getType()
+	{
+		return type;
+	}
+	
+	public String getElementName()
+	{
+		return "subscription";
+	}
+
+	public String getNamespace()
+	{
+		return null;
+	}
+
+	public String toXML()
+	{
+		StringBuilder builder = new StringBuilder("<");
+		builder.append(getElementName());
+		appendAttribute(builder, "node", node);
+		appendAttribute(builder, "affiliation", type.toString());
+		
+		builder.append("/>");
+		return builder.toString();
+	}
+
+	private void appendAttribute(StringBuilder builder, String att, String value)
+	{
+		builder.append(" ");
+		builder.append(att);
+		builder.append("='");
+		builder.append(value);
+		builder.append("'");
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/AffiliationsExtension.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/AffiliationsExtension.java
index aa82dcb..4c0cb61 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/AffiliationsExtension.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/AffiliationsExtension.java
@@ -1,69 +1,69 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Represents the <b>affiliations</b> element of the reply to a request for affiliations.
- * It is defined in the specification in section <a href="http://xmpp.org/extensions/xep-0060.html#entity-affiliations">5.7 Retrieve Affiliations</a>.
- * 
- * @author Robin Collier
- */
-public class AffiliationsExtension extends NodeExtension
-{
-	protected List<Affiliation> items = Collections.EMPTY_LIST;
-	
-	public AffiliationsExtension()
-	{
-		super(PubSubElementType.AFFILIATIONS);
-	}
-	
-	public AffiliationsExtension(List<Affiliation> subList)
-	{
-		super(PubSubElementType.AFFILIATIONS);
-		items = subList;
-	}
-
-	public List<Affiliation> getAffiliations()
-	{
-		return items;
-	}
-
-	@Override
-	public String toXML()
-	{
-		if ((items == null) || (items.size() == 0))
-		{
-			return super.toXML();
-		}
-		else
-		{
-			StringBuilder builder = new StringBuilder("<");
-			builder.append(getElementName());
-			builder.append(">");
-			
-			for (Affiliation item : items)
-			{
-				builder.append(item.toXML());
-			}
-			
-			builder.append("</");
-			builder.append(getElementName());
-			builder.append(">");
-			return builder.toString();
-		}
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Represents the <b>affiliations</b> element of the reply to a request for affiliations.
+ * It is defined in the specification in section <a href="http://xmpp.org/extensions/xep-0060.html#entity-affiliations">5.7 Retrieve Affiliations</a>.
+ * 
+ * @author Robin Collier
+ */
+public class AffiliationsExtension extends NodeExtension
+{
+	protected List<Affiliation> items = Collections.EMPTY_LIST;
+	
+	public AffiliationsExtension()
+	{
+		super(PubSubElementType.AFFILIATIONS);
+	}
+	
+	public AffiliationsExtension(List<Affiliation> subList)
+	{
+		super(PubSubElementType.AFFILIATIONS);
+		items = subList;
+	}
+
+	public List<Affiliation> getAffiliations()
+	{
+		return items;
+	}
+
+	@Override
+	public String toXML()
+	{
+		if ((items == null) || (items.size() == 0))
+		{
+			return super.toXML();
+		}
+		else
+		{
+			StringBuilder builder = new StringBuilder("<");
+			builder.append(getElementName());
+			builder.append(">");
+			
+			for (Affiliation item : items)
+			{
+				builder.append(item.toXML());
+			}
+			
+			builder.append("</");
+			builder.append(getElementName());
+			builder.append(">");
+			return builder.toString();
+		}
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ChildrenAssociationPolicy.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ChildrenAssociationPolicy.java
index 933a39e..13fabe9 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ChildrenAssociationPolicy.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ChildrenAssociationPolicy.java
@@ -1,32 +1,32 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-/**
- * This enumeration represents the children association policy for associating leaf nodes
- * with collection nodes as defined in the pubsub specification section <a href="http://xmpp.org/extensions/xep-0060.html#registrar-formtypes-config">16.4.3</a>
- * 
- * @author Robin Collier
- */
-public enum ChildrenAssociationPolicy
-{
-	/** Anyone may associate leaf nodes with the collection	 */
-	all,
-	
-	/** Only collection node owners may associate leaf nodes with the collection. */
-	owners,
-	
-	/** Only those on a whitelist may associate leaf nodes with the collection.	 */
-	whitelist;
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+/**
+ * This enumeration represents the children association policy for associating leaf nodes
+ * with collection nodes as defined in the pubsub specification section <a href="http://xmpp.org/extensions/xep-0060.html#registrar-formtypes-config">16.4.3</a>
+ * 
+ * @author Robin Collier
+ */
+public enum ChildrenAssociationPolicy
+{
+	/** Anyone may associate leaf nodes with the collection	 */
+	all,
+	
+	/** Only collection node owners may associate leaf nodes with the collection. */
+	owners,
+	
+	/** Only those on a whitelist may associate leaf nodes with the collection.	 */
+	whitelist;
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/CollectionNode.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/CollectionNode.java
index dcd1cc4..73b9165 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/CollectionNode.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/CollectionNode.java
@@ -17,15 +17,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jivesoftware.smackx.pubsub;
-
-import org.jivesoftware.smack.Connection;
-
-public class CollectionNode extends Node
-{
-	CollectionNode(Connection connection, String nodeId)
-	{
-		super(connection, nodeId);
-	}
-
-}
+package org.jivesoftware.smackx.pubsub;
+
+import org.jivesoftware.smack.Connection;
+
+public class CollectionNode extends Node
+{
+	CollectionNode(Connection connection, String nodeId)
+	{
+		super(connection, nodeId);
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ConfigurationEvent.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ConfigurationEvent.java
index 67b8304..3f002cb 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ConfigurationEvent.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ConfigurationEvent.java
@@ -1,56 +1,56 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-
-/**
- * Represents the <b>configuration</b> element of a pubsub message event which 
- * associates a configuration form to the node which was configured.  The form 
- * contains the current node configuration.
- *  
- * @author Robin Collier
- */
-public class ConfigurationEvent extends NodeExtension implements EmbeddedPacketExtension
-{
-	private ConfigureForm form;
-	
-	public ConfigurationEvent(String nodeId)
-	{
-		super(PubSubElementType.CONFIGURATION, nodeId);
-	}
-	
-	public ConfigurationEvent(String nodeId, ConfigureForm configForm)
-	{
-		super(PubSubElementType.CONFIGURATION, nodeId);
-		form = configForm;
-	}
-	
-	public ConfigureForm getConfiguration()
-	{
-		return form;
-	}
-
-	public List<PacketExtension> getExtensions()
-	{
-		if (getConfiguration() == null)
-			return Collections.EMPTY_LIST;
-		else
-			return Arrays.asList(((PacketExtension)getConfiguration().getDataFormToSend()));
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+
+/**
+ * Represents the <b>configuration</b> element of a pubsub message event which 
+ * associates a configuration form to the node which was configured.  The form 
+ * contains the current node configuration.
+ *  
+ * @author Robin Collier
+ */
+public class ConfigurationEvent extends NodeExtension implements EmbeddedPacketExtension
+{
+	private ConfigureForm form;
+	
+	public ConfigurationEvent(String nodeId)
+	{
+		super(PubSubElementType.CONFIGURATION, nodeId);
+	}
+	
+	public ConfigurationEvent(String nodeId, ConfigureForm configForm)
+	{
+		super(PubSubElementType.CONFIGURATION, nodeId);
+		form = configForm;
+	}
+	
+	public ConfigureForm getConfiguration()
+	{
+		return form;
+	}
+
+	public List<PacketExtension> getExtensions()
+	{
+		if (getConfiguration() == null)
+			return Collections.EMPTY_LIST;
+		else
+			return Arrays.asList(((PacketExtension)getConfiguration().getDataFormToSend()));
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ConfigureForm.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ConfigureForm.java
index f6fe140..127c849 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ConfigureForm.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ConfigureForm.java
@@ -1,709 +1,709 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.jivesoftware.smackx.Form;
-import org.jivesoftware.smackx.FormField;
-import org.jivesoftware.smackx.packet.DataForm;
-
-/**
- * A decorator for a {@link Form} to easily enable reading and updating
- * of node configuration.  All operations read or update the underlying {@link DataForm}.
- * 
- * <p>Unlike the {@link Form}.setAnswer(XXX)} methods, which throw an exception if the field does not
- * exist, all <b>ConfigureForm.setXXX</b> methods will create the field in the wrapped form
- * if it does not already exist. 
- * 
- * @author Robin Collier
- */
-public class ConfigureForm extends Form
-{
-	/**
-	 * Create a decorator from an existing {@link DataForm} that has been
-	 * retrieved from parsing a node configuration request.
-	 * 
-	 * @param configDataForm
-	 */
-	public ConfigureForm(DataForm configDataForm)
-	{
-		super(configDataForm);
-	}
-	
-	/**
-	 * Create a decorator from an existing {@link Form} for node configuration.
-	 * Typically, this can be used to create a decorator for an answer form
-	 * by using the result of {@link #createAnswerForm()} as the input parameter.
-	 * 
-	 * @param nodeConfigForm
-	 */
-	public ConfigureForm(Form nodeConfigForm)
-	{
-		super(nodeConfigForm.getDataFormToSend());
-	}
-	
-	/**
-	 * Create a new form for configuring a node.  This would typically only be used 
-	 * when creating and configuring a node at the same time via {@link PubSubManager#createNode(String, Form)}, since 
-	 * configuration of an existing node is typically accomplished by calling {@link LeafNode#getNodeConfiguration()} and
-	 * using the resulting form to create a answer form.  See {@link #ConfigureForm(Form)}.
-	 * @param formType
-	 */
-	public ConfigureForm(FormType formType)
-	{
-		super(formType.toString());
-	}
-	
-	/**
-	 * Get the currently configured {@link AccessModel}, null if it is not set.
-	 * 
-	 * @return The current {@link AccessModel}
-	 */
-	public AccessModel getAccessModel()
-	{
-		String value = getFieldValue(ConfigureNodeFields.access_model);
-		
-		if (value == null)
-			return null;
-		else
-			return AccessModel.valueOf(value);
-	}
-	
-	/**
-	 * Sets the value of access model.
-	 * 
-	 * @param accessModel
-	 */
-	public void setAccessModel(AccessModel accessModel)
-	{
-		addField(ConfigureNodeFields.access_model, FormField.TYPE_LIST_SINGLE);
-		setAnswer(ConfigureNodeFields.access_model.getFieldName(), getListSingle(accessModel.toString()));
-	}
-
-	/**
-	 * Returns the URL of an XSL transformation which can be applied to payloads in order to 
-	 * generate an appropriate message body element.
-	 * 
-	 * @return URL to an XSL
-	 */
-	public String getBodyXSLT()
-	{
-		return getFieldValue(ConfigureNodeFields.body_xslt);
-	}
-
-	/**
-	 * Set the URL of an XSL transformation which can be applied to payloads in order to 
-	 * generate an appropriate message body element.
-	 * 
-	 * @param bodyXslt The URL of an XSL
-	 */
-	public void setBodyXSLT(String bodyXslt)
-	{
-		addField(ConfigureNodeFields.body_xslt, FormField.TYPE_TEXT_SINGLE);
-		setAnswer(ConfigureNodeFields.body_xslt.getFieldName(), bodyXslt);
-	}
-	
-	/**
-	 * The id's of the child nodes associated with a collection node (both leaf and collection).
-	 * 
-	 * @return Iterator over the list of child nodes.
-	 */
-	public Iterator<String> getChildren()
-	{
-		return getFieldValues(ConfigureNodeFields.children);
-	}
-	
-	/**
-	 * Set the list of child node ids that are associated with a collection node.
-	 * 
-	 * @param children
-	 */
-	public void setChildren(List<String> children)
-	{
-		addField(ConfigureNodeFields.children, FormField.TYPE_TEXT_MULTI);
-		setAnswer(ConfigureNodeFields.children.getFieldName(), children);
-	}
-	
-	/**
-	 * Returns the policy that determines who may associate children with the node.
-	 *  
-	 * @return The current policy
-	 */
-	public ChildrenAssociationPolicy getChildrenAssociationPolicy()
-	{
-		String value = getFieldValue(ConfigureNodeFields.children_association_policy);
-		
-		if (value == null)
-			return null;
-		else
-			return ChildrenAssociationPolicy.valueOf(value);
-	}
-	
-	/**
-	 * Sets the policy that determines who may associate children with the node.
-	 * 
-	 * @param policy The policy being set
-	 */
-	public void setChildrenAssociationPolicy(ChildrenAssociationPolicy policy)
-	{
-		addField(ConfigureNodeFields.children_association_policy, FormField.TYPE_LIST_SINGLE);
-        List<String> values = new ArrayList<String>(1);
-        values.add(policy.toString());
-        setAnswer(ConfigureNodeFields.children_association_policy.getFieldName(), values);
-	}
-	
-	/**
-	 * Iterator of JID's that are on the whitelist that determines who can associate child nodes 
-	 * with the collection node.  This is only relevant if {@link #getChildrenAssociationPolicy()} is set to
-	 * {@link ChildrenAssociationPolicy#whitelist}.
-	 * 
-	 * @return Iterator over whitelist
-	 */
-	public Iterator<String> getChildrenAssociationWhitelist()
-	{
-		return getFieldValues(ConfigureNodeFields.children_association_whitelist);
-	}
-	
-	/**
-	 * Set the JID's in the whitelist of users that can associate child nodes with the collection 
-	 * node.  This is only relevant if {@link #getChildrenAssociationPolicy()} is set to
-	 * {@link ChildrenAssociationPolicy#whitelist}.
-	 * 
-	 * @param whitelist The list of JID's
-	 */
-	public void setChildrenAssociationWhitelist(List<String> whitelist)
-	{
-		addField(ConfigureNodeFields.children_association_whitelist, FormField.TYPE_JID_MULTI);
-		setAnswer(ConfigureNodeFields.children_association_whitelist.getFieldName(), whitelist);
-	}
-
-	/**
-	 * Gets the maximum number of child nodes that can be associated with the collection node.
-	 * 
-	 * @return The maximum number of child nodes
-	 */
-	public int getChildrenMax()
-	{
-		return Integer.parseInt(getFieldValue(ConfigureNodeFields.children_max));
-	}
-
-	/**
-	 * Set the maximum number of child nodes that can be associated with a collection node.
-	 * 
-	 * @param max The maximum number of child nodes.
-	 */
-	public void setChildrenMax(int max)
-	{
-		addField(ConfigureNodeFields.children_max, FormField.TYPE_TEXT_SINGLE);
-		setAnswer(ConfigureNodeFields.children_max.getFieldName(), max);
-	}
-
-	/**
-	 * Gets the collection node which the node is affiliated with.
-	 * 
-	 * @return The collection node id
-	 */
-	public String getCollection()
-	{
-		return getFieldValue(ConfigureNodeFields.collection);
-	}
-
-	/**
-	 * Sets the collection node which the node is affiliated with.
-	 * 
-	 * @param collection The node id of the collection node
-	 */
-	public void setCollection(String collection)
-	{
-		addField(ConfigureNodeFields.collection, FormField.TYPE_TEXT_SINGLE);
-		setAnswer(ConfigureNodeFields.collection.getFieldName(), collection);
-	}
-
-	/**
-	 * Gets the URL of an XSL transformation which can be applied to the payload
-	 * format in order to generate a valid Data Forms result that the client could
-	 * display using a generic Data Forms rendering engine.
-	 * 
-	 * @return The URL of an XSL transformation
-	 */
-	public String getDataformXSLT()
-	{
-		return getFieldValue(ConfigureNodeFields.dataform_xslt);
-	}
-
-	/**
-	 * Sets the URL of an XSL transformation which can be applied to the payload
-	 * format in order to generate a valid Data Forms result that the client could
-	 * display using a generic Data Forms rendering engine.
-	 * 
-	 * @param url The URL of an XSL transformation
-	 */
-	public void setDataformXSLT(String url)
-	{
-		addField(ConfigureNodeFields.dataform_xslt, FormField.TYPE_TEXT_SINGLE);
-		setAnswer(ConfigureNodeFields.dataform_xslt.getFieldName(), url);
-	}
-
-	/**
-	 * Does the node deliver payloads with event notifications.
-	 * 
-	 * @return true if it does, false otherwise
-	 */
-	public boolean isDeliverPayloads()
-	{
-		return parseBoolean(getFieldValue(ConfigureNodeFields.deliver_payloads));
-	}
-	
-	/**
-	 * Sets whether the node will deliver payloads with event notifications.
-	 * 
-	 * @param deliver true if the payload will be delivered, false otherwise
-	 */
-	public void setDeliverPayloads(boolean deliver)
-	{
-		addField(ConfigureNodeFields.deliver_payloads, FormField.TYPE_BOOLEAN);
-		setAnswer(ConfigureNodeFields.deliver_payloads.getFieldName(), deliver);
-	}
-
-	/**
-	 * Determines who should get replies to items
-	 * 
-	 * @return Who should get the reply
-	 */
-	public ItemReply getItemReply()
-	{
-		String value = getFieldValue(ConfigureNodeFields.itemreply);
-		
-		if (value == null)
-			return null;
-		else
-			return ItemReply.valueOf(value);
-	}
-
-	/**
-	 * Sets who should get the replies to items
-	 * 
-	 * @param reply Defines who should get the reply
-	 */
-	public void setItemReply(ItemReply reply)
-	{
-		addField(ConfigureNodeFields.itemreply, FormField.TYPE_LIST_SINGLE);
-		setAnswer(ConfigureNodeFields.itemreply.getFieldName(), getListSingle(reply.toString()));
-	}
-
-	/**
-	 * Gets the maximum number of items to persisted to this node if {@link #isPersistItems()} is
-	 * true.
-	 * 
-	 * @return The maximum number of items to persist
-	 */
-	public int getMaxItems()
-	{
-		return Integer.parseInt(getFieldValue(ConfigureNodeFields.max_items));
-	}
-
-	/**
-	 * Set the maximum number of items to persisted to this node if {@link #isPersistItems()} is
-	 * true.
-	 * 
-	 * @param max The maximum number of items to persist
-	 */
-	public void setMaxItems(int max)
-	{
-		addField(ConfigureNodeFields.max_items, FormField.TYPE_TEXT_SINGLE);
-		setAnswer(ConfigureNodeFields.max_items.getFieldName(), max);
-	}
-	
-	/**
-	 * Gets the maximum payload size in bytes.
-	 * 
-	 * @return The maximum payload size
-	 */
-	public int getMaxPayloadSize()
-	{
-		return Integer.parseInt(getFieldValue(ConfigureNodeFields.max_payload_size));
-	}
-
-	/**
-	 * Sets the maximum payload size in bytes
-	 * 
-	 * @param max The maximum payload size
-	 */
-	public void setMaxPayloadSize(int max)
-	{
-		addField(ConfigureNodeFields.max_payload_size, FormField.TYPE_TEXT_SINGLE);
-		setAnswer(ConfigureNodeFields.max_payload_size.getFieldName(), max);
-	}
-	
-	/**
-	 * Gets the node type
-	 * 
-	 * @return The node type
-	 */
-	public NodeType getNodeType()
-	{
-		String value = getFieldValue(ConfigureNodeFields.node_type);
-		
-		if (value == null)
-			return null;
-		else
-			return NodeType.valueOf(value);
-	}
-	
-	/**
-	 * Sets the node type
-	 * 
-	 * @param type The node type
-	 */
-	public void setNodeType(NodeType type)
-	{
-		addField(ConfigureNodeFields.node_type, FormField.TYPE_LIST_SINGLE);
-		setAnswer(ConfigureNodeFields.node_type.getFieldName(), getListSingle(type.toString()));
-	}
-
-	/**
-	 * Determines if subscribers should be notified when the configuration changes.
-	 * 
-	 * @return true if they should be notified, false otherwise
-	 */
-	public boolean isNotifyConfig()
-	{
-		return parseBoolean(getFieldValue(ConfigureNodeFields.notify_config));
-	}
-	
-	/**
-	 * Sets whether subscribers should be notified when the configuration changes.
-	 * 
-	 * @param notify true if subscribers should be notified, false otherwise
-	 */
-	public void setNotifyConfig(boolean notify)
-	{
-		addField(ConfigureNodeFields.notify_config, FormField.TYPE_BOOLEAN);
-		setAnswer(ConfigureNodeFields.notify_config.getFieldName(), notify);
-	}
-
-	/**
-	 * Determines whether subscribers should be notified when the node is deleted.
-	 * 
-	 * @return true if subscribers should be notified, false otherwise
-	 */
-	public boolean isNotifyDelete()
-	{
-		return parseBoolean(getFieldValue(ConfigureNodeFields.notify_delete));
-	}
-	
-	/**
-	 * Sets whether subscribers should be notified when the node is deleted.
-	 * 
-	 * @param notify true if subscribers should be notified, false otherwise
-	 */
-	public void setNotifyDelete(boolean notify) 
-	{
-		addField(ConfigureNodeFields.notify_delete, FormField.TYPE_BOOLEAN);
-		setAnswer(ConfigureNodeFields.notify_delete.getFieldName(), notify);
-	}
-
-	/**
-	 * Determines whether subscribers should be notified when items are deleted 
-	 * from the node.
-	 * 
-	 * @return true if subscribers should be notified, false otherwise
-	 */
-	public boolean isNotifyRetract()
-	{
-		return parseBoolean(getFieldValue(ConfigureNodeFields.notify_retract));
-	}
-	
-	/**
-	 * Sets whether subscribers should be notified when items are deleted 
-	 * from the node.
-	 * 
-	 * @param notify true if subscribers should be notified, false otherwise
-	 */
-	public void setNotifyRetract(boolean notify) 
-	{
-		addField(ConfigureNodeFields.notify_retract, FormField.TYPE_BOOLEAN);
-		setAnswer(ConfigureNodeFields.notify_retract.getFieldName(), notify);
-	}
-	
-	/**
-	 * Determines whether items should be persisted in the node.
-	 * 
-	 * @return true if items are persisted
-	 */
-	public boolean isPersistItems()
-	{
-		return parseBoolean(getFieldValue(ConfigureNodeFields.persist_items));
-	}
-	
-	/**
-	 * Sets whether items should be persisted in the node.
-	 * 
-	 * @param persist true if items should be persisted, false otherwise
-	 */
-	public void setPersistentItems(boolean persist) 
-	{
-		addField(ConfigureNodeFields.persist_items, FormField.TYPE_BOOLEAN);
-		setAnswer(ConfigureNodeFields.persist_items.getFieldName(), persist);
-	}
-
-	/**
-	 * Determines whether to deliver notifications to available users only.
-	 * 
-	 * @return true if users must be available
-	 */
-	public boolean isPresenceBasedDelivery()
-	{
-		return parseBoolean(getFieldValue(ConfigureNodeFields.presence_based_delivery));
-	}
-	
-	/**
-	 * Sets whether to deliver notifications to available users only.
-	 * 
-	 * @param presenceBased true if user must be available, false otherwise
-	 */
-	public void setPresenceBasedDelivery(boolean presenceBased) 
-	{
-		addField(ConfigureNodeFields.presence_based_delivery, FormField.TYPE_BOOLEAN);
-		setAnswer(ConfigureNodeFields.presence_based_delivery.getFieldName(), presenceBased);
-	}
-
-	/**
-	 * Gets the publishing model for the node, which determines who may publish to it.
-	 * 
-	 * @return The publishing model
-	 */
-	public PublishModel getPublishModel()
-	{
-		String value = getFieldValue(ConfigureNodeFields.publish_model);
-		
-		if (value == null)
-			return null;
-		else
-			return PublishModel.valueOf(value);
-	}
-
-	/**
-	 * Sets the publishing model for the node, which determines who may publish to it.
-	 * 
-	 * @param publish The enum representing the possible options for the publishing model
-	 */
-	public void setPublishModel(PublishModel publish) 
-	{
-		addField(ConfigureNodeFields.publish_model, FormField.TYPE_LIST_SINGLE);
-		setAnswer(ConfigureNodeFields.publish_model.getFieldName(), getListSingle(publish.toString()));
-	}
-	
-	/**
-	 * Iterator over the multi user chat rooms that are specified as reply rooms.
-	 * 
-	 * @return The reply room JID's
-	 */
-	public Iterator<String> getReplyRoom()
-	{
-		return getFieldValues(ConfigureNodeFields.replyroom);
-	}
-	
-	/**
-	 * Sets the multi user chat rooms that are specified as reply rooms.
-	 * 
-	 * @param replyRooms The multi user chat room to use as reply rooms
-	 */
-	public void setReplyRoom(List<String> replyRooms) 
-	{
-		addField(ConfigureNodeFields.replyroom, FormField.TYPE_LIST_MULTI);
-		setAnswer(ConfigureNodeFields.replyroom.getFieldName(), replyRooms);
-	}
-	
-	/**
-	 * Gets the specific JID's for reply to.
-	 *  
-	 * @return The JID's
-	 */
-	public Iterator<String> getReplyTo()
-	{
-		return getFieldValues(ConfigureNodeFields.replyto);
-	}
-	
-	/**
-	 * Sets the specific JID's for reply to.
-	 * 
-	 * @param replyTos The JID's to reply to
-	 */
-	public void setReplyTo(List<String> replyTos)
-	{
-		addField(ConfigureNodeFields.replyto, FormField.TYPE_LIST_MULTI);
-		setAnswer(ConfigureNodeFields.replyto.getFieldName(), replyTos);
-	}
-	
-	/**
-	 * Gets the roster groups that are allowed to subscribe and retrieve items.
-	 *  
-	 * @return The roster groups
-	 */
-	public Iterator<String> getRosterGroupsAllowed()
-	{
-		return getFieldValues(ConfigureNodeFields.roster_groups_allowed);
-	}
-	
-	/**
-	 * Sets the roster groups that are allowed to subscribe and retrieve items.
-	 * 
-	 * @param groups The roster groups
-	 */
-	public void setRosterGroupsAllowed(List<String> groups)
-	{
-		addField(ConfigureNodeFields.roster_groups_allowed, FormField.TYPE_LIST_MULTI);
-		setAnswer(ConfigureNodeFields.roster_groups_allowed.getFieldName(), groups);
-	}
-	
-	/**
-	 * Determines if subscriptions are allowed.
-	 * 
-	 * @return true if subscriptions are allowed, false otherwise
-	 */
-	public boolean isSubscibe()
-	{
-		return parseBoolean(getFieldValue(ConfigureNodeFields.subscribe));
-	}
-
-	/**
-	 * Sets whether subscriptions are allowed.
-	 * 
-	 * @param subscribe true if they are, false otherwise
-	 */
-	public void setSubscribe(boolean subscribe)
-	{
-		addField(ConfigureNodeFields.subscribe, FormField.TYPE_BOOLEAN);
-		setAnswer(ConfigureNodeFields.subscribe.getFieldName(), subscribe);
-	}
-	
-	/**
-	 * Gets the human readable node title.
-	 * 
-	 * @return The node title
-	 */
-	public String getTitle()
-	{
-		return getFieldValue(ConfigureNodeFields.title);
-	}
-
-	/**
-	 * Sets a human readable title for the node.
-	 * 
-	 * @param title The node title
-	 */
-	public void setTitle(String title) 
-	{
-		addField(ConfigureNodeFields.title, FormField.TYPE_TEXT_SINGLE);
-		setAnswer(ConfigureNodeFields.title.getFieldName(), title);
-	}
-	
-	/**
-	 * The type of node data, usually specified by the namespace of the payload (if any).
-	 * 
-	 * @return The type of node data
-	 */
-	public String getDataType()
-	{
-		return getFieldValue(ConfigureNodeFields.type);
-	}
-
-	/**
-	 * Sets the type of node data, usually specified by the namespace of the payload (if any).
-	 * 
-	 * @param type The type of node data
-	 */
-	public void setDataType(String type) 
-	{
-		addField(ConfigureNodeFields.type, FormField.TYPE_TEXT_SINGLE);
-		setAnswer(ConfigureNodeFields.type.getFieldName(), type);
-	}
-	
-	@Override
-	public String toString()
-	{
-		StringBuilder result = new StringBuilder(getClass().getName() + " Content [");
-		
-		Iterator<FormField> fields = getFields();
-		
-		while (fields.hasNext())
-		{
-			FormField formField = fields.next();
-			result.append('(');
-			result.append(formField.getVariable());
-			result.append(':');
-			
-			Iterator<String> values = formField.getValues();
-			StringBuilder valuesBuilder = new StringBuilder();
-				
-			while (values.hasNext())
-			{
-				if (valuesBuilder.length() > 0)
-					result.append(',');
-				String value = (String)values.next();
-				valuesBuilder.append(value);
-			}
-			
-			if (valuesBuilder.length() == 0)
-				valuesBuilder.append("NOT SET");
-			result.append(valuesBuilder);
-			result.append(')');
-		}
-		result.append(']');
-		return result.toString();
-	}
-
-	static private boolean parseBoolean(String fieldValue)
-	{
-		return ("1".equals(fieldValue) || "true".equals(fieldValue));
-	}
-
-	private String getFieldValue(ConfigureNodeFields field)
-	{
-		FormField formField = getField(field.getFieldName());
-		
-		return (formField.getValues().hasNext()) ? formField.getValues().next() : null;
-	}
-
-	private Iterator<String> getFieldValues(ConfigureNodeFields field)
-	{
-		FormField formField = getField(field.getFieldName());
-		
-		return formField.getValues();
-	}
-
-	private void addField(ConfigureNodeFields nodeField, String type)
-	{
-		String fieldName = nodeField.getFieldName();
-		
-		if (getField(fieldName) == null)
-		{
-			FormField field = new FormField(fieldName);
-			field.setType(type);
-			addField(field);
-		}
-	}
-
-	private List<String> getListSingle(String value)
-	{
-		List<String> list = new ArrayList<String>(1);
-		list.add(value);
-		return list;
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jivesoftware.smackx.Form;
+import org.jivesoftware.smackx.FormField;
+import org.jivesoftware.smackx.packet.DataForm;
+
+/**
+ * A decorator for a {@link Form} to easily enable reading and updating
+ * of node configuration.  All operations read or update the underlying {@link DataForm}.
+ * 
+ * <p>Unlike the {@link Form}.setAnswer(XXX)} methods, which throw an exception if the field does not
+ * exist, all <b>ConfigureForm.setXXX</b> methods will create the field in the wrapped form
+ * if it does not already exist. 
+ * 
+ * @author Robin Collier
+ */
+public class ConfigureForm extends Form
+{
+	/**
+	 * Create a decorator from an existing {@link DataForm} that has been
+	 * retrieved from parsing a node configuration request.
+	 * 
+	 * @param configDataForm
+	 */
+	public ConfigureForm(DataForm configDataForm)
+	{
+		super(configDataForm);
+	}
+	
+	/**
+	 * Create a decorator from an existing {@link Form} for node configuration.
+	 * Typically, this can be used to create a decorator for an answer form
+	 * by using the result of {@link #createAnswerForm()} as the input parameter.
+	 * 
+	 * @param nodeConfigForm
+	 */
+	public ConfigureForm(Form nodeConfigForm)
+	{
+		super(nodeConfigForm.getDataFormToSend());
+	}
+	
+	/**
+	 * Create a new form for configuring a node.  This would typically only be used 
+	 * when creating and configuring a node at the same time via {@link PubSubManager#createNode(String, Form)}, since 
+	 * configuration of an existing node is typically accomplished by calling {@link LeafNode#getNodeConfiguration()} and
+	 * using the resulting form to create a answer form.  See {@link #ConfigureForm(Form)}.
+	 * @param formType
+	 */
+	public ConfigureForm(FormType formType)
+	{
+		super(formType.toString());
+	}
+	
+	/**
+	 * Get the currently configured {@link AccessModel}, null if it is not set.
+	 * 
+	 * @return The current {@link AccessModel}
+	 */
+	public AccessModel getAccessModel()
+	{
+		String value = getFieldValue(ConfigureNodeFields.access_model);
+		
+		if (value == null)
+			return null;
+		else
+			return AccessModel.valueOf(value);
+	}
+	
+	/**
+	 * Sets the value of access model.
+	 * 
+	 * @param accessModel
+	 */
+	public void setAccessModel(AccessModel accessModel)
+	{
+		addField(ConfigureNodeFields.access_model, FormField.TYPE_LIST_SINGLE);
+		setAnswer(ConfigureNodeFields.access_model.getFieldName(), getListSingle(accessModel.toString()));
+	}
+
+	/**
+	 * Returns the URL of an XSL transformation which can be applied to payloads in order to 
+	 * generate an appropriate message body element.
+	 * 
+	 * @return URL to an XSL
+	 */
+	public String getBodyXSLT()
+	{
+		return getFieldValue(ConfigureNodeFields.body_xslt);
+	}
+
+	/**
+	 * Set the URL of an XSL transformation which can be applied to payloads in order to 
+	 * generate an appropriate message body element.
+	 * 
+	 * @param bodyXslt The URL of an XSL
+	 */
+	public void setBodyXSLT(String bodyXslt)
+	{
+		addField(ConfigureNodeFields.body_xslt, FormField.TYPE_TEXT_SINGLE);
+		setAnswer(ConfigureNodeFields.body_xslt.getFieldName(), bodyXslt);
+	}
+	
+	/**
+	 * The id's of the child nodes associated with a collection node (both leaf and collection).
+	 * 
+	 * @return Iterator over the list of child nodes.
+	 */
+	public Iterator<String> getChildren()
+	{
+		return getFieldValues(ConfigureNodeFields.children);
+	}
+	
+	/**
+	 * Set the list of child node ids that are associated with a collection node.
+	 * 
+	 * @param children
+	 */
+	public void setChildren(List<String> children)
+	{
+		addField(ConfigureNodeFields.children, FormField.TYPE_TEXT_MULTI);
+		setAnswer(ConfigureNodeFields.children.getFieldName(), children);
+	}
+	
+	/**
+	 * Returns the policy that determines who may associate children with the node.
+	 *  
+	 * @return The current policy
+	 */
+	public ChildrenAssociationPolicy getChildrenAssociationPolicy()
+	{
+		String value = getFieldValue(ConfigureNodeFields.children_association_policy);
+		
+		if (value == null)
+			return null;
+		else
+			return ChildrenAssociationPolicy.valueOf(value);
+	}
+	
+	/**
+	 * Sets the policy that determines who may associate children with the node.
+	 * 
+	 * @param policy The policy being set
+	 */
+	public void setChildrenAssociationPolicy(ChildrenAssociationPolicy policy)
+	{
+		addField(ConfigureNodeFields.children_association_policy, FormField.TYPE_LIST_SINGLE);
+        List<String> values = new ArrayList<String>(1);
+        values.add(policy.toString());
+        setAnswer(ConfigureNodeFields.children_association_policy.getFieldName(), values);
+	}
+	
+	/**
+	 * Iterator of JID's that are on the whitelist that determines who can associate child nodes 
+	 * with the collection node.  This is only relevant if {@link #getChildrenAssociationPolicy()} is set to
+	 * {@link ChildrenAssociationPolicy#whitelist}.
+	 * 
+	 * @return Iterator over whitelist
+	 */
+	public Iterator<String> getChildrenAssociationWhitelist()
+	{
+		return getFieldValues(ConfigureNodeFields.children_association_whitelist);
+	}
+	
+	/**
+	 * Set the JID's in the whitelist of users that can associate child nodes with the collection 
+	 * node.  This is only relevant if {@link #getChildrenAssociationPolicy()} is set to
+	 * {@link ChildrenAssociationPolicy#whitelist}.
+	 * 
+	 * @param whitelist The list of JID's
+	 */
+	public void setChildrenAssociationWhitelist(List<String> whitelist)
+	{
+		addField(ConfigureNodeFields.children_association_whitelist, FormField.TYPE_JID_MULTI);
+		setAnswer(ConfigureNodeFields.children_association_whitelist.getFieldName(), whitelist);
+	}
+
+	/**
+	 * Gets the maximum number of child nodes that can be associated with the collection node.
+	 * 
+	 * @return The maximum number of child nodes
+	 */
+	public int getChildrenMax()
+	{
+		return Integer.parseInt(getFieldValue(ConfigureNodeFields.children_max));
+	}
+
+	/**
+	 * Set the maximum number of child nodes that can be associated with a collection node.
+	 * 
+	 * @param max The maximum number of child nodes.
+	 */
+	public void setChildrenMax(int max)
+	{
+		addField(ConfigureNodeFields.children_max, FormField.TYPE_TEXT_SINGLE);
+		setAnswer(ConfigureNodeFields.children_max.getFieldName(), max);
+	}
+
+	/**
+	 * Gets the collection node which the node is affiliated with.
+	 * 
+	 * @return The collection node id
+	 */
+	public String getCollection()
+	{
+		return getFieldValue(ConfigureNodeFields.collection);
+	}
+
+	/**
+	 * Sets the collection node which the node is affiliated with.
+	 * 
+	 * @param collection The node id of the collection node
+	 */
+	public void setCollection(String collection)
+	{
+		addField(ConfigureNodeFields.collection, FormField.TYPE_TEXT_SINGLE);
+		setAnswer(ConfigureNodeFields.collection.getFieldName(), collection);
+	}
+
+	/**
+	 * Gets the URL of an XSL transformation which can be applied to the payload
+	 * format in order to generate a valid Data Forms result that the client could
+	 * display using a generic Data Forms rendering engine.
+	 * 
+	 * @return The URL of an XSL transformation
+	 */
+	public String getDataformXSLT()
+	{
+		return getFieldValue(ConfigureNodeFields.dataform_xslt);
+	}
+
+	/**
+	 * Sets the URL of an XSL transformation which can be applied to the payload
+	 * format in order to generate a valid Data Forms result that the client could
+	 * display using a generic Data Forms rendering engine.
+	 * 
+	 * @param url The URL of an XSL transformation
+	 */
+	public void setDataformXSLT(String url)
+	{
+		addField(ConfigureNodeFields.dataform_xslt, FormField.TYPE_TEXT_SINGLE);
+		setAnswer(ConfigureNodeFields.dataform_xslt.getFieldName(), url);
+	}
+
+	/**
+	 * Does the node deliver payloads with event notifications.
+	 * 
+	 * @return true if it does, false otherwise
+	 */
+	public boolean isDeliverPayloads()
+	{
+		return parseBoolean(getFieldValue(ConfigureNodeFields.deliver_payloads));
+	}
+	
+	/**
+	 * Sets whether the node will deliver payloads with event notifications.
+	 * 
+	 * @param deliver true if the payload will be delivered, false otherwise
+	 */
+	public void setDeliverPayloads(boolean deliver)
+	{
+		addField(ConfigureNodeFields.deliver_payloads, FormField.TYPE_BOOLEAN);
+		setAnswer(ConfigureNodeFields.deliver_payloads.getFieldName(), deliver);
+	}
+
+	/**
+	 * Determines who should get replies to items
+	 * 
+	 * @return Who should get the reply
+	 */
+	public ItemReply getItemReply()
+	{
+		String value = getFieldValue(ConfigureNodeFields.itemreply);
+		
+		if (value == null)
+			return null;
+		else
+			return ItemReply.valueOf(value);
+	}
+
+	/**
+	 * Sets who should get the replies to items
+	 * 
+	 * @param reply Defines who should get the reply
+	 */
+	public void setItemReply(ItemReply reply)
+	{
+		addField(ConfigureNodeFields.itemreply, FormField.TYPE_LIST_SINGLE);
+		setAnswer(ConfigureNodeFields.itemreply.getFieldName(), getListSingle(reply.toString()));
+	}
+
+	/**
+	 * Gets the maximum number of items to persisted to this node if {@link #isPersistItems()} is
+	 * true.
+	 * 
+	 * @return The maximum number of items to persist
+	 */
+	public int getMaxItems()
+	{
+		return Integer.parseInt(getFieldValue(ConfigureNodeFields.max_items));
+	}
+
+	/**
+	 * Set the maximum number of items to persisted to this node if {@link #isPersistItems()} is
+	 * true.
+	 * 
+	 * @param max The maximum number of items to persist
+	 */
+	public void setMaxItems(int max)
+	{
+		addField(ConfigureNodeFields.max_items, FormField.TYPE_TEXT_SINGLE);
+		setAnswer(ConfigureNodeFields.max_items.getFieldName(), max);
+	}
+	
+	/**
+	 * Gets the maximum payload size in bytes.
+	 * 
+	 * @return The maximum payload size
+	 */
+	public int getMaxPayloadSize()
+	{
+		return Integer.parseInt(getFieldValue(ConfigureNodeFields.max_payload_size));
+	}
+
+	/**
+	 * Sets the maximum payload size in bytes
+	 * 
+	 * @param max The maximum payload size
+	 */
+	public void setMaxPayloadSize(int max)
+	{
+		addField(ConfigureNodeFields.max_payload_size, FormField.TYPE_TEXT_SINGLE);
+		setAnswer(ConfigureNodeFields.max_payload_size.getFieldName(), max);
+	}
+	
+	/**
+	 * Gets the node type
+	 * 
+	 * @return The node type
+	 */
+	public NodeType getNodeType()
+	{
+		String value = getFieldValue(ConfigureNodeFields.node_type);
+		
+		if (value == null)
+			return null;
+		else
+			return NodeType.valueOf(value);
+	}
+	
+	/**
+	 * Sets the node type
+	 * 
+	 * @param type The node type
+	 */
+	public void setNodeType(NodeType type)
+	{
+		addField(ConfigureNodeFields.node_type, FormField.TYPE_LIST_SINGLE);
+		setAnswer(ConfigureNodeFields.node_type.getFieldName(), getListSingle(type.toString()));
+	}
+
+	/**
+	 * Determines if subscribers should be notified when the configuration changes.
+	 * 
+	 * @return true if they should be notified, false otherwise
+	 */
+	public boolean isNotifyConfig()
+	{
+		return parseBoolean(getFieldValue(ConfigureNodeFields.notify_config));
+	}
+	
+	/**
+	 * Sets whether subscribers should be notified when the configuration changes.
+	 * 
+	 * @param notify true if subscribers should be notified, false otherwise
+	 */
+	public void setNotifyConfig(boolean notify)
+	{
+		addField(ConfigureNodeFields.notify_config, FormField.TYPE_BOOLEAN);
+		setAnswer(ConfigureNodeFields.notify_config.getFieldName(), notify);
+	}
+
+	/**
+	 * Determines whether subscribers should be notified when the node is deleted.
+	 * 
+	 * @return true if subscribers should be notified, false otherwise
+	 */
+	public boolean isNotifyDelete()
+	{
+		return parseBoolean(getFieldValue(ConfigureNodeFields.notify_delete));
+	}
+	
+	/**
+	 * Sets whether subscribers should be notified when the node is deleted.
+	 * 
+	 * @param notify true if subscribers should be notified, false otherwise
+	 */
+	public void setNotifyDelete(boolean notify) 
+	{
+		addField(ConfigureNodeFields.notify_delete, FormField.TYPE_BOOLEAN);
+		setAnswer(ConfigureNodeFields.notify_delete.getFieldName(), notify);
+	}
+
+	/**
+	 * Determines whether subscribers should be notified when items are deleted 
+	 * from the node.
+	 * 
+	 * @return true if subscribers should be notified, false otherwise
+	 */
+	public boolean isNotifyRetract()
+	{
+		return parseBoolean(getFieldValue(ConfigureNodeFields.notify_retract));
+	}
+	
+	/**
+	 * Sets whether subscribers should be notified when items are deleted 
+	 * from the node.
+	 * 
+	 * @param notify true if subscribers should be notified, false otherwise
+	 */
+	public void setNotifyRetract(boolean notify) 
+	{
+		addField(ConfigureNodeFields.notify_retract, FormField.TYPE_BOOLEAN);
+		setAnswer(ConfigureNodeFields.notify_retract.getFieldName(), notify);
+	}
+	
+	/**
+	 * Determines whether items should be persisted in the node.
+	 * 
+	 * @return true if items are persisted
+	 */
+	public boolean isPersistItems()
+	{
+		return parseBoolean(getFieldValue(ConfigureNodeFields.persist_items));
+	}
+	
+	/**
+	 * Sets whether items should be persisted in the node.
+	 * 
+	 * @param persist true if items should be persisted, false otherwise
+	 */
+	public void setPersistentItems(boolean persist) 
+	{
+		addField(ConfigureNodeFields.persist_items, FormField.TYPE_BOOLEAN);
+		setAnswer(ConfigureNodeFields.persist_items.getFieldName(), persist);
+	}
+
+	/**
+	 * Determines whether to deliver notifications to available users only.
+	 * 
+	 * @return true if users must be available
+	 */
+	public boolean isPresenceBasedDelivery()
+	{
+		return parseBoolean(getFieldValue(ConfigureNodeFields.presence_based_delivery));
+	}
+	
+	/**
+	 * Sets whether to deliver notifications to available users only.
+	 * 
+	 * @param presenceBased true if user must be available, false otherwise
+	 */
+	public void setPresenceBasedDelivery(boolean presenceBased) 
+	{
+		addField(ConfigureNodeFields.presence_based_delivery, FormField.TYPE_BOOLEAN);
+		setAnswer(ConfigureNodeFields.presence_based_delivery.getFieldName(), presenceBased);
+	}
+
+	/**
+	 * Gets the publishing model for the node, which determines who may publish to it.
+	 * 
+	 * @return The publishing model
+	 */
+	public PublishModel getPublishModel()
+	{
+		String value = getFieldValue(ConfigureNodeFields.publish_model);
+		
+		if (value == null)
+			return null;
+		else
+			return PublishModel.valueOf(value);
+	}
+
+	/**
+	 * Sets the publishing model for the node, which determines who may publish to it.
+	 * 
+	 * @param publish The enum representing the possible options for the publishing model
+	 */
+	public void setPublishModel(PublishModel publish) 
+	{
+		addField(ConfigureNodeFields.publish_model, FormField.TYPE_LIST_SINGLE);
+		setAnswer(ConfigureNodeFields.publish_model.getFieldName(), getListSingle(publish.toString()));
+	}
+	
+	/**
+	 * Iterator over the multi user chat rooms that are specified as reply rooms.
+	 * 
+	 * @return The reply room JID's
+	 */
+	public Iterator<String> getReplyRoom()
+	{
+		return getFieldValues(ConfigureNodeFields.replyroom);
+	}
+	
+	/**
+	 * Sets the multi user chat rooms that are specified as reply rooms.
+	 * 
+	 * @param replyRooms The multi user chat room to use as reply rooms
+	 */
+	public void setReplyRoom(List<String> replyRooms) 
+	{
+		addField(ConfigureNodeFields.replyroom, FormField.TYPE_LIST_MULTI);
+		setAnswer(ConfigureNodeFields.replyroom.getFieldName(), replyRooms);
+	}
+	
+	/**
+	 * Gets the specific JID's for reply to.
+	 *  
+	 * @return The JID's
+	 */
+	public Iterator<String> getReplyTo()
+	{
+		return getFieldValues(ConfigureNodeFields.replyto);
+	}
+	
+	/**
+	 * Sets the specific JID's for reply to.
+	 * 
+	 * @param replyTos The JID's to reply to
+	 */
+	public void setReplyTo(List<String> replyTos)
+	{
+		addField(ConfigureNodeFields.replyto, FormField.TYPE_LIST_MULTI);
+		setAnswer(ConfigureNodeFields.replyto.getFieldName(), replyTos);
+	}
+	
+	/**
+	 * Gets the roster groups that are allowed to subscribe and retrieve items.
+	 *  
+	 * @return The roster groups
+	 */
+	public Iterator<String> getRosterGroupsAllowed()
+	{
+		return getFieldValues(ConfigureNodeFields.roster_groups_allowed);
+	}
+	
+	/**
+	 * Sets the roster groups that are allowed to subscribe and retrieve items.
+	 * 
+	 * @param groups The roster groups
+	 */
+	public void setRosterGroupsAllowed(List<String> groups)
+	{
+		addField(ConfigureNodeFields.roster_groups_allowed, FormField.TYPE_LIST_MULTI);
+		setAnswer(ConfigureNodeFields.roster_groups_allowed.getFieldName(), groups);
+	}
+	
+	/**
+	 * Determines if subscriptions are allowed.
+	 * 
+	 * @return true if subscriptions are allowed, false otherwise
+	 */
+	public boolean isSubscibe()
+	{
+		return parseBoolean(getFieldValue(ConfigureNodeFields.subscribe));
+	}
+
+	/**
+	 * Sets whether subscriptions are allowed.
+	 * 
+	 * @param subscribe true if they are, false otherwise
+	 */
+	public void setSubscribe(boolean subscribe)
+	{
+		addField(ConfigureNodeFields.subscribe, FormField.TYPE_BOOLEAN);
+		setAnswer(ConfigureNodeFields.subscribe.getFieldName(), subscribe);
+	}
+	
+	/**
+	 * Gets the human readable node title.
+	 * 
+	 * @return The node title
+	 */
+	public String getTitle()
+	{
+		return getFieldValue(ConfigureNodeFields.title);
+	}
+
+	/**
+	 * Sets a human readable title for the node.
+	 * 
+	 * @param title The node title
+	 */
+	public void setTitle(String title) 
+	{
+		addField(ConfigureNodeFields.title, FormField.TYPE_TEXT_SINGLE);
+		setAnswer(ConfigureNodeFields.title.getFieldName(), title);
+	}
+	
+	/**
+	 * The type of node data, usually specified by the namespace of the payload (if any).
+	 * 
+	 * @return The type of node data
+	 */
+	public String getDataType()
+	{
+		return getFieldValue(ConfigureNodeFields.type);
+	}
+
+	/**
+	 * Sets the type of node data, usually specified by the namespace of the payload (if any).
+	 * 
+	 * @param type The type of node data
+	 */
+	public void setDataType(String type) 
+	{
+		addField(ConfigureNodeFields.type, FormField.TYPE_TEXT_SINGLE);
+		setAnswer(ConfigureNodeFields.type.getFieldName(), type);
+	}
+	
+	@Override
+	public String toString()
+	{
+		StringBuilder result = new StringBuilder(getClass().getName() + " Content [");
+		
+		Iterator<FormField> fields = getFields();
+		
+		while (fields.hasNext())
+		{
+			FormField formField = fields.next();
+			result.append('(');
+			result.append(formField.getVariable());
+			result.append(':');
+			
+			Iterator<String> values = formField.getValues();
+			StringBuilder valuesBuilder = new StringBuilder();
+				
+			while (values.hasNext())
+			{
+				if (valuesBuilder.length() > 0)
+					result.append(',');
+				String value = (String)values.next();
+				valuesBuilder.append(value);
+			}
+			
+			if (valuesBuilder.length() == 0)
+				valuesBuilder.append("NOT SET");
+			result.append(valuesBuilder);
+			result.append(')');
+		}
+		result.append(']');
+		return result.toString();
+	}
+
+	static private boolean parseBoolean(String fieldValue)
+	{
+		return ("1".equals(fieldValue) || "true".equals(fieldValue));
+	}
+
+	private String getFieldValue(ConfigureNodeFields field)
+	{
+		FormField formField = getField(field.getFieldName());
+		
+		return (formField.getValues().hasNext()) ? formField.getValues().next() : null;
+	}
+
+	private Iterator<String> getFieldValues(ConfigureNodeFields field)
+	{
+		FormField formField = getField(field.getFieldName());
+		
+		return formField.getValues();
+	}
+
+	private void addField(ConfigureNodeFields nodeField, String type)
+	{
+		String fieldName = nodeField.getFieldName();
+		
+		if (getField(fieldName) == null)
+		{
+			FormField field = new FormField(fieldName);
+			field.setType(type);
+			addField(field);
+		}
+	}
+
+	private List<String> getListSingle(String value)
+	{
+		List<String> list = new ArrayList<String>(1);
+		list.add(value);
+		return list;
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ConfigureNodeFields.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ConfigureNodeFields.java
index 3912483..5b9f662 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ConfigureNodeFields.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ConfigureNodeFields.java
@@ -1,218 +1,218 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import java.net.URL;
-
-import org.jivesoftware.smackx.Form;
-
-/**
- * This enumeration represents all the fields of a node configuration form.  This enumeration
- * is not required when using the {@link ConfigureForm} to configure nodes, but may be helpful
- * for generic UI's using only a {@link Form} for configuration.
- * 
- * @author Robin Collier
- */
-public enum ConfigureNodeFields
-{
-	/**
-	 * Determines who may subscribe and retrieve items
-	 * 
-	 * <p><b>Value: {@link AccessModel}</b></p>
-	 */
-	access_model,
-
-	/**
-	 * The URL of an XSL transformation which can be applied to 
-	 * payloads in order to generate an appropriate message
-	 * body element
-	 * 
-	 * <p><b>Value: {@link URL}</b></p>
-	 */
-	body_xslt,
-	
-	/**
-	 * The collection with which a node is affiliated
-	 * 
-	 * <p><b>Value: String</b></p>
-	 */
-	collection,
-
-	/**
-	 * The URL of an XSL transformation which can be applied to 
-	 * payload format in order to generate a valid Data Forms result 
-	 * that the client could display using a generic Data Forms 
-	 * rendering engine body element.
-	 * 
-	 * <p><b>Value: {@link URL}</b></p>
-	 */
-	dataform_xslt,
-
-	/**
-	 * Whether to deliver payloads with event notifications
-	 *
-	 * <p><b>Value: boolean</b></p>
-	 */
-	deliver_payloads,
-	
-	/**
-	 * Whether owners or publisher should receive replies to items
-	 *
-	 * <p><b>Value: {@link ItemReply}</b></p>
-	 */
-	itemreply,
-	
-	/**
-	 * Who may associate leaf nodes with a collection
-	 * 
-	 * <p><b>Value: {@link ChildrenAssociationPolicy}</b></p>
-	 */
-	children_association_policy,
-	
-	/**
-	 * The list of JIDs that may associate leaf nodes with a 
-	 * collection
-	 * 
-	 * <p><b>Value: List of JIDs as Strings</b></p>
-	 */
-	children_association_whitelist,
-	
-	/**
-	 * The child nodes (leaf or collection) associated with a collection
-	 * 
-	 * <p><b>Value: List of Strings</b></p>
-	 */
-	children,
-	
-	/**
-	 * The maximum number of child nodes that can be associated with a 
-	 * collection
-	 * 
-	 * <p><b>Value: int</b></p>
-	 */
-	children_max,
-	
-	/**
-	 * The maximum number of items to persist
-	 * 
-	 * <p><b>Value: int</b></p>
-	 */
-	max_items,
-	
-	/**
-	 * The maximum payload size in bytes
-	 * 
-	 * <p><b>Value: int</b></p>
-	 */
-	max_payload_size,
-	
-	/**
-	 * Whether the node is a leaf (default) or collection
-	 * 
-	 * <p><b>Value: {@link NodeType}</b></p>
-	 */
-	node_type,
-	
-	/**
-	 * Whether to notify subscribers when the node configuration changes
-	 * 
-	 * <p><b>Value: boolean</b></p>
-	 */
-	notify_config,
-	
-	/**
-	 * Whether to notify subscribers when the node is deleted
-	 * 
-	 * <p><b>Value: boolean</b></p>
-	 */
-	notify_delete,
-
-	/**
-	 * Whether to notify subscribers when items are removed from the node
-	 * 
-	 * <p><b>Value: boolean</b></p>
-	 */
-	notify_retract,
-	
-	/**
-	 * Whether to persist items to storage.  This is required to have multiple 
-	 * items in the node. 
-	 * 
-	 * <p><b>Value: boolean</b></p>
-	 */
-	persist_items,
-	
-	/**
-	 * Whether to deliver notifications to available users only
-	 * 
-	 * <p><b>Value: boolean</b></p>
-	 */
-	presence_based_delivery,
-
-	/**
-	 * Defines who can publish to the node
-	 * 
-	 * <p><b>Value: {@link PublishModel}</b></p>
-	 */
-	publish_model,
-	
-	/**
-	 * The specific multi-user chat rooms to specify for replyroom
-	 * 
-	 * <p><b>Value: List of JIDs as Strings</b></p>
-	 */
-	replyroom,
-	
-	/**
-	 * The specific JID(s) to specify for replyto
-	 * 
-	 * <p><b>Value: List of JIDs as Strings</b></p>
-	 */
-	replyto,
-	
-	/**
-	 * The roster group(s) allowed to subscribe and retrieve items
-	 * 
-	 * <p><b>Value: List of strings</b></p>
-	 */
-	roster_groups_allowed,
-	
-	/**
-	 * Whether to allow subscriptions
-	 * 
-	 * <p><b>Value: boolean</b></p>
-	 */
-	subscribe,
-	
-	/**
-	 * A friendly name for the node
-	 * 
-	 * <p><b>Value: String</b></p>
-	 */
-	title,
-	
-	/**
-	 * The type of node data, ussually specified by the namespace 
-	 * of the payload(if any);MAY be a list-single rather than a 
-	 * text single
-	 * 
-	 * <p><b>Value: String</b></p>
-	 */
-	type;
-	
-	public String getFieldName()
-	{
-		return "pubsub#" + toString();
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import java.net.URL;
+
+import org.jivesoftware.smackx.Form;
+
+/**
+ * This enumeration represents all the fields of a node configuration form.  This enumeration
+ * is not required when using the {@link ConfigureForm} to configure nodes, but may be helpful
+ * for generic UI's using only a {@link Form} for configuration.
+ * 
+ * @author Robin Collier
+ */
+public enum ConfigureNodeFields
+{
+	/**
+	 * Determines who may subscribe and retrieve items
+	 * 
+	 * <p><b>Value: {@link AccessModel}</b></p>
+	 */
+	access_model,
+
+	/**
+	 * The URL of an XSL transformation which can be applied to 
+	 * payloads in order to generate an appropriate message
+	 * body element
+	 * 
+	 * <p><b>Value: {@link URL}</b></p>
+	 */
+	body_xslt,
+	
+	/**
+	 * The collection with which a node is affiliated
+	 * 
+	 * <p><b>Value: String</b></p>
+	 */
+	collection,
+
+	/**
+	 * The URL of an XSL transformation which can be applied to 
+	 * payload format in order to generate a valid Data Forms result 
+	 * that the client could display using a generic Data Forms 
+	 * rendering engine body element.
+	 * 
+	 * <p><b>Value: {@link URL}</b></p>
+	 */
+	dataform_xslt,
+
+	/**
+	 * Whether to deliver payloads with event notifications
+	 *
+	 * <p><b>Value: boolean</b></p>
+	 */
+	deliver_payloads,
+	
+	/**
+	 * Whether owners or publisher should receive replies to items
+	 *
+	 * <p><b>Value: {@link ItemReply}</b></p>
+	 */
+	itemreply,
+	
+	/**
+	 * Who may associate leaf nodes with a collection
+	 * 
+	 * <p><b>Value: {@link ChildrenAssociationPolicy}</b></p>
+	 */
+	children_association_policy,
+	
+	/**
+	 * The list of JIDs that may associate leaf nodes with a 
+	 * collection
+	 * 
+	 * <p><b>Value: List of JIDs as Strings</b></p>
+	 */
+	children_association_whitelist,
+	
+	/**
+	 * The child nodes (leaf or collection) associated with a collection
+	 * 
+	 * <p><b>Value: List of Strings</b></p>
+	 */
+	children,
+	
+	/**
+	 * The maximum number of child nodes that can be associated with a 
+	 * collection
+	 * 
+	 * <p><b>Value: int</b></p>
+	 */
+	children_max,
+	
+	/**
+	 * The maximum number of items to persist
+	 * 
+	 * <p><b>Value: int</b></p>
+	 */
+	max_items,
+	
+	/**
+	 * The maximum payload size in bytes
+	 * 
+	 * <p><b>Value: int</b></p>
+	 */
+	max_payload_size,
+	
+	/**
+	 * Whether the node is a leaf (default) or collection
+	 * 
+	 * <p><b>Value: {@link NodeType}</b></p>
+	 */
+	node_type,
+	
+	/**
+	 * Whether to notify subscribers when the node configuration changes
+	 * 
+	 * <p><b>Value: boolean</b></p>
+	 */
+	notify_config,
+	
+	/**
+	 * Whether to notify subscribers when the node is deleted
+	 * 
+	 * <p><b>Value: boolean</b></p>
+	 */
+	notify_delete,
+
+	/**
+	 * Whether to notify subscribers when items are removed from the node
+	 * 
+	 * <p><b>Value: boolean</b></p>
+	 */
+	notify_retract,
+	
+	/**
+	 * Whether to persist items to storage.  This is required to have multiple 
+	 * items in the node. 
+	 * 
+	 * <p><b>Value: boolean</b></p>
+	 */
+	persist_items,
+	
+	/**
+	 * Whether to deliver notifications to available users only
+	 * 
+	 * <p><b>Value: boolean</b></p>
+	 */
+	presence_based_delivery,
+
+	/**
+	 * Defines who can publish to the node
+	 * 
+	 * <p><b>Value: {@link PublishModel}</b></p>
+	 */
+	publish_model,
+	
+	/**
+	 * The specific multi-user chat rooms to specify for replyroom
+	 * 
+	 * <p><b>Value: List of JIDs as Strings</b></p>
+	 */
+	replyroom,
+	
+	/**
+	 * The specific JID(s) to specify for replyto
+	 * 
+	 * <p><b>Value: List of JIDs as Strings</b></p>
+	 */
+	replyto,
+	
+	/**
+	 * The roster group(s) allowed to subscribe and retrieve items
+	 * 
+	 * <p><b>Value: List of strings</b></p>
+	 */
+	roster_groups_allowed,
+	
+	/**
+	 * Whether to allow subscriptions
+	 * 
+	 * <p><b>Value: boolean</b></p>
+	 */
+	subscribe,
+	
+	/**
+	 * A friendly name for the node
+	 * 
+	 * <p><b>Value: String</b></p>
+	 */
+	title,
+	
+	/**
+	 * The type of node data, ussually specified by the namespace 
+	 * of the payload(if any);MAY be a list-single rather than a 
+	 * text single
+	 * 
+	 * <p><b>Value: String</b></p>
+	 */
+	type;
+	
+	public String getFieldName()
+	{
+		return "pubsub#" + toString();
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/EmbeddedPacketExtension.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/EmbeddedPacketExtension.java
index b17a66a..a3b71e5 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/EmbeddedPacketExtension.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/EmbeddedPacketExtension.java
@@ -1,45 +1,45 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import java.util.List;
-
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.util.PacketParserUtils;
-
-/**
- * This interface defines {@link PacketExtension} implementations that contain other
- * extensions.  This effectively extends the idea of an extension within one of the 
- * top level {@link Packet} types to consider any embedded element to be an extension
- * of its parent.  This more easily enables the usage of some of Smacks parsing
- * utilities such as {@link PacketParserUtils#parsePacketExtension(String, String, org.xmlpull.v1.XmlPullParser)} to be used
- * to parse any element of the XML being parsed.
- * 
- * <p>Top level extensions have only one element, but they can have multiple children, or
- * their children can have multiple children.  This interface is a way of allowing extensions 
- * to be embedded within one another as a partial or complete one to one mapping of extension 
- * to element.
- * 
- * @author Robin Collier
- */
-public interface EmbeddedPacketExtension extends PacketExtension
-{
-	/**
-	 * Get the list of embedded {@link PacketExtension} objects.
-	 *  
-	 * @return List of embedded {@link PacketExtension}
-	 */
-	List<PacketExtension> getExtensions();
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import java.util.List;
+
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.util.PacketParserUtils;
+
+/**
+ * This interface defines {@link PacketExtension} implementations that contain other
+ * extensions.  This effectively extends the idea of an extension within one of the 
+ * top level {@link Packet} types to consider any embedded element to be an extension
+ * of its parent.  This more easily enables the usage of some of Smacks parsing
+ * utilities such as {@link PacketParserUtils#parsePacketExtension(String, String, org.xmlpull.v1.XmlPullParser)} to be used
+ * to parse any element of the XML being parsed.
+ * 
+ * <p>Top level extensions have only one element, but they can have multiple children, or
+ * their children can have multiple children.  This interface is a way of allowing extensions 
+ * to be embedded within one another as a partial or complete one to one mapping of extension 
+ * to element.
+ * 
+ * @author Robin Collier
+ */
+public interface EmbeddedPacketExtension extends PacketExtension
+{
+	/**
+	 * Get the list of embedded {@link PacketExtension} objects.
+	 *  
+	 * @return List of embedded {@link PacketExtension}
+	 */
+	List<PacketExtension> getExtensions();
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/EventElement.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/EventElement.java
index 165970f..e91b437 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/EventElement.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/EventElement.java
@@ -1,74 +1,74 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
-
-/**
- * Represents the top level element of a pubsub event extension.  All types of pubsub events are
- * represented by this class.  The specific type can be found by {@link #getEventType()}.  The 
- * embedded event information, which is specific to the event type, can be retrieved by the {@link #getEvent()}
- * method.
- * 
- * @author Robin Collier
- */
-public class EventElement implements EmbeddedPacketExtension
-{
-	private EventElementType type;
-	private NodeExtension ext;
-	
-	public EventElement(EventElementType eventType, NodeExtension eventExt)
-	{
-		type = eventType;
-		ext = eventExt;
-	}
-	
-	public EventElementType getEventType()
-	{
-		return type;
-	}
-
-	public List<PacketExtension> getExtensions()
-	{
-		return Arrays.asList(new PacketExtension[]{getEvent()});
-	}
-
-	public NodeExtension getEvent()
-	{
-		return ext;
-	}
-
-	public String getElementName()
-	{
-		return "event";
-	}
-
-	public String getNamespace()
-	{
-		return PubSubNamespace.EVENT.getXmlns();
-	}
-
-	public String toXML()
-	{
-		StringBuilder builder = new StringBuilder("<event xmlns='" + PubSubNamespace.EVENT.getXmlns() + "'>");
-
-		builder.append(ext.toXML());
-		builder.append("</event>");
-		return builder.toString();
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
+
+/**
+ * Represents the top level element of a pubsub event extension.  All types of pubsub events are
+ * represented by this class.  The specific type can be found by {@link #getEventType()}.  The 
+ * embedded event information, which is specific to the event type, can be retrieved by the {@link #getEvent()}
+ * method.
+ * 
+ * @author Robin Collier
+ */
+public class EventElement implements EmbeddedPacketExtension
+{
+	private EventElementType type;
+	private NodeExtension ext;
+	
+	public EventElement(EventElementType eventType, NodeExtension eventExt)
+	{
+		type = eventType;
+		ext = eventExt;
+	}
+	
+	public EventElementType getEventType()
+	{
+		return type;
+	}
+
+	public List<PacketExtension> getExtensions()
+	{
+		return Arrays.asList(new PacketExtension[]{getEvent()});
+	}
+
+	public NodeExtension getEvent()
+	{
+		return ext;
+	}
+
+	public String getElementName()
+	{
+		return "event";
+	}
+
+	public String getNamespace()
+	{
+		return PubSubNamespace.EVENT.getXmlns();
+	}
+
+	public String toXML()
+	{
+		StringBuilder builder = new StringBuilder("<event xmlns='" + PubSubNamespace.EVENT.getXmlns() + "'>");
+
+		builder.append(ext.toXML());
+		builder.append("</event>");
+		return builder.toString();
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/EventElementType.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/EventElementType.java
index 343edbe..038b979 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/EventElementType.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/EventElementType.java
@@ -1,41 +1,41 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-/**
- * This enumeration defines the possible event types that are supported within pubsub
- * event messages.
- * 
- * @author Robin Collier
- */
-public enum EventElementType
-{
-	/** A node has been associated or dissassociated with a collection node */
-	collection, 
-
-	/** A node has had its configuration changed */
-	configuration, 
-	
-	/** A node has been deleted */
-	delete, 
-	
-	/** Items have been published to a node */
-	items, 
-	
-	/** All items have been purged from a node */
-	purge, 
-	
-	/** A node has been subscribed to */
-	subscription
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+/**
+ * This enumeration defines the possible event types that are supported within pubsub
+ * event messages.
+ * 
+ * @author Robin Collier
+ */
+public enum EventElementType
+{
+	/** A node has been associated or dissassociated with a collection node */
+	collection, 
+
+	/** A node has had its configuration changed */
+	configuration, 
+	
+	/** A node has been deleted */
+	delete, 
+	
+	/** Items have been published to a node */
+	items, 
+	
+	/** All items have been purged from a node */
+	purge, 
+	
+	/** A node has been subscribed to */
+	subscription
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/FormNode.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/FormNode.java
index e08bed2..992c265 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/FormNode.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/FormNode.java
@@ -1,99 +1,99 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import org.jivesoftware.smackx.Form;
-
-/**
- * Generic packet extension which represents any pubsub form that is
- * parsed from the incoming stream or being sent out to the server.
- * 
- * Form types are defined in {@link FormNodeType}.
- * 
- * @author Robin Collier
- */
-public class FormNode extends NodeExtension
-{
-	private Form configForm;
-	
-	/**
-	 * Create a {@link FormNode} which contains the specified form.
-	 * 
-	 * @param formType The type of form being sent
-	 * @param submitForm The form
-	 */
-	public FormNode(FormNodeType formType, Form submitForm)
-	{
-		super(formType.getNodeElement());
-
-		if (submitForm == null)
-			throw new IllegalArgumentException("Submit form cannot be null");
-		configForm = submitForm;
-	}
-	
-	/**
-	 * Create a {@link FormNode} which contains the specified form, which is 
-	 * associated with the specified node.
-	 * 
-	 * @param formType The type of form being sent
-	 * @param nodeId The node the form is associated with
-	 * @param submitForm The form
-	 */
-	public FormNode(FormNodeType formType, String nodeId, Form submitForm)
-	{
-		super(formType.getNodeElement(), nodeId);
-
-		if (submitForm == null)
-			throw new IllegalArgumentException("Submit form cannot be null");
-		configForm = submitForm;
-	}
-	
-	/**
-	 * Get the Form that is to be sent, or was retrieved from the server.
-	 * 
-	 * @return The form
-	 */
-	public Form getForm()
-	{
-		return configForm;
-	}
-	
-	@Override
-	public String toXML()
-	{
-		if (configForm == null)
-		{
-			return super.toXML();
-		}
-		else
-		{
-			StringBuilder builder = new StringBuilder("<");
-			builder.append(getElementName());
-			
-			if (getNode() != null)
-			{
-				builder.append(" node='");
-				builder.append(getNode());
-				builder.append("'>");
-			}
-			else
-				builder.append('>');
-			builder.append(configForm.getDataFormToSend().toXML());
-			builder.append("</");
-			builder.append(getElementName() + '>');
-			return builder.toString();
-		}
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import org.jivesoftware.smackx.Form;
+
+/**
+ * Generic packet extension which represents any pubsub form that is
+ * parsed from the incoming stream or being sent out to the server.
+ * 
+ * Form types are defined in {@link FormNodeType}.
+ * 
+ * @author Robin Collier
+ */
+public class FormNode extends NodeExtension
+{
+	private Form configForm;
+	
+	/**
+	 * Create a {@link FormNode} which contains the specified form.
+	 * 
+	 * @param formType The type of form being sent
+	 * @param submitForm The form
+	 */
+	public FormNode(FormNodeType formType, Form submitForm)
+	{
+		super(formType.getNodeElement());
+
+		if (submitForm == null)
+			throw new IllegalArgumentException("Submit form cannot be null");
+		configForm = submitForm;
+	}
+	
+	/**
+	 * Create a {@link FormNode} which contains the specified form, which is 
+	 * associated with the specified node.
+	 * 
+	 * @param formType The type of form being sent
+	 * @param nodeId The node the form is associated with
+	 * @param submitForm The form
+	 */
+	public FormNode(FormNodeType formType, String nodeId, Form submitForm)
+	{
+		super(formType.getNodeElement(), nodeId);
+
+		if (submitForm == null)
+			throw new IllegalArgumentException("Submit form cannot be null");
+		configForm = submitForm;
+	}
+	
+	/**
+	 * Get the Form that is to be sent, or was retrieved from the server.
+	 * 
+	 * @return The form
+	 */
+	public Form getForm()
+	{
+		return configForm;
+	}
+	
+	@Override
+	public String toXML()
+	{
+		if (configForm == null)
+		{
+			return super.toXML();
+		}
+		else
+		{
+			StringBuilder builder = new StringBuilder("<");
+			builder.append(getElementName());
+			
+			if (getNode() != null)
+			{
+				builder.append(" node='");
+				builder.append(getNode());
+				builder.append("'>");
+			}
+			else
+				builder.append('>');
+			builder.append(configForm.getDataFormToSend().toXML());
+			builder.append("</");
+			builder.append(getElementName() + '>');
+			return builder.toString();
+		}
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/FormNodeType.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/FormNodeType.java
index 6a163ee..48a600a 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/FormNodeType.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/FormNodeType.java
@@ -1,50 +1,50 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
-
-/**
- * The types of forms supported by the pubsub specification.
- * 
- * @author Robin Collier
- */
-public enum FormNodeType
-{
-	/** Form for configuring an existing node */
-	CONFIGURE_OWNER,
-	
-	/** Form for configuring a node during creation */
-	CONFIGURE,
-	
-	/** Form for configuring subscription options */
-	OPTIONS,
-
-	/** Form which represents the default node configuration options */
-	DEFAULT;
-	
-	public PubSubElementType getNodeElement()
-	{
-		return PubSubElementType.valueOf(toString());
-	}
-
-	public static FormNodeType valueOfFromElementName(String elem, String configNamespace)
-	{
-		if ("configure".equals(elem) && PubSubNamespace.OWNER.getXmlns().equals(configNamespace))
-		{
-			return CONFIGURE_OWNER;
-		}
-		return valueOf(elem.toUpperCase());
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
+
+/**
+ * The types of forms supported by the pubsub specification.
+ * 
+ * @author Robin Collier
+ */
+public enum FormNodeType
+{
+	/** Form for configuring an existing node */
+	CONFIGURE_OWNER,
+	
+	/** Form for configuring a node during creation */
+	CONFIGURE,
+	
+	/** Form for configuring subscription options */
+	OPTIONS,
+
+	/** Form which represents the default node configuration options */
+	DEFAULT;
+	
+	public PubSubElementType getNodeElement()
+	{
+		return PubSubElementType.valueOf(toString());
+	}
+
+	public static FormNodeType valueOfFromElementName(String elem, String configNamespace)
+	{
+		if ("configure".equals(elem) && PubSubNamespace.OWNER.getXmlns().equals(configNamespace))
+		{
+			return CONFIGURE_OWNER;
+		}
+		return valueOf(elem.toUpperCase());
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/FormType.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/FormType.java
index e0fff51..f4df255 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/FormType.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/FormType.java
@@ -1,26 +1,26 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import org.jivesoftware.smackx.Form;
-
-/**
- * Defines the allowable types for a {@link Form}
- * 
- * @author Robin Collier
- */
-public enum FormType
-{
-    form, submit, cancel, result;
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import org.jivesoftware.smackx.Form;
+
+/**
+ * Defines the allowable types for a {@link Form}
+ * 
+ * @author Robin Collier
+ */
+public enum FormType
+{
+    form, submit, cancel, result;
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/GetItemsRequest.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/GetItemsRequest.java
index 0935571..341b7b5 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/GetItemsRequest.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/GetItemsRequest.java
@@ -1,85 +1,85 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-/**
- * Represents a request to subscribe to a node.
- * 
- * @author Robin Collier
- */
-public class GetItemsRequest extends NodeExtension
-{
-	protected String subId;
-	protected int maxItems;
-	
-	public GetItemsRequest(String nodeId)
-	{
-		super(PubSubElementType.ITEMS, nodeId);
-	}
-	
-	public GetItemsRequest(String nodeId, String subscriptionId)
-	{
-		super(PubSubElementType.ITEMS, nodeId);
-		subId = subscriptionId;
-	}
-
-	public GetItemsRequest(String nodeId, int maxItemsToReturn)
-	{
-		super(PubSubElementType.ITEMS, nodeId);
-		maxItems = maxItemsToReturn;
-	}
-
-	public GetItemsRequest(String nodeId, String subscriptionId, int maxItemsToReturn)
-	{
-		this(nodeId, maxItemsToReturn);
-		subId = subscriptionId;
-	}
-
-	public String getSubscriptionId()
-	{
-		return subId;
-	}
-
-	public int getMaxItems()
-	{
-		return maxItems;
-	}
-
-	@Override
-	public String toXML()
-	{
-		StringBuilder builder = new StringBuilder("<");
-		builder.append(getElementName());
-		
-		builder.append(" node='");
-		builder.append(getNode());
-		builder.append("'");
-
-		if (getSubscriptionId() != null)
-		{
-			builder.append(" subid='");
-			builder.append(getSubscriptionId());
-			builder.append("'");
-		}
-
-		if (getMaxItems() > 0)
-		{
-			builder.append(" max_items='");
-			builder.append(getMaxItems());
-			builder.append("'");
-		}
-		builder.append("/>");
-		return builder.toString();
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+/**
+ * Represents a request to subscribe to a node.
+ * 
+ * @author Robin Collier
+ */
+public class GetItemsRequest extends NodeExtension
+{
+	protected String subId;
+	protected int maxItems;
+	
+	public GetItemsRequest(String nodeId)
+	{
+		super(PubSubElementType.ITEMS, nodeId);
+	}
+	
+	public GetItemsRequest(String nodeId, String subscriptionId)
+	{
+		super(PubSubElementType.ITEMS, nodeId);
+		subId = subscriptionId;
+	}
+
+	public GetItemsRequest(String nodeId, int maxItemsToReturn)
+	{
+		super(PubSubElementType.ITEMS, nodeId);
+		maxItems = maxItemsToReturn;
+	}
+
+	public GetItemsRequest(String nodeId, String subscriptionId, int maxItemsToReturn)
+	{
+		this(nodeId, maxItemsToReturn);
+		subId = subscriptionId;
+	}
+
+	public String getSubscriptionId()
+	{
+		return subId;
+	}
+
+	public int getMaxItems()
+	{
+		return maxItems;
+	}
+
+	@Override
+	public String toXML()
+	{
+		StringBuilder builder = new StringBuilder("<");
+		builder.append(getElementName());
+		
+		builder.append(" node='");
+		builder.append(getNode());
+		builder.append("'");
+
+		if (getSubscriptionId() != null)
+		{
+			builder.append(" subid='");
+			builder.append(getSubscriptionId());
+			builder.append("'");
+		}
+
+		if (getMaxItems() > 0)
+		{
+			builder.append(" max_items='");
+			builder.append(getMaxItems());
+			builder.append("'");
+		}
+		builder.append("/>");
+		return builder.toString();
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/Item.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/Item.java
index 2ce0baa..8e897c7 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/Item.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/Item.java
@@ -1,132 +1,132 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import org.jivesoftware.smack.packet.Message;
-import org.jivesoftware.smackx.pubsub.provider.ItemProvider;
-
-/**
- * This class represents an item that has been, or will be published to a
- * pubsub node.  An <tt>Item</tt> has several properties that are dependent
- * on the configuration of the node to which it has been or will be published.
- * 
- * <h1>An Item received from a node (via {@link LeafNode#getItems()} or {@link LeafNode#addItemEventListener(org.jivesoftware.smackx.pubsub.listener.ItemEventListener)}</b>
- * <li>Will always have an id (either user or server generated) unless node configuration has both
- * {@link ConfigureForm#isPersistItems()} and {@link ConfigureForm#isDeliverPayloads()}set to false.
- * <li>Will have a payload if the node configuration has {@link ConfigureForm#isDeliverPayloads()} set 
- * to true, otherwise it will be null.
- * 
- * <h1>An Item created to send to a node (via {@link LeafNode#send()} or {@link LeafNode#publish()}</b>
- * <li>The id is optional, since the server will generate one if necessary, but should be used if it is 
- * meaningful in the context of the node.  This value must be unique within the node that it is sent to, since
- * resending an item with the same id will overwrite the one that already exists if the items are persisted.
- * <li>Will require payload if the node configuration has {@link ConfigureForm#isDeliverPayloads()} set
- * to true. 
- * 
- * <p>To customise the payload object being returned from the {@link #getPayload()} method, you can
- * add a custom parser as explained in {@link ItemProvider}.
- * 
- * @author Robin Collier
- */
-public class Item extends NodeExtension
-{
-	private String id;
-	
-	/**
-	 * Create an empty <tt>Item</tt> with no id.  This is a valid item for nodes which are configured
-	 * so that {@link ConfigureForm#isDeliverPayloads()} is false.  In most cases an id will be generated by the server.
-	 * For nodes configured with {@link ConfigureForm#isDeliverPayloads()} and {@link ConfigureForm#isPersistItems()} 
-	 * set to false, no <tt>Item</tt> is sent to the node, you have to use {@link LeafNode#send()} or {@link LeafNode#publish()}
-	 * methods in this case. 
-	 */
-	public Item()
-	{
-		super(PubSubElementType.ITEM);
-	}
-	
-	/**
-	 * Create an <tt>Item</tt> with an id but no payload.  This is a valid item for nodes which are configured
-	 * so that {@link ConfigureForm#isDeliverPayloads()} is false.
-	 * 
-	 * @param itemId The id if the item.  It must be unique within the node unless overwriting and existing item.
-	 * Passing null is the equivalent of calling {@link #Item()}.
-	 */
-	public Item(String itemId)
-	{
-		// The element type is actually irrelevant since we override getNamespace() to return null
-		super(PubSubElementType.ITEM);
-		id = itemId;
-	}
-
-	/**
-	 * Create an <tt>Item</tt> with an id and a node id.  
-	 * <p>
-	 * <b>Note:</b> This is not valid for publishing an item to a node, only receiving from 
-	 * one as part of {@link Message}.  If used to create an Item to publish 
-	 * (via {@link LeafNode#publish(Item)}, the server <i>may</i> return an
-	 * error for an invalid packet.
-	 * 
-	 * @param itemId The id of the item.
-	 * @param nodeId The id of the node which the item was published to.
-	 */
-    public Item(String itemId, String nodeId) 
-    {
-    	super(PubSubElementType.ITEM_EVENT, nodeId);
-        id = itemId;
-    }
-	
-	/**
-	 * Get the item id.  Unique to the node it is associated with.
-	 * 
-	 * @return The id
-	 */
-	public String getId()
-	{
-		return id;
-	}
-	
-	@Override
-	public String getNamespace()
-	{
-		return null;
-	}
-
-	@Override
-	public String toXML()
-	{
-		StringBuilder builder = new StringBuilder("<item");
-		
-		if (id != null)
-		{
-			builder.append(" id='");
-			builder.append(id);
-			builder.append("'");
-		}
-		
-        if (getNode() != null) {
-            builder.append(" node='");
-            builder.append(getNode());
-            builder.append("'");
-        }
-		builder.append("/>");
-
-		return builder.toString();
-	}
-
-	@Override
-	public String toString()
-	{
-		return getClass().getName() + " | Content [" + toXML() + "]";
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import org.jivesoftware.smack.packet.Message;
+import org.jivesoftware.smackx.pubsub.provider.ItemProvider;
+
+/**
+ * This class represents an item that has been, or will be published to a
+ * pubsub node.  An <tt>Item</tt> has several properties that are dependent
+ * on the configuration of the node to which it has been or will be published.
+ * 
+ * <h1>An Item received from a node (via {@link LeafNode#getItems()} or {@link LeafNode#addItemEventListener(org.jivesoftware.smackx.pubsub.listener.ItemEventListener)}</b>
+ * <li>Will always have an id (either user or server generated) unless node configuration has both
+ * {@link ConfigureForm#isPersistItems()} and {@link ConfigureForm#isDeliverPayloads()}set to false.
+ * <li>Will have a payload if the node configuration has {@link ConfigureForm#isDeliverPayloads()} set 
+ * to true, otherwise it will be null.
+ * 
+ * <h1>An Item created to send to a node (via {@link LeafNode#send()} or {@link LeafNode#publish()}</b>
+ * <li>The id is optional, since the server will generate one if necessary, but should be used if it is 
+ * meaningful in the context of the node.  This value must be unique within the node that it is sent to, since
+ * resending an item with the same id will overwrite the one that already exists if the items are persisted.
+ * <li>Will require payload if the node configuration has {@link ConfigureForm#isDeliverPayloads()} set
+ * to true. 
+ * 
+ * <p>To customise the payload object being returned from the {@link #getPayload()} method, you can
+ * add a custom parser as explained in {@link ItemProvider}.
+ * 
+ * @author Robin Collier
+ */
+public class Item extends NodeExtension
+{
+	private String id;
+	
+	/**
+	 * Create an empty <tt>Item</tt> with no id.  This is a valid item for nodes which are configured
+	 * so that {@link ConfigureForm#isDeliverPayloads()} is false.  In most cases an id will be generated by the server.
+	 * For nodes configured with {@link ConfigureForm#isDeliverPayloads()} and {@link ConfigureForm#isPersistItems()} 
+	 * set to false, no <tt>Item</tt> is sent to the node, you have to use {@link LeafNode#send()} or {@link LeafNode#publish()}
+	 * methods in this case. 
+	 */
+	public Item()
+	{
+		super(PubSubElementType.ITEM);
+	}
+	
+	/**
+	 * Create an <tt>Item</tt> with an id but no payload.  This is a valid item for nodes which are configured
+	 * so that {@link ConfigureForm#isDeliverPayloads()} is false.
+	 * 
+	 * @param itemId The id if the item.  It must be unique within the node unless overwriting and existing item.
+	 * Passing null is the equivalent of calling {@link #Item()}.
+	 */
+	public Item(String itemId)
+	{
+		// The element type is actually irrelevant since we override getNamespace() to return null
+		super(PubSubElementType.ITEM);
+		id = itemId;
+	}
+
+	/**
+	 * Create an <tt>Item</tt> with an id and a node id.  
+	 * <p>
+	 * <b>Note:</b> This is not valid for publishing an item to a node, only receiving from 
+	 * one as part of {@link Message}.  If used to create an Item to publish 
+	 * (via {@link LeafNode#publish(Item)}, the server <i>may</i> return an
+	 * error for an invalid packet.
+	 * 
+	 * @param itemId The id of the item.
+	 * @param nodeId The id of the node which the item was published to.
+	 */
+    public Item(String itemId, String nodeId) 
+    {
+    	super(PubSubElementType.ITEM_EVENT, nodeId);
+        id = itemId;
+    }
+	
+	/**
+	 * Get the item id.  Unique to the node it is associated with.
+	 * 
+	 * @return The id
+	 */
+	public String getId()
+	{
+		return id;
+	}
+	
+	@Override
+	public String getNamespace()
+	{
+		return null;
+	}
+
+	@Override
+	public String toXML()
+	{
+		StringBuilder builder = new StringBuilder("<item");
+		
+		if (id != null)
+		{
+			builder.append(" id='");
+			builder.append(id);
+			builder.append("'");
+		}
+		
+        if (getNode() != null) {
+            builder.append(" node='");
+            builder.append(getNode());
+            builder.append("'");
+        }
+		builder.append("/>");
+
+		return builder.toString();
+	}
+
+	@Override
+	public String toString()
+	{
+		return getClass().getName() + " | Content [" + toXML() + "]";
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ItemDeleteEvent.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ItemDeleteEvent.java
index 82ab7df..b26dd6f 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ItemDeleteEvent.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ItemDeleteEvent.java
@@ -1,62 +1,62 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Represents an event in which items have been deleted from the node.
- * 
- * @author Robin Collier
- */
-public class ItemDeleteEvent extends SubscriptionEvent
-{
-	private List<String> itemIds = Collections.EMPTY_LIST;
-	
-	/**
-	 * Constructs an <tt>ItemDeleteEvent</tt> that indicates the the supplied
-	 * items (by id) have been deleted, and that the event matches the listed
-	 * subscriptions.  The subscriptions would have been created by calling 
-	 * {@link LeafNode#subscribe(String)}.
-	 * 
-	 * @param nodeId The id of the node the event came from
-	 * @param deletedItemIds The item ids of the items that were deleted.
-	 * @param subscriptionIds The subscriptions that match the event.
-	 */
-	public ItemDeleteEvent(String nodeId, List<String> deletedItemIds, List<String> subscriptionIds)
-	{
-		super(nodeId, subscriptionIds);
-		
-		if (deletedItemIds == null)
-			throw new IllegalArgumentException("deletedItemIds cannot be null");
-		itemIds = deletedItemIds;
-	}
-	
-	/**
-	 * Get the item id's of the items that have been deleted.
-	 * 
-	 * @return List of item id's
-	 */
-	public List<String> getItemIds()
-	{
-		return Collections.unmodifiableList(itemIds);
-	}
-	
-	@Override
-	public String toString()
-	{
-		return getClass().getName() + "  [subscriptions: " + getSubscriptions() + "], [Deleted Items: " + itemIds + ']';
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Represents an event in which items have been deleted from the node.
+ * 
+ * @author Robin Collier
+ */
+public class ItemDeleteEvent extends SubscriptionEvent
+{
+	private List<String> itemIds = Collections.EMPTY_LIST;
+	
+	/**
+	 * Constructs an <tt>ItemDeleteEvent</tt> that indicates the the supplied
+	 * items (by id) have been deleted, and that the event matches the listed
+	 * subscriptions.  The subscriptions would have been created by calling 
+	 * {@link LeafNode#subscribe(String)}.
+	 * 
+	 * @param nodeId The id of the node the event came from
+	 * @param deletedItemIds The item ids of the items that were deleted.
+	 * @param subscriptionIds The subscriptions that match the event.
+	 */
+	public ItemDeleteEvent(String nodeId, List<String> deletedItemIds, List<String> subscriptionIds)
+	{
+		super(nodeId, subscriptionIds);
+		
+		if (deletedItemIds == null)
+			throw new IllegalArgumentException("deletedItemIds cannot be null");
+		itemIds = deletedItemIds;
+	}
+	
+	/**
+	 * Get the item id's of the items that have been deleted.
+	 * 
+	 * @return List of item id's
+	 */
+	public List<String> getItemIds()
+	{
+		return Collections.unmodifiableList(itemIds);
+	}
+	
+	@Override
+	public String toString()
+	{
+		return getClass().getName() + "  [subscriptions: " + getSubscriptions() + "], [Deleted Items: " + itemIds + ']';
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ItemPublishEvent.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ItemPublishEvent.java
index 1ef1f67..7c0574c 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ItemPublishEvent.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ItemPublishEvent.java
@@ -1,123 +1,123 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-
-/**
- * Represents an event generated by an item(s) being published to a node.
- * 
- * @author Robin Collier
- */
-public class ItemPublishEvent <T extends Item> extends SubscriptionEvent
-{
-	private List<T> items;
-	private Date originalDate;
-	
-	/**
-	 * Constructs an <tt>ItemPublishEvent</tt> with the provided list
-	 * of {@link Item} that were published.
-	 * 
-	 * @param nodeId The id of the node the event came from
-	 * @param eventItems The list of {@link Item} that were published 
-	 */
-	public ItemPublishEvent(String nodeId, List<T> eventItems)
-	{
-		super(nodeId);
-		items = eventItems;
-	}
-	
-	/**
-	 * Constructs an <tt>ItemPublishEvent</tt> with the provided list
-	 * of {@link Item} that were published.  The list of subscription ids
-	 * represents the subscriptions that matched the event, in the case 
-	 * of the user having multiple subscriptions.
-	 * 
-	 * @param nodeId The id of the node the event came from
-	 * @param eventItems The list of {@link Item} that were published 
-	 * @param subscriptionIds The list of subscriptionIds
-	 */
-	public ItemPublishEvent(String nodeId, List<T> eventItems, List<String> subscriptionIds)
-	{
-		super(nodeId, subscriptionIds);
-		items = eventItems;
-	}
-	
-	/**
-	 * Constructs an <tt>ItemPublishEvent</tt> with the provided list
-	 * of {@link Item} that were published in the past.  The published
-	 * date signifies that this is delayed event.  The list of subscription ids
-	 * represents the subscriptions that matched the event, in the case 
-	 * of the user having multiple subscriptions. 
-	 *
-	 * @param nodeId The id of the node the event came from
-	 * @param eventItems The list of {@link Item} that were published 
-	 * @param subscriptionIds The list of subscriptionIds
-	 * @param publishedDate The original publishing date of the events
-	 */
-	public ItemPublishEvent(String nodeId, List<T> eventItems, List<String> subscriptionIds, Date publishedDate)
-	{
-		super(nodeId, subscriptionIds);
-		items = eventItems;
-		
-		if (publishedDate != null)
-			originalDate = publishedDate;
-	}
-	
-	/**
-	 * Get the list of {@link Item} that were published.
-	 * 
-	 * @return The list of published {@link Item}
-	 */
-	public List<T> getItems()
-	{
-		return Collections.unmodifiableList(items);
-	}
-	
-	/**
-	 * Indicates whether this event was delayed.  That is, the items
-	 * were published to the node at some time in the past.  This will 
-	 * typically happen if there is an item already published to the node
-	 * before a user subscribes to it.  In this case, when the user 
-	 * subscribes, the server may send the last item published to the node
-	 * with a delay date showing its time of original publication.
-	 * 
-	 * @return true if the items are delayed, false otherwise.
-	 */
-	public boolean isDelayed()
-	{
-		return (originalDate != null);
-	}
-	
-	/**
-	 * Gets the original date the items were published.  This is only 
-	 * valid if {@link #isDelayed()} is true.
-	 * 
-	 * @return Date items were published if {@link #isDelayed()} is true, null otherwise.
-	 */
-	public Date getPublishedDate()
-	{
-		return originalDate;
-	}
-
-	@Override
-	public String toString()
-	{
-		return getClass().getName() + "  [subscriptions: " + getSubscriptions() + "], [Delayed: " + 
-			(isDelayed() ? originalDate.toString() : "false") + ']';
-	}
-	
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Represents an event generated by an item(s) being published to a node.
+ * 
+ * @author Robin Collier
+ */
+public class ItemPublishEvent <T extends Item> extends SubscriptionEvent
+{
+	private List<T> items;
+	private Date originalDate;
+	
+	/**
+	 * Constructs an <tt>ItemPublishEvent</tt> with the provided list
+	 * of {@link Item} that were published.
+	 * 
+	 * @param nodeId The id of the node the event came from
+	 * @param eventItems The list of {@link Item} that were published 
+	 */
+	public ItemPublishEvent(String nodeId, List<T> eventItems)
+	{
+		super(nodeId);
+		items = eventItems;
+	}
+	
+	/**
+	 * Constructs an <tt>ItemPublishEvent</tt> with the provided list
+	 * of {@link Item} that were published.  The list of subscription ids
+	 * represents the subscriptions that matched the event, in the case 
+	 * of the user having multiple subscriptions.
+	 * 
+	 * @param nodeId The id of the node the event came from
+	 * @param eventItems The list of {@link Item} that were published 
+	 * @param subscriptionIds The list of subscriptionIds
+	 */
+	public ItemPublishEvent(String nodeId, List<T> eventItems, List<String> subscriptionIds)
+	{
+		super(nodeId, subscriptionIds);
+		items = eventItems;
+	}
+	
+	/**
+	 * Constructs an <tt>ItemPublishEvent</tt> with the provided list
+	 * of {@link Item} that were published in the past.  The published
+	 * date signifies that this is delayed event.  The list of subscription ids
+	 * represents the subscriptions that matched the event, in the case 
+	 * of the user having multiple subscriptions. 
+	 *
+	 * @param nodeId The id of the node the event came from
+	 * @param eventItems The list of {@link Item} that were published 
+	 * @param subscriptionIds The list of subscriptionIds
+	 * @param publishedDate The original publishing date of the events
+	 */
+	public ItemPublishEvent(String nodeId, List<T> eventItems, List<String> subscriptionIds, Date publishedDate)
+	{
+		super(nodeId, subscriptionIds);
+		items = eventItems;
+		
+		if (publishedDate != null)
+			originalDate = publishedDate;
+	}
+	
+	/**
+	 * Get the list of {@link Item} that were published.
+	 * 
+	 * @return The list of published {@link Item}
+	 */
+	public List<T> getItems()
+	{
+		return Collections.unmodifiableList(items);
+	}
+	
+	/**
+	 * Indicates whether this event was delayed.  That is, the items
+	 * were published to the node at some time in the past.  This will 
+	 * typically happen if there is an item already published to the node
+	 * before a user subscribes to it.  In this case, when the user 
+	 * subscribes, the server may send the last item published to the node
+	 * with a delay date showing its time of original publication.
+	 * 
+	 * @return true if the items are delayed, false otherwise.
+	 */
+	public boolean isDelayed()
+	{
+		return (originalDate != null);
+	}
+	
+	/**
+	 * Gets the original date the items were published.  This is only 
+	 * valid if {@link #isDelayed()} is true.
+	 * 
+	 * @return Date items were published if {@link #isDelayed()} is true, null otherwise.
+	 */
+	public Date getPublishedDate()
+	{
+		return originalDate;
+	}
+
+	@Override
+	public String toString()
+	{
+		return getClass().getName() + "  [subscriptions: " + getSubscriptions() + "], [Delayed: " + 
+			(isDelayed() ? originalDate.toString() : "false") + ']';
+	}
+	
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ItemReply.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ItemReply.java
index 3e090d9..99a0827 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ItemReply.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ItemReply.java
@@ -1,29 +1,29 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-/**
- * These are the options for the node configuration setting {@link ConfigureForm#setItemReply(ItemReply)},
- * which defines who should receive replies to items.
- * 
- * @author Robin Collier
- */
-public enum ItemReply
-{
-	/** The node owner */
-	owner,
-	
-	/** The item publisher */
-	publisher;
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+/**
+ * These are the options for the node configuration setting {@link ConfigureForm#setItemReply(ItemReply)},
+ * which defines who should receive replies to items.
+ * 
+ * @author Robin Collier
+ */
+public enum ItemReply
+{
+	/** The node owner */
+	owner,
+	
+	/** The item publisher */
+	publisher;
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ItemsExtension.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ItemsExtension.java
index c98d93a..855ed06 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ItemsExtension.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/ItemsExtension.java
@@ -1,196 +1,196 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import java.util.List;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-
-/**
- * This class is used to for multiple purposes.  
- * <li>It can represent an event containing a list of items that have been published
- * <li>It can represent an event containing a list of retracted (deleted) items.
- * <li>It can represent a request to delete a list of items.
- * <li>It can represent a request to get existing items.
- * 
- * <p><b>Please note, this class is used for internal purposes, and is not required for usage of 
- * pubsub functionality.</b>
- * 
- * @author Robin Collier
- */
-public class ItemsExtension extends NodeExtension implements EmbeddedPacketExtension
-{
-	protected ItemsElementType type;
-	protected Boolean notify;
-	protected List<? extends PacketExtension> items;
-
-	public enum ItemsElementType
-	{
-		/** An items element, which has an optional <b>max_items</b> attribute when requesting items */
-		items(PubSubElementType.ITEMS, "max_items"),
-		
-		/** A retract element, which has an optional <b>notify</b> attribute when publishing deletions */
-		retract(PubSubElementType.RETRACT, "notify");
-		
-		private PubSubElementType elem;
-		private String att;
-		
-		private ItemsElementType(PubSubElementType nodeElement, String attribute)
-		{
-			elem = nodeElement;
-			att = attribute;
-		}
-		
-		public PubSubElementType getNodeElement()
-		{
-			return elem;
-		}
-
-		public String getElementAttribute()
-		{
-			return att;
-		}
-	}
-
-	/**
-	 * Construct an instance with a list representing items that have been published or deleted.
-	 * 
-	 * <p>Valid scenarios are:
-	 * <li>Request items from node - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and an
-	 * optional value for the <b>max_items</b> attribute.
-	 * <li>Request to delete items - itemsType = {@link ItemsElementType#retract}, items = list of {@link Item} containing
-	 * only id's and an optional value for the <b>notify</b> attribute.
-	 * <li>Items published event - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and 
-	 * attributeValue = <code>null</code>
-	 * <li>Items deleted event -  itemsType = {@link ItemsElementType#items}, items = list of {@link RetractItem} and 
-	 * attributeValue = <code>null</code> 
-	 * 
-	 * @param itemsType Type of representation
-	 * @param nodeId The node to which the items are being sent or deleted
-	 * @param items The list of {@link Item} or {@link RetractItem}
-	 * @param attributeValue The value of the <b>max_items</b>  
-	 */
-	public ItemsExtension(ItemsElementType itemsType, String nodeId, List<? extends PacketExtension> items)
-	{
-		super(itemsType.getNodeElement(), nodeId);
-		type = itemsType;
-		this.items = items;
-	}
-	
-	/**
-	 * Construct an instance with a list representing items that have been published or deleted.
-	 * 
-	 * <p>Valid scenarios are:
-	 * <li>Request items from node - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and an
-	 * optional value for the <b>max_items</b> attribute.
-	 * <li>Request to delete items - itemsType = {@link ItemsElementType#retract}, items = list of {@link Item} containing
-	 * only id's and an optional value for the <b>notify</b> attribute.
-	 * <li>Items published event - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and 
-	 * attributeValue = <code>null</code>
-	 * <li>Items deleted event -  itemsType = {@link ItemsElementType#items}, items = list of {@link RetractItem} and 
-	 * attributeValue = <code>null</code> 
-	 * 
-	 * @param itemsType Type of representation
-	 * @param nodeId The node to which the items are being sent or deleted
-	 * @param items The list of {@link Item} or {@link RetractItem}
-	 * @param attributeValue The value of the <b>max_items</b>  
-	 */
-	public ItemsExtension(String nodeId, List<? extends PacketExtension> items, boolean notify)
-	{
-		super(ItemsElementType.retract.getNodeElement(), nodeId);
-		type = ItemsElementType.retract;
-		this.items = items; 
-		this.notify = notify;
-	}
-	
-	/**
-	 * Get the type of element
-	 * 
-	 * @return The element type
-	 */
-	public ItemsElementType getItemsElementType()
-	{
-		return type;
-	}
-	
-	public List<PacketExtension> getExtensions()
-	{
-		return (List<PacketExtension>)getItems();
-	}
-	
-	/**
-	 * Gets the items related to the type of request or event.
-	 * 
-	 * return List of {@link Item}, {@link RetractItem}, or null
-	 */
-	public List<? extends PacketExtension> getItems()
-	{
-		return items;
-	}
-
-	/**
-	 * Gets the value of the optional attribute related to the {@link ItemsElementType}.
-	 * 
-	 * @return The attribute value
-	 */
-	public boolean getNotify()
-	{
-		return notify;
-	}
-	
-	@Override
-	public String toXML()
-	{
-		if ((items == null) || (items.size() == 0))
-		{
-			return super.toXML();
-		}
-		else
-		{
-			StringBuilder builder = new StringBuilder("<");
-			builder.append(getElementName());
-			builder.append(" node='");
-			builder.append(getNode());
-			
-			if (notify != null)
-			{
-				builder.append("' ");
-				builder.append(type.getElementAttribute());
-				builder.append("='");
-				builder.append(notify.equals(Boolean.TRUE) ? 1 : 0);
-				builder.append("'>");
-			}
-			else
-			{
-				builder.append("'>");
-				for (PacketExtension item : items)
-				{
-					builder.append(item.toXML());
-				}
-			}
-			
-			builder.append("</");
-			builder.append(getElementName());
-			builder.append(">");
-			return builder.toString();
-		}
-	}
-
-	@Override
-	public String toString()
-	{
-		return getClass().getName() + "Content [" + toXML() + "]";
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import java.util.List;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+
+/**
+ * This class is used to for multiple purposes.  
+ * <li>It can represent an event containing a list of items that have been published
+ * <li>It can represent an event containing a list of retracted (deleted) items.
+ * <li>It can represent a request to delete a list of items.
+ * <li>It can represent a request to get existing items.
+ * 
+ * <p><b>Please note, this class is used for internal purposes, and is not required for usage of 
+ * pubsub functionality.</b>
+ * 
+ * @author Robin Collier
+ */
+public class ItemsExtension extends NodeExtension implements EmbeddedPacketExtension
+{
+	protected ItemsElementType type;
+	protected Boolean notify;
+	protected List<? extends PacketExtension> items;
+
+	public enum ItemsElementType
+	{
+		/** An items element, which has an optional <b>max_items</b> attribute when requesting items */
+		items(PubSubElementType.ITEMS, "max_items"),
+		
+		/** A retract element, which has an optional <b>notify</b> attribute when publishing deletions */
+		retract(PubSubElementType.RETRACT, "notify");
+		
+		private PubSubElementType elem;
+		private String att;
+		
+		private ItemsElementType(PubSubElementType nodeElement, String attribute)
+		{
+			elem = nodeElement;
+			att = attribute;
+		}
+		
+		public PubSubElementType getNodeElement()
+		{
+			return elem;
+		}
+
+		public String getElementAttribute()
+		{
+			return att;
+		}
+	}
+
+	/**
+	 * Construct an instance with a list representing items that have been published or deleted.
+	 * 
+	 * <p>Valid scenarios are:
+	 * <li>Request items from node - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and an
+	 * optional value for the <b>max_items</b> attribute.
+	 * <li>Request to delete items - itemsType = {@link ItemsElementType#retract}, items = list of {@link Item} containing
+	 * only id's and an optional value for the <b>notify</b> attribute.
+	 * <li>Items published event - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and 
+	 * attributeValue = <code>null</code>
+	 * <li>Items deleted event -  itemsType = {@link ItemsElementType#items}, items = list of {@link RetractItem} and 
+	 * attributeValue = <code>null</code> 
+	 * 
+	 * @param itemsType Type of representation
+	 * @param nodeId The node to which the items are being sent or deleted
+	 * @param items The list of {@link Item} or {@link RetractItem}
+	 * @param attributeValue The value of the <b>max_items</b>  
+	 */
+	public ItemsExtension(ItemsElementType itemsType, String nodeId, List<? extends PacketExtension> items)
+	{
+		super(itemsType.getNodeElement(), nodeId);
+		type = itemsType;
+		this.items = items;
+	}
+	
+	/**
+	 * Construct an instance with a list representing items that have been published or deleted.
+	 * 
+	 * <p>Valid scenarios are:
+	 * <li>Request items from node - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and an
+	 * optional value for the <b>max_items</b> attribute.
+	 * <li>Request to delete items - itemsType = {@link ItemsElementType#retract}, items = list of {@link Item} containing
+	 * only id's and an optional value for the <b>notify</b> attribute.
+	 * <li>Items published event - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and 
+	 * attributeValue = <code>null</code>
+	 * <li>Items deleted event -  itemsType = {@link ItemsElementType#items}, items = list of {@link RetractItem} and 
+	 * attributeValue = <code>null</code> 
+	 * 
+	 * @param itemsType Type of representation
+	 * @param nodeId The node to which the items are being sent or deleted
+	 * @param items The list of {@link Item} or {@link RetractItem}
+	 * @param attributeValue The value of the <b>max_items</b>  
+	 */
+	public ItemsExtension(String nodeId, List<? extends PacketExtension> items, boolean notify)
+	{
+		super(ItemsElementType.retract.getNodeElement(), nodeId);
+		type = ItemsElementType.retract;
+		this.items = items; 
+		this.notify = notify;
+	}
+	
+	/**
+	 * Get the type of element
+	 * 
+	 * @return The element type
+	 */
+	public ItemsElementType getItemsElementType()
+	{
+		return type;
+	}
+	
+	public List<PacketExtension> getExtensions()
+	{
+		return (List<PacketExtension>)getItems();
+	}
+	
+	/**
+	 * Gets the items related to the type of request or event.
+	 * 
+	 * return List of {@link Item}, {@link RetractItem}, or null
+	 */
+	public List<? extends PacketExtension> getItems()
+	{
+		return items;
+	}
+
+	/**
+	 * Gets the value of the optional attribute related to the {@link ItemsElementType}.
+	 * 
+	 * @return The attribute value
+	 */
+	public boolean getNotify()
+	{
+		return notify;
+	}
+	
+	@Override
+	public String toXML()
+	{
+		if ((items == null) || (items.size() == 0))
+		{
+			return super.toXML();
+		}
+		else
+		{
+			StringBuilder builder = new StringBuilder("<");
+			builder.append(getElementName());
+			builder.append(" node='");
+			builder.append(getNode());
+			
+			if (notify != null)
+			{
+				builder.append("' ");
+				builder.append(type.getElementAttribute());
+				builder.append("='");
+				builder.append(notify.equals(Boolean.TRUE) ? 1 : 0);
+				builder.append("'>");
+			}
+			else
+			{
+				builder.append("'>");
+				for (PacketExtension item : items)
+				{
+					builder.append(item.toXML());
+				}
+			}
+			
+			builder.append("</");
+			builder.append(getElementName());
+			builder.append(">");
+			return builder.toString();
+		}
+	}
+
+	@Override
+	public String toString()
+	{
+		return getClass().getName() + "Content [" + toXML() + "]";
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/LeafNode.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/LeafNode.java
index eee6293..96ef515 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/LeafNode.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/LeafNode.java
@@ -1,352 +1,352 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.packet.IQ.Type;
-import org.jivesoftware.smackx.packet.DiscoverItems;
-import org.jivesoftware.smackx.pubsub.packet.PubSub;
-import org.jivesoftware.smackx.pubsub.packet.SyncPacketSend;
-
-/**
- * The main class for the majority of pubsub functionality.  In general
- * almost all pubsub capabilities are related to the concept of a node.
- * All items are published to a node, and typically subscribed to by other
- * users.  These users then retrieve events based on this subscription.
- * 
- * @author Robin Collier
- */
-public class LeafNode extends Node
-{
-	LeafNode(Connection connection, String nodeName)
-	{
-		super(connection, nodeName);
-	}
-	
-	/**
-	 * Get information on the items in the node in standard
-	 * {@link DiscoverItems} format.
-	 * 
-	 * @return The item details in {@link DiscoverItems} format
-	 * 
-	 * @throws XMPPException
-	 */
-	public DiscoverItems discoverItems()
-		throws XMPPException
-	{
-		DiscoverItems items = new DiscoverItems();
-		items.setTo(to);
-		items.setNode(getId());
-		return (DiscoverItems)SyncPacketSend.getReply(con, items);
-	}
-
-	/**
-	 * Get the current items stored in the node.
-	 * 
-	 * @return List of {@link Item} in the node
-	 * 
-	 * @throws XMPPException
-	 */
-	public <T extends Item> List<T> getItems()
-		throws XMPPException
-	{
-		PubSub request = createPubsubPacket(Type.GET, new GetItemsRequest(getId()));
-		
-		PubSub result = (PubSub)SyncPacketSend.getReply(con, request);
-		ItemsExtension itemsElem = (ItemsExtension)result.getExtension(PubSubElementType.ITEMS);
-		return (List<T>)itemsElem.getItems();
-	}
-	
-	/**
-	 * Get the current items stored in the node based
-	 * on the subscription associated with the provided 
-	 * subscription id.
-	 * 
-	 * @param subscriptionId -  The subscription id for the 
-	 * associated subscription.
-	 * @return List of {@link Item} in the node
-	 * 
-	 * @throws XMPPException
-	 */
-	public <T extends Item> List<T> getItems(String subscriptionId)
-		throws XMPPException
-	{
-		PubSub request = createPubsubPacket(Type.GET, new GetItemsRequest(getId(), subscriptionId));
-		
-		PubSub result = (PubSub)SyncPacketSend.getReply(con, request);
-		ItemsExtension itemsElem = (ItemsExtension)result.getExtension(PubSubElementType.ITEMS);
-		return (List<T>)itemsElem.getItems();
-	}
-
-	/**
-	 * Get the items specified from the node.  This would typically be
-	 * used when the server does not return the payload due to size 
-	 * constraints.  The user would be required to retrieve the payload 
-	 * after the items have been retrieved via {@link #getItems()} or an
-	 * event, that did not include the payload.
-	 * 
-	 * @param ids Item ids of the items to retrieve
-	 * 
-	 * @return The list of {@link Item} with payload
-	 * 
-	 * @throws XMPPException
-	 */
-	public <T extends Item> List<T> getItems(Collection<String> ids)
-		throws XMPPException
-	{
-		List<Item> itemList = new ArrayList<Item>(ids.size());
-		
-		for (String id : ids)
-		{
-			itemList.add(new Item(id));
-		}
-		PubSub request = createPubsubPacket(Type.GET, new ItemsExtension(ItemsExtension.ItemsElementType.items, getId(), itemList));
-		
-		PubSub result = (PubSub)SyncPacketSend.getReply(con, request);
-		ItemsExtension itemsElem = (ItemsExtension)result.getExtension(PubSubElementType.ITEMS);
-		return (List<T>)itemsElem.getItems();
-	}
-
-	/**
-	 * Get items persisted on the node, limited to the specified number.
-	 * 
-	 * @param maxItems Maximum number of items to return
-	 * 
-	 * @return List of {@link Item}
-	 * 
-	 * @throws XMPPException
-	 */
-	public <T extends Item> List<T> getItems(int maxItems)
-		throws XMPPException
-	{
-		PubSub request = createPubsubPacket(Type.GET, new GetItemsRequest(getId(), maxItems));
-		
-		PubSub result = (PubSub)SyncPacketSend.getReply(con, request);
-		ItemsExtension itemsElem = (ItemsExtension)result.getExtension(PubSubElementType.ITEMS);
-		return (List<T>)itemsElem.getItems();
-	}
-	
-	/**
-	 * Get items persisted on the node, limited to the specified number
-	 * based on the subscription associated with the provided subscriptionId.
-	 * 
-	 * @param maxItems Maximum number of items to return
-	 * @param subscriptionId The subscription which the retrieval is based
-	 * on.
-	 * 
-	 * @return List of {@link Item}
-	 * 
-	 * @throws XMPPException
-	 */
-	public <T extends Item> List<T> getItems(int maxItems, String subscriptionId)
-		throws XMPPException
-	{
-		PubSub request = createPubsubPacket(Type.GET, new GetItemsRequest(getId(), subscriptionId, maxItems));
-		
-		PubSub result = (PubSub)SyncPacketSend.getReply(con, request);
-		ItemsExtension itemsElem = (ItemsExtension)result.getExtension(PubSubElementType.ITEMS);
-		return (List<T>)itemsElem.getItems();
-	}
-	
-	/**
-	 * Publishes an event to the node.  This is an empty event
-	 * with no item.
-	 * 
-	 * This is only acceptable for nodes with {@link ConfigureForm#isPersistItems()}=false
-	 * and {@link ConfigureForm#isDeliverPayloads()}=false.
-	 * 
-	 * This is an asynchronous call which returns as soon as the 
-	 * packet has been sent.
-	 * 
-	 * For synchronous calls use {@link #send() send()}.
-	 */
-	public void publish()
-	{
-		PubSub packet = createPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.PUBLISH, getId()));
-		
-		con.sendPacket(packet);
-	}
-	
-	/**
-	 * Publishes an event to the node.  This is a simple item
-	 * with no payload.
-	 * 
-	 * If the id is null, an empty item (one without an id) will be sent.
-	 * Please note that this is not the same as {@link #send()}, which
-	 * publishes an event with NO item.
-	 * 
-	 * This is an asynchronous call which returns as soon as the 
-	 * packet has been sent.
-	 * 
-	 * For synchronous calls use {@link #send(Item) send(Item))}.
-	 * 
-	 * @param item - The item being sent
-	 */
-	public <T extends Item> void publish(T item)
-	{
-		Collection<T> items = new ArrayList<T>(1);
-		items.add((T)(item == null ? new Item() : item));
-		publish(items);
-	}
-
-	/**
-	 * Publishes multiple events to the node.  Same rules apply as in {@link #publish(Item)}.
-	 * 
-	 * In addition, if {@link ConfigureForm#isPersistItems()}=false, only the last item in the input
-	 * list will get stored on the node, assuming it stores the last sent item.
-	 * 
-	 * This is an asynchronous call which returns as soon as the 
-	 * packet has been sent.
-	 * 
-	 * For synchronous calls use {@link #send(Collection) send(Collection))}.
-	 * 
-	 * @param items - The collection of items being sent
-	 */
-	public <T extends Item> void publish(Collection<T> items)
-	{
-		PubSub packet = createPubsubPacket(Type.SET, new PublishItem<T>(getId(), items));
-		
-		con.sendPacket(packet);
-	}
-
-	/**
-	 * Publishes an event to the node.  This is an empty event
-	 * with no item.
-	 * 
-	 * This is only acceptable for nodes with {@link ConfigureForm#isPersistItems()}=false
-	 * and {@link ConfigureForm#isDeliverPayloads()}=false.
-	 * 
-	 * This is a synchronous call which will throw an exception 
-	 * on failure.
-	 * 
-	 * For asynchronous calls, use {@link #publish() publish()}.
-	 * 
-	 * @throws XMPPException
-	 */
-	public void send()
-		throws XMPPException
-	{
-		PubSub packet = createPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.PUBLISH, getId()));
-		
-		SyncPacketSend.getReply(con, packet);
-	}
-	
-	/**
-	 * Publishes an event to the node.  This can be either a simple item
-	 * with no payload, or one with it.  This is determined by the Node
-	 * configuration.
-	 * 
-	 * If the node has <b>deliver_payload=false</b>, the Item must not
-	 * have a payload.
-	 * 
-	 * If the id is null, an empty item (one without an id) will be sent.
-	 * Please note that this is not the same as {@link #send()}, which
-	 * publishes an event with NO item.
-	 * 
-	 * This is a synchronous call which will throw an exception 
-	 * on failure.
-	 * 
-	 * For asynchronous calls, use {@link #publish(Item) publish(Item)}.
-	 * 
-	 * @param item - The item being sent
-	 * 
-	 * @throws XMPPException
-	 */
-	public <T extends Item> void send(T item)
-		throws XMPPException
-	{
-		Collection<T> items = new ArrayList<T>(1);
-		items.add((item == null ? (T)new Item() : item));
-		send(items);
-	}
-	
-	/**
-	 * Publishes multiple events to the node.  Same rules apply as in {@link #send(Item)}.
-	 * 
-	 * In addition, if {@link ConfigureForm#isPersistItems()}=false, only the last item in the input
-	 * list will get stored on the node, assuming it stores the last sent item.
-	 *  
-	 * This is a synchronous call which will throw an exception 
-	 * on failure.
-	 * 
-	 * For asynchronous calls, use {@link #publish(Collection) publish(Collection))}.
-	 * 
-	 * @param items - The collection of {@link Item} objects being sent
-	 * 
-	 * @throws XMPPException
-	 */
-	public <T extends Item> void send(Collection<T> items)
-		throws XMPPException
-	{
-		PubSub packet = createPubsubPacket(Type.SET, new PublishItem<T>(getId(), items));
-		
-		SyncPacketSend.getReply(con, packet);
-	}
-	
-	/**
-	 * Purges the node of all items.
-	 *   
-	 * <p>Note: Some implementations may keep the last item
-	 * sent.
-	 * 
-	 * @throws XMPPException
-	 */
-	public void deleteAllItems()
-		throws XMPPException
-	{
-		PubSub request = createPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.PURGE_OWNER, getId()), PubSubElementType.PURGE_OWNER.getNamespace());
-		
-		SyncPacketSend.getReply(con, request);
-	}
-	
-	/**
-	 * Delete the item with the specified id from the node.
-	 * 
-	 * @param itemId The id of the item
-	 * 
-	 * @throws XMPPException
-	 */
-	public void deleteItem(String itemId)
-		throws XMPPException
-	{
-		Collection<String> items = new ArrayList<String>(1);
-		items.add(itemId);
-		deleteItem(items);
-	}
-	
-	/**
-	 * Delete the items with the specified id's from the node.
-	 * 
-	 * @param itemIds The list of id's of items to delete
-	 * 
-	 * @throws XMPPException
-	 */
-	public void deleteItem(Collection<String> itemIds)
-		throws XMPPException
-	{
-		List<Item> items = new ArrayList<Item>(itemIds.size());
-		
-		for (String id : itemIds)
-		{
-			items.add(new Item(id));
-		}
-		PubSub request = createPubsubPacket(Type.SET, new ItemsExtension(ItemsExtension.ItemsElementType.retract, getId(), items));
-		SyncPacketSend.getReply(con, request);
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.packet.IQ.Type;
+import org.jivesoftware.smackx.packet.DiscoverItems;
+import org.jivesoftware.smackx.pubsub.packet.PubSub;
+import org.jivesoftware.smackx.pubsub.packet.SyncPacketSend;
+
+/**
+ * The main class for the majority of pubsub functionality.  In general
+ * almost all pubsub capabilities are related to the concept of a node.
+ * All items are published to a node, and typically subscribed to by other
+ * users.  These users then retrieve events based on this subscription.
+ * 
+ * @author Robin Collier
+ */
+public class LeafNode extends Node
+{
+	LeafNode(Connection connection, String nodeName)
+	{
+		super(connection, nodeName);
+	}
+	
+	/**
+	 * Get information on the items in the node in standard
+	 * {@link DiscoverItems} format.
+	 * 
+	 * @return The item details in {@link DiscoverItems} format
+	 * 
+	 * @throws XMPPException
+	 */
+	public DiscoverItems discoverItems()
+		throws XMPPException
+	{
+		DiscoverItems items = new DiscoverItems();
+		items.setTo(to);
+		items.setNode(getId());
+		return (DiscoverItems)SyncPacketSend.getReply(con, items);
+	}
+
+	/**
+	 * Get the current items stored in the node.
+	 * 
+	 * @return List of {@link Item} in the node
+	 * 
+	 * @throws XMPPException
+	 */
+	public <T extends Item> List<T> getItems()
+		throws XMPPException
+	{
+		PubSub request = createPubsubPacket(Type.GET, new GetItemsRequest(getId()));
+		
+		PubSub result = (PubSub)SyncPacketSend.getReply(con, request);
+		ItemsExtension itemsElem = (ItemsExtension)result.getExtension(PubSubElementType.ITEMS);
+		return (List<T>)itemsElem.getItems();
+	}
+	
+	/**
+	 * Get the current items stored in the node based
+	 * on the subscription associated with the provided 
+	 * subscription id.
+	 * 
+	 * @param subscriptionId -  The subscription id for the 
+	 * associated subscription.
+	 * @return List of {@link Item} in the node
+	 * 
+	 * @throws XMPPException
+	 */
+	public <T extends Item> List<T> getItems(String subscriptionId)
+		throws XMPPException
+	{
+		PubSub request = createPubsubPacket(Type.GET, new GetItemsRequest(getId(), subscriptionId));
+		
+		PubSub result = (PubSub)SyncPacketSend.getReply(con, request);
+		ItemsExtension itemsElem = (ItemsExtension)result.getExtension(PubSubElementType.ITEMS);
+		return (List<T>)itemsElem.getItems();
+	}
+
+	/**
+	 * Get the items specified from the node.  This would typically be
+	 * used when the server does not return the payload due to size 
+	 * constraints.  The user would be required to retrieve the payload 
+	 * after the items have been retrieved via {@link #getItems()} or an
+	 * event, that did not include the payload.
+	 * 
+	 * @param ids Item ids of the items to retrieve
+	 * 
+	 * @return The list of {@link Item} with payload
+	 * 
+	 * @throws XMPPException
+	 */
+	public <T extends Item> List<T> getItems(Collection<String> ids)
+		throws XMPPException
+	{
+		List<Item> itemList = new ArrayList<Item>(ids.size());
+		
+		for (String id : ids)
+		{
+			itemList.add(new Item(id));
+		}
+		PubSub request = createPubsubPacket(Type.GET, new ItemsExtension(ItemsExtension.ItemsElementType.items, getId(), itemList));
+		
+		PubSub result = (PubSub)SyncPacketSend.getReply(con, request);
+		ItemsExtension itemsElem = (ItemsExtension)result.getExtension(PubSubElementType.ITEMS);
+		return (List<T>)itemsElem.getItems();
+	}
+
+	/**
+	 * Get items persisted on the node, limited to the specified number.
+	 * 
+	 * @param maxItems Maximum number of items to return
+	 * 
+	 * @return List of {@link Item}
+	 * 
+	 * @throws XMPPException
+	 */
+	public <T extends Item> List<T> getItems(int maxItems)
+		throws XMPPException
+	{
+		PubSub request = createPubsubPacket(Type.GET, new GetItemsRequest(getId(), maxItems));
+		
+		PubSub result = (PubSub)SyncPacketSend.getReply(con, request);
+		ItemsExtension itemsElem = (ItemsExtension)result.getExtension(PubSubElementType.ITEMS);
+		return (List<T>)itemsElem.getItems();
+	}
+	
+	/**
+	 * Get items persisted on the node, limited to the specified number
+	 * based on the subscription associated with the provided subscriptionId.
+	 * 
+	 * @param maxItems Maximum number of items to return
+	 * @param subscriptionId The subscription which the retrieval is based
+	 * on.
+	 * 
+	 * @return List of {@link Item}
+	 * 
+	 * @throws XMPPException
+	 */
+	public <T extends Item> List<T> getItems(int maxItems, String subscriptionId)
+		throws XMPPException
+	{
+		PubSub request = createPubsubPacket(Type.GET, new GetItemsRequest(getId(), subscriptionId, maxItems));
+		
+		PubSub result = (PubSub)SyncPacketSend.getReply(con, request);
+		ItemsExtension itemsElem = (ItemsExtension)result.getExtension(PubSubElementType.ITEMS);
+		return (List<T>)itemsElem.getItems();
+	}
+	
+	/**
+	 * Publishes an event to the node.  This is an empty event
+	 * with no item.
+	 * 
+	 * This is only acceptable for nodes with {@link ConfigureForm#isPersistItems()}=false
+	 * and {@link ConfigureForm#isDeliverPayloads()}=false.
+	 * 
+	 * This is an asynchronous call which returns as soon as the 
+	 * packet has been sent.
+	 * 
+	 * For synchronous calls use {@link #send() send()}.
+	 */
+	public void publish()
+	{
+		PubSub packet = createPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.PUBLISH, getId()));
+		
+		con.sendPacket(packet);
+	}
+	
+	/**
+	 * Publishes an event to the node.  This is a simple item
+	 * with no payload.
+	 * 
+	 * If the id is null, an empty item (one without an id) will be sent.
+	 * Please note that this is not the same as {@link #send()}, which
+	 * publishes an event with NO item.
+	 * 
+	 * This is an asynchronous call which returns as soon as the 
+	 * packet has been sent.
+	 * 
+	 * For synchronous calls use {@link #send(Item) send(Item))}.
+	 * 
+	 * @param item - The item being sent
+	 */
+	public <T extends Item> void publish(T item)
+	{
+		Collection<T> items = new ArrayList<T>(1);
+		items.add((T)(item == null ? new Item() : item));
+		publish(items);
+	}
+
+	/**
+	 * Publishes multiple events to the node.  Same rules apply as in {@link #publish(Item)}.
+	 * 
+	 * In addition, if {@link ConfigureForm#isPersistItems()}=false, only the last item in the input
+	 * list will get stored on the node, assuming it stores the last sent item.
+	 * 
+	 * This is an asynchronous call which returns as soon as the 
+	 * packet has been sent.
+	 * 
+	 * For synchronous calls use {@link #send(Collection) send(Collection))}.
+	 * 
+	 * @param items - The collection of items being sent
+	 */
+	public <T extends Item> void publish(Collection<T> items)
+	{
+		PubSub packet = createPubsubPacket(Type.SET, new PublishItem<T>(getId(), items));
+		
+		con.sendPacket(packet);
+	}
+
+	/**
+	 * Publishes an event to the node.  This is an empty event
+	 * with no item.
+	 * 
+	 * This is only acceptable for nodes with {@link ConfigureForm#isPersistItems()}=false
+	 * and {@link ConfigureForm#isDeliverPayloads()}=false.
+	 * 
+	 * This is a synchronous call which will throw an exception 
+	 * on failure.
+	 * 
+	 * For asynchronous calls, use {@link #publish() publish()}.
+	 * 
+	 * @throws XMPPException
+	 */
+	public void send()
+		throws XMPPException
+	{
+		PubSub packet = createPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.PUBLISH, getId()));
+		
+		SyncPacketSend.getReply(con, packet);
+	}
+	
+	/**
+	 * Publishes an event to the node.  This can be either a simple item
+	 * with no payload, or one with it.  This is determined by the Node
+	 * configuration.
+	 * 
+	 * If the node has <b>deliver_payload=false</b>, the Item must not
+	 * have a payload.
+	 * 
+	 * If the id is null, an empty item (one without an id) will be sent.
+	 * Please note that this is not the same as {@link #send()}, which
+	 * publishes an event with NO item.
+	 * 
+	 * This is a synchronous call which will throw an exception 
+	 * on failure.
+	 * 
+	 * For asynchronous calls, use {@link #publish(Item) publish(Item)}.
+	 * 
+	 * @param item - The item being sent
+	 * 
+	 * @throws XMPPException
+	 */
+	public <T extends Item> void send(T item)
+		throws XMPPException
+	{
+		Collection<T> items = new ArrayList<T>(1);
+		items.add((item == null ? (T)new Item() : item));
+		send(items);
+	}
+	
+	/**
+	 * Publishes multiple events to the node.  Same rules apply as in {@link #send(Item)}.
+	 * 
+	 * In addition, if {@link ConfigureForm#isPersistItems()}=false, only the last item in the input
+	 * list will get stored on the node, assuming it stores the last sent item.
+	 *  
+	 * This is a synchronous call which will throw an exception 
+	 * on failure.
+	 * 
+	 * For asynchronous calls, use {@link #publish(Collection) publish(Collection))}.
+	 * 
+	 * @param items - The collection of {@link Item} objects being sent
+	 * 
+	 * @throws XMPPException
+	 */
+	public <T extends Item> void send(Collection<T> items)
+		throws XMPPException
+	{
+		PubSub packet = createPubsubPacket(Type.SET, new PublishItem<T>(getId(), items));
+		
+		SyncPacketSend.getReply(con, packet);
+	}
+	
+	/**
+	 * Purges the node of all items.
+	 *   
+	 * <p>Note: Some implementations may keep the last item
+	 * sent.
+	 * 
+	 * @throws XMPPException
+	 */
+	public void deleteAllItems()
+		throws XMPPException
+	{
+		PubSub request = createPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.PURGE_OWNER, getId()), PubSubElementType.PURGE_OWNER.getNamespace());
+		
+		SyncPacketSend.getReply(con, request);
+	}
+	
+	/**
+	 * Delete the item with the specified id from the node.
+	 * 
+	 * @param itemId The id of the item
+	 * 
+	 * @throws XMPPException
+	 */
+	public void deleteItem(String itemId)
+		throws XMPPException
+	{
+		Collection<String> items = new ArrayList<String>(1);
+		items.add(itemId);
+		deleteItem(items);
+	}
+	
+	/**
+	 * Delete the items with the specified id's from the node.
+	 * 
+	 * @param itemIds The list of id's of items to delete
+	 * 
+	 * @throws XMPPException
+	 */
+	public void deleteItem(Collection<String> itemIds)
+		throws XMPPException
+	{
+		List<Item> items = new ArrayList<Item>(itemIds.size());
+		
+		for (String id : itemIds)
+		{
+			items.add(new Item(id));
+		}
+		PubSub request = createPubsubPacket(Type.SET, new ItemsExtension(ItemsExtension.ItemsElementType.retract, getId(), items));
+		SyncPacketSend.getReply(con, request);
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/Node.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/Node.java
index 1b0ff5a..3e745f3 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/Node.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/Node.java
@@ -17,525 +17,525 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jivesoftware.smackx.pubsub;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.jivesoftware.smack.PacketListener;
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.filter.OrFilter;
-import org.jivesoftware.smack.filter.PacketFilter;
-import org.jivesoftware.smack.packet.Message;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.packet.IQ.Type;
-import org.jivesoftware.smackx.Form;
-import org.jivesoftware.smackx.packet.DelayInformation;
-import org.jivesoftware.smackx.packet.DiscoverInfo;
-import org.jivesoftware.smackx.packet.Header;
-import org.jivesoftware.smackx.packet.HeadersExtension;
-import org.jivesoftware.smackx.pubsub.listener.ItemDeleteListener;
-import org.jivesoftware.smackx.pubsub.listener.ItemEventListener;
-import org.jivesoftware.smackx.pubsub.listener.NodeConfigListener;
-import org.jivesoftware.smackx.pubsub.packet.PubSub;
-import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
-import org.jivesoftware.smackx.pubsub.packet.SyncPacketSend;
-import org.jivesoftware.smackx.pubsub.util.NodeUtils;
-
-abstract public class Node
-{
-	protected Connection con;
-	protected String id;
-	protected String to;
-	
-	protected ConcurrentHashMap<ItemEventListener<Item>, PacketListener> itemEventToListenerMap = new ConcurrentHashMap<ItemEventListener<Item>, PacketListener>();
-	protected ConcurrentHashMap<ItemDeleteListener, PacketListener> itemDeleteToListenerMap = new ConcurrentHashMap<ItemDeleteListener, PacketListener>();
-	protected ConcurrentHashMap<NodeConfigListener, PacketListener> configEventToListenerMap = new ConcurrentHashMap<NodeConfigListener, PacketListener>();
-	
-	/**
-	 * Construct a node associated to the supplied connection with the specified 
-	 * node id.
-	 * 
-	 * @param connection The connection the node is associated with
-	 * @param nodeName The node id
-	 */
-	Node(Connection connection, String nodeName)
-	{
-		con = connection;
-		id = nodeName;
-	}
-
-	/**
-	 * Some XMPP servers may require a specific service to be addressed on the 
-	 * server.
-	 * 
-	 *   For example, OpenFire requires the server to be prefixed by <b>pubsub</b>
-	 */
-	void setTo(String toAddress)
-	{
-		to = toAddress;
-	}
-
-	/**
-	 * Get the NodeId
-	 * 
-	 * @return the node id
-	 */
-	public String getId() 
-	{
-		return id;
-	}
-	/**
-	 * Returns a configuration form, from which you can create an answer form to be submitted
-	 * via the {@link #sendConfigurationForm(Form)}.
-	 * 
-	 * @return the configuration form
-	 */
-	public ConfigureForm getNodeConfiguration()
-		throws XMPPException
-	{
-		Packet reply = sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.CONFIGURE_OWNER, getId()), PubSubNamespace.OWNER);
-		return NodeUtils.getFormFromPacket(reply, PubSubElementType.CONFIGURE_OWNER);
-	}
-	
-	/**
-	 * Update the configuration with the contents of the new {@link Form}
-	 * 
-	 * @param submitForm
-	 */
-	public void sendConfigurationForm(Form submitForm)
-		throws XMPPException
-	{
-		PubSub packet = createPubsubPacket(Type.SET, new FormNode(FormNodeType.CONFIGURE_OWNER, getId(), submitForm), PubSubNamespace.OWNER);
-		SyncPacketSend.getReply(con, packet);
-	}
-	
-	/**
-	 * Discover node information in standard {@link DiscoverInfo} format.
-	 * 
-	 * @return The discovery information about the node.
-	 * 
-	 * @throws XMPPException
-	 */
-	public DiscoverInfo discoverInfo()
-		throws XMPPException
-	{
-		DiscoverInfo info = new DiscoverInfo();
-		info.setTo(to);
-		info.setNode(getId());
-		return (DiscoverInfo)SyncPacketSend.getReply(con, info);
-	}
-	
-	/**
-	 * Get the subscriptions currently associated with this node.
-	 * 
-	 * @return List of {@link Subscription}
-	 * 
-	 * @throws XMPPException
-	 */
-	public List<Subscription> getSubscriptions()
-		throws XMPPException
-	{
-		PubSub reply = (PubSub)sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.SUBSCRIPTIONS, getId()));
-		SubscriptionsExtension subElem = (SubscriptionsExtension)reply.getExtension(PubSubElementType.SUBSCRIPTIONS);
-		return subElem.getSubscriptions();
-	}
-
-	/**
-	 * The user subscribes to the node using the supplied jid.  The
-	 * bare jid portion of this one must match the jid for the connection.
-	 * 
-	 * Please note that the {@link Subscription.State} should be checked 
-	 * on return since more actions may be required by the caller.
-	 * {@link Subscription.State#pending} - The owner must approve the subscription 
-	 * request before messages will be received.
-	 * {@link Subscription.State#unconfigured} - If the {@link Subscription#isConfigRequired()} is true, 
-	 * the caller must configure the subscription before messages will be received.  If it is false
-	 * the caller can configure it but is not required to do so.
-	 * @param jid The jid to subscribe as.
-	 * @return The subscription
-	 * @exception XMPPException
-	 */
-	public Subscription subscribe(String jid)
-		throws XMPPException
-	{
-		PubSub reply = (PubSub)sendPubsubPacket(Type.SET, new SubscribeExtension(jid, getId()));
-		return (Subscription)reply.getExtension(PubSubElementType.SUBSCRIPTION);
-	}
-	
-	/**
-	 * The user subscribes to the node using the supplied jid and subscription
-	 * options.  The bare jid portion of this one must match the jid for the 
-	 * connection.
-	 * 
-	 * Please note that the {@link Subscription.State} should be checked 
-	 * on return since more actions may be required by the caller.
-	 * {@link Subscription.State#pending} - The owner must approve the subscription 
-	 * request before messages will be received.
-	 * {@link Subscription.State#unconfigured} - If the {@link Subscription#isConfigRequired()} is true, 
-	 * the caller must configure the subscription before messages will be received.  If it is false
-	 * the caller can configure it but is not required to do so.
-	 * @param jid The jid to subscribe as.
-	 * @return The subscription
-	 * @exception XMPPException
-	 */
-	public Subscription subscribe(String jid, SubscribeForm subForm)
-		throws XMPPException
-	{
-		PubSub request = createPubsubPacket(Type.SET, new SubscribeExtension(jid, getId()));
-		request.addExtension(new FormNode(FormNodeType.OPTIONS, subForm));
-		PubSub reply = (PubSub)PubSubManager.sendPubsubPacket(con, jid, Type.SET, request);
-		return (Subscription)reply.getExtension(PubSubElementType.SUBSCRIPTION);
-	}
-
-	/**
-	 * Remove the subscription related to the specified JID.  This will only 
-	 * work if there is only 1 subscription.  If there are multiple subscriptions,
-	 * use {@link #unsubscribe(String, String)}.
-	 * 
-	 * @param jid The JID used to subscribe to the node
-	 * 
-	 * @throws XMPPException
-	 */
-	public void unsubscribe(String jid)
-		throws XMPPException
-	{
-		unsubscribe(jid, null);
-	}
-	
-	/**
-	 * Remove the specific subscription related to the specified JID.
-	 * 
-	 * @param jid The JID used to subscribe to the node
-	 * @param subscriptionId The id of the subscription being removed
-	 * 
-	 * @throws XMPPException
-	 */
-	public void unsubscribe(String jid, String subscriptionId)
-		throws XMPPException
-	{
-		sendPubsubPacket(Type.SET, new UnsubscribeExtension(jid, getId(), subscriptionId));
-	}
-
-	/**
-	 * Returns a SubscribeForm for subscriptions, from which you can create an answer form to be submitted
-	 * via the {@link #sendConfigurationForm(Form)}.
-	 * 
-	 * @return A subscription options form
-	 * 
-	 * @throws XMPPException
-	 */
-	public SubscribeForm getSubscriptionOptions(String jid)
-		throws XMPPException
-	{
-		return getSubscriptionOptions(jid, null);
-	}
-
-
-	/**
-	 * Get the options for configuring the specified subscription.
-	 * 
-	 * @param jid JID the subscription is registered under
-	 * @param subscriptionId The subscription id
-	 * 
-	 * @return The subscription option form
-	 * 
-	 * @throws XMPPException
-	 */
-	public SubscribeForm getSubscriptionOptions(String jid, String subscriptionId)
-		throws XMPPException
-	{
-		PubSub packet = (PubSub)sendPubsubPacket(Type.GET, new OptionsExtension(jid, getId(), subscriptionId));
-		FormNode ext = (FormNode)packet.getExtension(PubSubElementType.OPTIONS);
-		return new SubscribeForm(ext.getForm());
-	}
-
-	/**
-	 * Register a listener for item publication events.  This 
-	 * listener will get called whenever an item is published to 
-	 * this node.
-	 * 
-	 * @param listener The handler for the event
-	 */
-	public void addItemEventListener(ItemEventListener listener)
-	{
-		PacketListener conListener = new ItemEventTranslator(listener); 
-		itemEventToListenerMap.put(listener, conListener);
-		con.addPacketListener(conListener, new EventContentFilter(EventElementType.items.toString(), "item"));
-	}
-
-	/**
-	 * Unregister a listener for publication events.
-	 * 
-	 * @param listener The handler to unregister
-	 */
-	public void removeItemEventListener(ItemEventListener listener)
-	{
-		PacketListener conListener = itemEventToListenerMap.remove(listener);
-		
-		if (conListener != null)
-			con.removePacketListener(conListener);
-	}
-
-	/**
-	 * Register a listener for configuration events.  This listener
-	 * will get called whenever the node's configuration changes.
-	 * 
-	 * @param listener The handler for the event
-	 */
-	public void addConfigurationListener(NodeConfigListener listener)
-	{
-		PacketListener conListener = new NodeConfigTranslator(listener); 
-		configEventToListenerMap.put(listener, conListener);
-		con.addPacketListener(conListener, new EventContentFilter(EventElementType.configuration.toString()));
-	}
-
-	/**
-	 * Unregister a listener for configuration events.
-	 * 
-	 * @param listener The handler to unregister
-	 */
-	public void removeConfigurationListener(NodeConfigListener listener)
-	{
-		PacketListener conListener = configEventToListenerMap .remove(listener);
-		
-		if (conListener != null)
-			con.removePacketListener(conListener);
-	}
-	
-	/**
-	 * Register an listener for item delete events.  This listener
-	 * gets called whenever an item is deleted from the node.
-	 * 
-	 * @param listener The handler for the event
-	 */
-	public void addItemDeleteListener(ItemDeleteListener listener)
-	{
-		PacketListener delListener = new ItemDeleteTranslator(listener); 
-		itemDeleteToListenerMap.put(listener, delListener);
-		EventContentFilter deleteItem = new EventContentFilter(EventElementType.items.toString(), "retract");
-		EventContentFilter purge = new EventContentFilter(EventElementType.purge.toString());
-		
-		con.addPacketListener(delListener, new OrFilter(deleteItem, purge));
-	}
-
-	/**
-	 * Unregister a listener for item delete events.
-	 * 
-	 * @param listener The handler to unregister
-	 */
-	public void removeItemDeleteListener(ItemDeleteListener listener)
-	{
-		PacketListener conListener = itemDeleteToListenerMap .remove(listener);
-		
-		if (conListener != null)
-			con.removePacketListener(conListener);
-	}
-
-	@Override
-	public String toString()
-	{
-		return super.toString() + " " + getClass().getName() + " id: " + id;
-	}
-	
-	protected PubSub createPubsubPacket(Type type, PacketExtension ext)
-	{
-		return createPubsubPacket(type, ext, null);
-	}
-	
-	protected PubSub createPubsubPacket(Type type, PacketExtension ext, PubSubNamespace ns)
-	{
-		return PubSubManager.createPubsubPacket(to, type, ext, ns);
-	}
-
-	protected Packet sendPubsubPacket(Type type, NodeExtension ext)
-		throws XMPPException
-	{
-		return PubSubManager.sendPubsubPacket(con, to, type, ext);
-	}
-
-	protected Packet sendPubsubPacket(Type type, NodeExtension ext, PubSubNamespace ns)
-		throws XMPPException
-	{
-		return PubSubManager.sendPubsubPacket(con, to, type, ext, ns);
-	}
-
-
-	private static List<String> getSubscriptionIds(Packet packet)
-	{
-		HeadersExtension headers = (HeadersExtension)packet.getExtension("headers", "http://jabber.org/protocol/shim");
-		List<String> values = null;
-		
-		if (headers != null)
-		{
-			values = new ArrayList<String>(headers.getHeaders().size());
-			
-			for (Header header : headers.getHeaders())
-			{
-				values.add(header.getValue());
-			}
-		}
-		return values;
-	}
-
-	/**
-	 * This class translates low level item publication events into api level objects for 
-	 * user consumption.
-	 * 
-	 * @author Robin Collier
-	 */
-	public class ItemEventTranslator implements PacketListener
-	{
-		private ItemEventListener listener;
-
-		public ItemEventTranslator(ItemEventListener eventListener)
-		{
-			listener = eventListener;
-		}
-		
-		public void processPacket(Packet packet)
-		{
-	        EventElement event = (EventElement)packet.getExtension("event", PubSubNamespace.EVENT.getXmlns());
-			ItemsExtension itemsElem = (ItemsExtension)event.getEvent();
-			DelayInformation delay = (DelayInformation)packet.getExtension("delay", "urn:xmpp:delay");
-			
-			// If there was no delay based on XEP-0203, then try XEP-0091 for backward compatibility
-			if (delay == null)
-			{
-				delay = (DelayInformation)packet.getExtension("x", "jabber:x:delay");
-			}
-			ItemPublishEvent eventItems = new ItemPublishEvent(itemsElem.getNode(), (List<Item>)itemsElem.getItems(), getSubscriptionIds(packet), (delay == null ? null : delay.getStamp()));
-			listener.handlePublishedItems(eventItems);
-		}
-	}
-
-	/**
-	 * This class translates low level item deletion events into api level objects for 
-	 * user consumption.
-	 * 
-	 * @author Robin Collier
-	 */
-	public class ItemDeleteTranslator implements PacketListener
-	{
-		private ItemDeleteListener listener;
-
-		public ItemDeleteTranslator(ItemDeleteListener eventListener)
-		{
-			listener = eventListener;
-		}
-		
-		public void processPacket(Packet packet)
-		{
-	        EventElement event = (EventElement)packet.getExtension("event", PubSubNamespace.EVENT.getXmlns());
-	        
-	        List<PacketExtension> extList = event.getExtensions();
-	        
-	        if (extList.get(0).getElementName().equals(PubSubElementType.PURGE_EVENT.getElementName()))
-	        {
-	        	listener.handlePurge();
-	        }
-	        else
-	        {
-				ItemsExtension itemsElem = (ItemsExtension)event.getEvent();
-				Collection<? extends PacketExtension> pubItems = itemsElem.getItems();
-				Iterator<RetractItem> it = (Iterator<RetractItem>)pubItems.iterator();
-				List<String> items = new ArrayList<String>(pubItems.size());
-
-				while (it.hasNext())
-				{
-					RetractItem item = it.next();
-					items.add(item.getId());
-				}
-
-				ItemDeleteEvent eventItems = new ItemDeleteEvent(itemsElem.getNode(), items, getSubscriptionIds(packet));
-				listener.handleDeletedItems(eventItems);
-	        }
-		}
-	}
-	
-	/**
-	 * This class translates low level node configuration events into api level objects for 
-	 * user consumption.
-	 * 
-	 * @author Robin Collier
-	 */
-	public class NodeConfigTranslator implements PacketListener
-	{
-		private NodeConfigListener listener;
-
-		public NodeConfigTranslator(NodeConfigListener eventListener)
-		{
-			listener = eventListener;
-		}
-		
-		public void processPacket(Packet packet)
-		{
-	        EventElement event = (EventElement)packet.getExtension("event", PubSubNamespace.EVENT.getXmlns());
-			ConfigurationEvent config = (ConfigurationEvent)event.getEvent();
-
-			listener.handleNodeConfiguration(config);
-		}
-	}
-
-	/**
-	 * Filter for {@link PacketListener} to filter out events not specific to the 
-	 * event type expected for this node.
-	 * 
-	 * @author Robin Collier
-	 */
-	class EventContentFilter implements PacketFilter
-	{
-		private String firstElement;
-		private String secondElement;
-		
-		EventContentFilter(String elementName)
-		{
-			firstElement = elementName;
-		}
-
-		EventContentFilter(String firstLevelEelement, String secondLevelElement)
-		{
-			firstElement = firstLevelEelement;
-			secondElement = secondLevelElement;
-		}
-
-		public boolean accept(Packet packet)
-		{
-			if (!(packet instanceof Message))
-				return false;
-
-			EventElement event = (EventElement)packet.getExtension("event", PubSubNamespace.EVENT.getXmlns());
-			
-			if (event == null)
-				return false;
-
-			NodeExtension embedEvent = event.getEvent();
-			
-			if (embedEvent == null)
-				return false;
-			
-			if (embedEvent.getElementName().equals(firstElement))
-			{
-				if (!embedEvent.getNode().equals(getId()))
-					return false;
-				
-				if (secondElement == null)
-					return true;
-				
-				if (embedEvent instanceof EmbeddedPacketExtension)
-				{
-					List<PacketExtension> secondLevelList = ((EmbeddedPacketExtension)embedEvent).getExtensions();
-					
-					if (secondLevelList.size() > 0 && secondLevelList.get(0).getElementName().equals(secondElement))
-						return true;
-				}
-			}
-			return false;
-		}
-	}
-}
+package org.jivesoftware.smackx.pubsub;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.jivesoftware.smack.PacketListener;
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.filter.OrFilter;
+import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.packet.Message;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.packet.IQ.Type;
+import org.jivesoftware.smackx.Form;
+import org.jivesoftware.smackx.packet.DelayInformation;
+import org.jivesoftware.smackx.packet.DiscoverInfo;
+import org.jivesoftware.smackx.packet.Header;
+import org.jivesoftware.smackx.packet.HeadersExtension;
+import org.jivesoftware.smackx.pubsub.listener.ItemDeleteListener;
+import org.jivesoftware.smackx.pubsub.listener.ItemEventListener;
+import org.jivesoftware.smackx.pubsub.listener.NodeConfigListener;
+import org.jivesoftware.smackx.pubsub.packet.PubSub;
+import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
+import org.jivesoftware.smackx.pubsub.packet.SyncPacketSend;
+import org.jivesoftware.smackx.pubsub.util.NodeUtils;
+
+abstract public class Node
+{
+	protected Connection con;
+	protected String id;
+	protected String to;
+	
+	protected ConcurrentHashMap<ItemEventListener<Item>, PacketListener> itemEventToListenerMap = new ConcurrentHashMap<ItemEventListener<Item>, PacketListener>();
+	protected ConcurrentHashMap<ItemDeleteListener, PacketListener> itemDeleteToListenerMap = new ConcurrentHashMap<ItemDeleteListener, PacketListener>();
+	protected ConcurrentHashMap<NodeConfigListener, PacketListener> configEventToListenerMap = new ConcurrentHashMap<NodeConfigListener, PacketListener>();
+	
+	/**
+	 * Construct a node associated to the supplied connection with the specified 
+	 * node id.
+	 * 
+	 * @param connection The connection the node is associated with
+	 * @param nodeName The node id
+	 */
+	Node(Connection connection, String nodeName)
+	{
+		con = connection;
+		id = nodeName;
+	}
+
+	/**
+	 * Some XMPP servers may require a specific service to be addressed on the 
+	 * server.
+	 * 
+	 *   For example, OpenFire requires the server to be prefixed by <b>pubsub</b>
+	 */
+	void setTo(String toAddress)
+	{
+		to = toAddress;
+	}
+
+	/**
+	 * Get the NodeId
+	 * 
+	 * @return the node id
+	 */
+	public String getId() 
+	{
+		return id;
+	}
+	/**
+	 * Returns a configuration form, from which you can create an answer form to be submitted
+	 * via the {@link #sendConfigurationForm(Form)}.
+	 * 
+	 * @return the configuration form
+	 */
+	public ConfigureForm getNodeConfiguration()
+		throws XMPPException
+	{
+		Packet reply = sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.CONFIGURE_OWNER, getId()), PubSubNamespace.OWNER);
+		return NodeUtils.getFormFromPacket(reply, PubSubElementType.CONFIGURE_OWNER);
+	}
+	
+	/**
+	 * Update the configuration with the contents of the new {@link Form}
+	 * 
+	 * @param submitForm
+	 */
+	public void sendConfigurationForm(Form submitForm)
+		throws XMPPException
+	{
+		PubSub packet = createPubsubPacket(Type.SET, new FormNode(FormNodeType.CONFIGURE_OWNER, getId(), submitForm), PubSubNamespace.OWNER);
+		SyncPacketSend.getReply(con, packet);
+	}
+	
+	/**
+	 * Discover node information in standard {@link DiscoverInfo} format.
+	 * 
+	 * @return The discovery information about the node.
+	 * 
+	 * @throws XMPPException
+	 */
+	public DiscoverInfo discoverInfo()
+		throws XMPPException
+	{
+		DiscoverInfo info = new DiscoverInfo();
+		info.setTo(to);
+		info.setNode(getId());
+		return (DiscoverInfo)SyncPacketSend.getReply(con, info);
+	}
+	
+	/**
+	 * Get the subscriptions currently associated with this node.
+	 * 
+	 * @return List of {@link Subscription}
+	 * 
+	 * @throws XMPPException
+	 */
+	public List<Subscription> getSubscriptions()
+		throws XMPPException
+	{
+		PubSub reply = (PubSub)sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.SUBSCRIPTIONS, getId()));
+		SubscriptionsExtension subElem = (SubscriptionsExtension)reply.getExtension(PubSubElementType.SUBSCRIPTIONS);
+		return subElem.getSubscriptions();
+	}
+
+	/**
+	 * The user subscribes to the node using the supplied jid.  The
+	 * bare jid portion of this one must match the jid for the connection.
+	 * 
+	 * Please note that the {@link Subscription.State} should be checked 
+	 * on return since more actions may be required by the caller.
+	 * {@link Subscription.State#pending} - The owner must approve the subscription 
+	 * request before messages will be received.
+	 * {@link Subscription.State#unconfigured} - If the {@link Subscription#isConfigRequired()} is true, 
+	 * the caller must configure the subscription before messages will be received.  If it is false
+	 * the caller can configure it but is not required to do so.
+	 * @param jid The jid to subscribe as.
+	 * @return The subscription
+	 * @exception XMPPException
+	 */
+	public Subscription subscribe(String jid)
+		throws XMPPException
+	{
+		PubSub reply = (PubSub)sendPubsubPacket(Type.SET, new SubscribeExtension(jid, getId()));
+		return (Subscription)reply.getExtension(PubSubElementType.SUBSCRIPTION);
+	}
+	
+	/**
+	 * The user subscribes to the node using the supplied jid and subscription
+	 * options.  The bare jid portion of this one must match the jid for the 
+	 * connection.
+	 * 
+	 * Please note that the {@link Subscription.State} should be checked 
+	 * on return since more actions may be required by the caller.
+	 * {@link Subscription.State#pending} - The owner must approve the subscription 
+	 * request before messages will be received.
+	 * {@link Subscription.State#unconfigured} - If the {@link Subscription#isConfigRequired()} is true, 
+	 * the caller must configure the subscription before messages will be received.  If it is false
+	 * the caller can configure it but is not required to do so.
+	 * @param jid The jid to subscribe as.
+	 * @return The subscription
+	 * @exception XMPPException
+	 */
+	public Subscription subscribe(String jid, SubscribeForm subForm)
+		throws XMPPException
+	{
+		PubSub request = createPubsubPacket(Type.SET, new SubscribeExtension(jid, getId()));
+		request.addExtension(new FormNode(FormNodeType.OPTIONS, subForm));
+		PubSub reply = (PubSub)PubSubManager.sendPubsubPacket(con, jid, Type.SET, request);
+		return (Subscription)reply.getExtension(PubSubElementType.SUBSCRIPTION);
+	}
+
+	/**
+	 * Remove the subscription related to the specified JID.  This will only 
+	 * work if there is only 1 subscription.  If there are multiple subscriptions,
+	 * use {@link #unsubscribe(String, String)}.
+	 * 
+	 * @param jid The JID used to subscribe to the node
+	 * 
+	 * @throws XMPPException
+	 */
+	public void unsubscribe(String jid)
+		throws XMPPException
+	{
+		unsubscribe(jid, null);
+	}
+	
+	/**
+	 * Remove the specific subscription related to the specified JID.
+	 * 
+	 * @param jid The JID used to subscribe to the node
+	 * @param subscriptionId The id of the subscription being removed
+	 * 
+	 * @throws XMPPException
+	 */
+	public void unsubscribe(String jid, String subscriptionId)
+		throws XMPPException
+	{
+		sendPubsubPacket(Type.SET, new UnsubscribeExtension(jid, getId(), subscriptionId));
+	}
+
+	/**
+	 * Returns a SubscribeForm for subscriptions, from which you can create an answer form to be submitted
+	 * via the {@link #sendConfigurationForm(Form)}.
+	 * 
+	 * @return A subscription options form
+	 * 
+	 * @throws XMPPException
+	 */
+	public SubscribeForm getSubscriptionOptions(String jid)
+		throws XMPPException
+	{
+		return getSubscriptionOptions(jid, null);
+	}
+
+
+	/**
+	 * Get the options for configuring the specified subscription.
+	 * 
+	 * @param jid JID the subscription is registered under
+	 * @param subscriptionId The subscription id
+	 * 
+	 * @return The subscription option form
+	 * 
+	 * @throws XMPPException
+	 */
+	public SubscribeForm getSubscriptionOptions(String jid, String subscriptionId)
+		throws XMPPException
+	{
+		PubSub packet = (PubSub)sendPubsubPacket(Type.GET, new OptionsExtension(jid, getId(), subscriptionId));
+		FormNode ext = (FormNode)packet.getExtension(PubSubElementType.OPTIONS);
+		return new SubscribeForm(ext.getForm());
+	}
+
+	/**
+	 * Register a listener for item publication events.  This 
+	 * listener will get called whenever an item is published to 
+	 * this node.
+	 * 
+	 * @param listener The handler for the event
+	 */
+	public void addItemEventListener(ItemEventListener listener)
+	{
+		PacketListener conListener = new ItemEventTranslator(listener); 
+		itemEventToListenerMap.put(listener, conListener);
+		con.addPacketListener(conListener, new EventContentFilter(EventElementType.items.toString(), "item"));
+	}
+
+	/**
+	 * Unregister a listener for publication events.
+	 * 
+	 * @param listener The handler to unregister
+	 */
+	public void removeItemEventListener(ItemEventListener listener)
+	{
+		PacketListener conListener = itemEventToListenerMap.remove(listener);
+		
+		if (conListener != null)
+			con.removePacketListener(conListener);
+	}
+
+	/**
+	 * Register a listener for configuration events.  This listener
+	 * will get called whenever the node's configuration changes.
+	 * 
+	 * @param listener The handler for the event
+	 */
+	public void addConfigurationListener(NodeConfigListener listener)
+	{
+		PacketListener conListener = new NodeConfigTranslator(listener); 
+		configEventToListenerMap.put(listener, conListener);
+		con.addPacketListener(conListener, new EventContentFilter(EventElementType.configuration.toString()));
+	}
+
+	/**
+	 * Unregister a listener for configuration events.
+	 * 
+	 * @param listener The handler to unregister
+	 */
+	public void removeConfigurationListener(NodeConfigListener listener)
+	{
+		PacketListener conListener = configEventToListenerMap .remove(listener);
+		
+		if (conListener != null)
+			con.removePacketListener(conListener);
+	}
+	
+	/**
+	 * Register an listener for item delete events.  This listener
+	 * gets called whenever an item is deleted from the node.
+	 * 
+	 * @param listener The handler for the event
+	 */
+	public void addItemDeleteListener(ItemDeleteListener listener)
+	{
+		PacketListener delListener = new ItemDeleteTranslator(listener); 
+		itemDeleteToListenerMap.put(listener, delListener);
+		EventContentFilter deleteItem = new EventContentFilter(EventElementType.items.toString(), "retract");
+		EventContentFilter purge = new EventContentFilter(EventElementType.purge.toString());
+		
+		con.addPacketListener(delListener, new OrFilter(deleteItem, purge));
+	}
+
+	/**
+	 * Unregister a listener for item delete events.
+	 * 
+	 * @param listener The handler to unregister
+	 */
+	public void removeItemDeleteListener(ItemDeleteListener listener)
+	{
+		PacketListener conListener = itemDeleteToListenerMap .remove(listener);
+		
+		if (conListener != null)
+			con.removePacketListener(conListener);
+	}
+
+	@Override
+	public String toString()
+	{
+		return super.toString() + " " + getClass().getName() + " id: " + id;
+	}
+	
+	protected PubSub createPubsubPacket(Type type, PacketExtension ext)
+	{
+		return createPubsubPacket(type, ext, null);
+	}
+	
+	protected PubSub createPubsubPacket(Type type, PacketExtension ext, PubSubNamespace ns)
+	{
+		return PubSubManager.createPubsubPacket(to, type, ext, ns);
+	}
+
+	protected Packet sendPubsubPacket(Type type, NodeExtension ext)
+		throws XMPPException
+	{
+		return PubSubManager.sendPubsubPacket(con, to, type, ext);
+	}
+
+	protected Packet sendPubsubPacket(Type type, NodeExtension ext, PubSubNamespace ns)
+		throws XMPPException
+	{
+		return PubSubManager.sendPubsubPacket(con, to, type, ext, ns);
+	}
+
+
+	private static List<String> getSubscriptionIds(Packet packet)
+	{
+		HeadersExtension headers = (HeadersExtension)packet.getExtension("headers", "http://jabber.org/protocol/shim");
+		List<String> values = null;
+		
+		if (headers != null)
+		{
+			values = new ArrayList<String>(headers.getHeaders().size());
+			
+			for (Header header : headers.getHeaders())
+			{
+				values.add(header.getValue());
+			}
+		}
+		return values;
+	}
+
+	/**
+	 * This class translates low level item publication events into api level objects for 
+	 * user consumption.
+	 * 
+	 * @author Robin Collier
+	 */
+	public class ItemEventTranslator implements PacketListener
+	{
+		private ItemEventListener listener;
+
+		public ItemEventTranslator(ItemEventListener eventListener)
+		{
+			listener = eventListener;
+		}
+		
+		public void processPacket(Packet packet)
+		{
+	        EventElement event = (EventElement)packet.getExtension("event", PubSubNamespace.EVENT.getXmlns());
+			ItemsExtension itemsElem = (ItemsExtension)event.getEvent();
+			DelayInformation delay = (DelayInformation)packet.getExtension("delay", "urn:xmpp:delay");
+			
+			// If there was no delay based on XEP-0203, then try XEP-0091 for backward compatibility
+			if (delay == null)
+			{
+				delay = (DelayInformation)packet.getExtension("x", "jabber:x:delay");
+			}
+			ItemPublishEvent eventItems = new ItemPublishEvent(itemsElem.getNode(), (List<Item>)itemsElem.getItems(), getSubscriptionIds(packet), (delay == null ? null : delay.getStamp()));
+			listener.handlePublishedItems(eventItems);
+		}
+	}
+
+	/**
+	 * This class translates low level item deletion events into api level objects for 
+	 * user consumption.
+	 * 
+	 * @author Robin Collier
+	 */
+	public class ItemDeleteTranslator implements PacketListener
+	{
+		private ItemDeleteListener listener;
+
+		public ItemDeleteTranslator(ItemDeleteListener eventListener)
+		{
+			listener = eventListener;
+		}
+		
+		public void processPacket(Packet packet)
+		{
+	        EventElement event = (EventElement)packet.getExtension("event", PubSubNamespace.EVENT.getXmlns());
+	        
+	        List<PacketExtension> extList = event.getExtensions();
+	        
+	        if (extList.get(0).getElementName().equals(PubSubElementType.PURGE_EVENT.getElementName()))
+	        {
+	        	listener.handlePurge();
+	        }
+	        else
+	        {
+				ItemsExtension itemsElem = (ItemsExtension)event.getEvent();
+				Collection<? extends PacketExtension> pubItems = itemsElem.getItems();
+				Iterator<RetractItem> it = (Iterator<RetractItem>)pubItems.iterator();
+				List<String> items = new ArrayList<String>(pubItems.size());
+
+				while (it.hasNext())
+				{
+					RetractItem item = it.next();
+					items.add(item.getId());
+				}
+
+				ItemDeleteEvent eventItems = new ItemDeleteEvent(itemsElem.getNode(), items, getSubscriptionIds(packet));
+				listener.handleDeletedItems(eventItems);
+	        }
+		}
+	}
+	
+	/**
+	 * This class translates low level node configuration events into api level objects for 
+	 * user consumption.
+	 * 
+	 * @author Robin Collier
+	 */
+	public class NodeConfigTranslator implements PacketListener
+	{
+		private NodeConfigListener listener;
+
+		public NodeConfigTranslator(NodeConfigListener eventListener)
+		{
+			listener = eventListener;
+		}
+		
+		public void processPacket(Packet packet)
+		{
+	        EventElement event = (EventElement)packet.getExtension("event", PubSubNamespace.EVENT.getXmlns());
+			ConfigurationEvent config = (ConfigurationEvent)event.getEvent();
+
+			listener.handleNodeConfiguration(config);
+		}
+	}
+
+	/**
+	 * Filter for {@link PacketListener} to filter out events not specific to the 
+	 * event type expected for this node.
+	 * 
+	 * @author Robin Collier
+	 */
+	class EventContentFilter implements PacketFilter
+	{
+		private String firstElement;
+		private String secondElement;
+		
+		EventContentFilter(String elementName)
+		{
+			firstElement = elementName;
+		}
+
+		EventContentFilter(String firstLevelEelement, String secondLevelElement)
+		{
+			firstElement = firstLevelEelement;
+			secondElement = secondLevelElement;
+		}
+
+		public boolean accept(Packet packet)
+		{
+			if (!(packet instanceof Message))
+				return false;
+
+			EventElement event = (EventElement)packet.getExtension("event", PubSubNamespace.EVENT.getXmlns());
+			
+			if (event == null)
+				return false;
+
+			NodeExtension embedEvent = event.getEvent();
+			
+			if (embedEvent == null)
+				return false;
+			
+			if (embedEvent.getElementName().equals(firstElement))
+			{
+				if (!embedEvent.getNode().equals(getId()))
+					return false;
+				
+				if (secondElement == null)
+					return true;
+				
+				if (embedEvent instanceof EmbeddedPacketExtension)
+				{
+					List<PacketExtension> secondLevelList = ((EmbeddedPacketExtension)embedEvent).getExtensions();
+					
+					if (secondLevelList.size() > 0 && secondLevelList.get(0).getElementName().equals(secondElement))
+						return true;
+				}
+			}
+			return false;
+		}
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/NodeEvent.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/NodeEvent.java
index 1392e85..d55e218 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/NodeEvent.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/NodeEvent.java
@@ -17,19 +17,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jivesoftware.smackx.pubsub;
-
-abstract public class NodeEvent
-{
-	private String nodeId;
-	
-	protected NodeEvent(String id)
-	{
-		nodeId = id;
-	}
-	
-	public String getNodeId()
-	{
-		return nodeId;
-	}
-}
+package org.jivesoftware.smackx.pubsub;
+
+abstract public class NodeEvent
+{
+	private String nodeId;
+	
+	protected NodeEvent(String id)
+	{
+		nodeId = id;
+	}
+	
+	public String getNodeId()
+	{
+		return nodeId;
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/NodeExtension.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/NodeExtension.java
index 7e4cdec..9a3e480 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/NodeExtension.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/NodeExtension.java
@@ -1,85 +1,85 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-
-/**
- * A class which represents a common element within the pubsub defined
- * schemas.  One which has a <b>node</b> as an attribute.  This class is 
- * used on its own as well as a base class for many others, since the 
- * node is a central concept to most pubsub functionality.
- * 
- * @author Robin Collier
- */
-public class NodeExtension implements PacketExtension
-{
-	private PubSubElementType element;
-	private String node;
-	
-	/**
-	 * Constructs a <tt>NodeExtension</tt> with an element name specified
-	 * by {@link PubSubElementType} and the specified node id.
-	 * 
-	 * @param elem Defines the element name and namespace
-	 * @param nodeId Specifies the id of the node
-	 */
-	public NodeExtension(PubSubElementType elem, String nodeId)
-	{
-		element = elem;
-		this.node = nodeId;
-	}
-
-	/**
-	 * Constructs a <tt>NodeExtension</tt> with an element name specified
-	 * by {@link PubSubElementType}.
-	 * 
-	 * @param elem Defines the element name and namespace
-	 */
-	public NodeExtension(PubSubElementType elem)
-	{
-		this(elem, null);
-	}
-
-	/**
-	 * Gets the node id
-	 * 
-	 * @return The node id
-	 */
-	public String getNode()
-	{
-		return node;
-	}
-	
-	public String getElementName()
-	{
-		return element.getElementName();
-	}
-
-	public String getNamespace()
-	{
-		return element.getNamespace().getXmlns();
-	}
-
-	public String toXML()
-	{
-		return '<' + getElementName() + (node == null ? "" : " node='" + node + '\'') + "/>";
-	}
-
-	@Override
-	public String toString()
-	{
-		return getClass().getName() + " - content [" + toXML() + "]";
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+
+/**
+ * A class which represents a common element within the pubsub defined
+ * schemas.  One which has a <b>node</b> as an attribute.  This class is 
+ * used on its own as well as a base class for many others, since the 
+ * node is a central concept to most pubsub functionality.
+ * 
+ * @author Robin Collier
+ */
+public class NodeExtension implements PacketExtension
+{
+	private PubSubElementType element;
+	private String node;
+	
+	/**
+	 * Constructs a <tt>NodeExtension</tt> with an element name specified
+	 * by {@link PubSubElementType} and the specified node id.
+	 * 
+	 * @param elem Defines the element name and namespace
+	 * @param nodeId Specifies the id of the node
+	 */
+	public NodeExtension(PubSubElementType elem, String nodeId)
+	{
+		element = elem;
+		this.node = nodeId;
+	}
+
+	/**
+	 * Constructs a <tt>NodeExtension</tt> with an element name specified
+	 * by {@link PubSubElementType}.
+	 * 
+	 * @param elem Defines the element name and namespace
+	 */
+	public NodeExtension(PubSubElementType elem)
+	{
+		this(elem, null);
+	}
+
+	/**
+	 * Gets the node id
+	 * 
+	 * @return The node id
+	 */
+	public String getNode()
+	{
+		return node;
+	}
+	
+	public String getElementName()
+	{
+		return element.getElementName();
+	}
+
+	public String getNamespace()
+	{
+		return element.getNamespace().getXmlns();
+	}
+
+	public String toXML()
+	{
+		return '<' + getElementName() + (node == null ? "" : " node='" + node + '\'') + "/>";
+	}
+
+	@Override
+	public String toString()
+	{
+		return getClass().getName() + " - content [" + toXML() + "]";
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/NodeType.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/NodeType.java
index 5ee5a05..5d0eb69 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/NodeType.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/NodeType.java
@@ -1,25 +1,25 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-/**
- * Defines the available types of nodes
- * 
- * @author Robin Collier
- */
-public enum NodeType
-{
-	leaf,
-	collection;
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+/**
+ * Defines the available types of nodes
+ * 
+ * @author Robin Collier
+ */
+public enum NodeType
+{
+	leaf,
+	collection;
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/OptionsExtension.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/OptionsExtension.java
index 32c0331..f8775d8 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/OptionsExtension.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/OptionsExtension.java
@@ -1,72 +1,72 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import org.jivesoftware.smackx.pubsub.util.XmlUtils;
-
-/**
- * A packet extension representing the <b>options</b> element. 
- * 
- * @author Robin Collier
- */
-public class OptionsExtension extends NodeExtension
-{
-	protected String jid;
-	protected String id;
-	
-	public OptionsExtension(String subscriptionJid)
-	{
-		this(subscriptionJid, null, null);
-	}
-	
-	public OptionsExtension(String subscriptionJid, String nodeId)
-	{
-		this(subscriptionJid, nodeId, null);
-	}
-	
-	public OptionsExtension(String jid, String nodeId, String subscriptionId)
-	{
-		super(PubSubElementType.OPTIONS, nodeId);
-		this.jid = jid;
-		id = subscriptionId;
-	}
-	
-	public String getJid()
-	{
-		return jid;
-	}
-	
-	public String getId()
-	{
-		return id;
-	}
-	
-	@Override
-	public String toXML()
-	{
-		StringBuilder builder = new StringBuilder("<");
-		builder.append(getElementName());
-		XmlUtils.appendAttribute(builder, "jid", jid);
-		
-		if (getNode() != null)
-			XmlUtils.appendAttribute(builder, "node", getNode());
-		
-		if (id != null)
-			XmlUtils.appendAttribute(builder, "subid", id);
-		
-		builder.append("/>");
-		return builder.toString();
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import org.jivesoftware.smackx.pubsub.util.XmlUtils;
+
+/**
+ * A packet extension representing the <b>options</b> element. 
+ * 
+ * @author Robin Collier
+ */
+public class OptionsExtension extends NodeExtension
+{
+	protected String jid;
+	protected String id;
+	
+	public OptionsExtension(String subscriptionJid)
+	{
+		this(subscriptionJid, null, null);
+	}
+	
+	public OptionsExtension(String subscriptionJid, String nodeId)
+	{
+		this(subscriptionJid, nodeId, null);
+	}
+	
+	public OptionsExtension(String jid, String nodeId, String subscriptionId)
+	{
+		super(PubSubElementType.OPTIONS, nodeId);
+		this.jid = jid;
+		id = subscriptionId;
+	}
+	
+	public String getJid()
+	{
+		return jid;
+	}
+	
+	public String getId()
+	{
+		return id;
+	}
+	
+	@Override
+	public String toXML()
+	{
+		StringBuilder builder = new StringBuilder("<");
+		builder.append(getElementName());
+		XmlUtils.appendAttribute(builder, "jid", jid);
+		
+		if (getNode() != null)
+			XmlUtils.appendAttribute(builder, "node", getNode());
+		
+		if (id != null)
+			XmlUtils.appendAttribute(builder, "subid", id);
+		
+		builder.append("/>");
+		return builder.toString();
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PayloadItem.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PayloadItem.java
index e9497c5..a6e6365 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PayloadItem.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PayloadItem.java
@@ -1,138 +1,138 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import org.jivesoftware.smack.packet.Message;
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smackx.pubsub.provider.ItemProvider;
-
-/**
- * This class represents an item that has been, or will be published to a
- * pubsub node.  An <tt>Item</tt> has several properties that are dependent
- * on the configuration of the node to which it has been or will be published.
- * 
- * <h1>An Item received from a node (via {@link LeafNode#getItems()} or {@link LeafNode#addItemEventListener(org.jivesoftware.smackx.pubsub.listener.ItemEventListener)}</b>
- * <li>Will always have an id (either user or server generated) unless node configuration has both
- * {@link ConfigureForm#isPersistItems()} and {@link ConfigureForm#isDeliverPayloads()}set to false.
- * <li>Will have a payload if the node configuration has {@link ConfigureForm#isDeliverPayloads()} set 
- * to true, otherwise it will be null.
- * 
- * <h1>An Item created to send to a node (via {@link LeafNode#send()} or {@link LeafNode#publish()}</b>
- * <li>The id is optional, since the server will generate one if necessary, but should be used if it is 
- * meaningful in the context of the node.  This value must be unique within the node that it is sent to, since
- * resending an item with the same id will overwrite the one that already exists if the items are persisted.
- * <li>Will require payload if the node configuration has {@link ConfigureForm#isDeliverPayloads()} set
- * to true. 
- * 
- * <p>To customise the payload object being returned from the {@link #getPayload()} method, you can
- * add a custom parser as explained in {@link ItemProvider}.
- * 
- * @author Robin Collier
- */
-public class PayloadItem<E extends PacketExtension> extends Item
-{
-	private E payload;
-	
-	/**
-	 * Create an <tt>Item</tt> with no id and a payload  The id will be set by the server.  
-	 * 
-	 * @param payloadExt A {@link PacketExtension} which represents the payload data.
-	 */
-	public PayloadItem(E payloadExt)
-	{
-		super();
-		
-		if (payloadExt == null)
-			throw new IllegalArgumentException("payload cannot be 'null'");
-		payload = payloadExt;
-	}
-
-	/**
-	 * Create an <tt>Item</tt> with an id and payload.  
-	 * 
-	 * @param itemId The id of this item.  It can be null if we want the server to set the id.
-	 * @param payloadExt A {@link PacketExtension} which represents the payload data.
-	 */
-	public PayloadItem(String itemId, E payloadExt)
-	{
-		super(itemId);
-		
-		if (payloadExt == null)
-			throw new IllegalArgumentException("payload cannot be 'null'");
-		payload = payloadExt;
-	}
-	
-	/**
-	 * Create an <tt>Item</tt> with an id, node id and payload.  
-	 * 
-	 * <p>
-	 * <b>Note:</b> This is not valid for publishing an item to a node, only receiving from 
-	 * one as part of {@link Message}.  If used to create an Item to publish 
-	 * (via {@link LeafNode#publish(Item)}, the server <i>may</i> return an
-	 * error for an invalid packet.
-	 * 
-	 * @param itemId The id of this item.
-	 * @param nodeId The id of the node the item was published to.
-	 * @param payloadExt A {@link PacketExtension} which represents the payload data.
-	 */
-	public PayloadItem(String itemId, String nodeId, E payloadExt)
-	{
-		super(itemId, nodeId);
-		
-		if (payloadExt == null)
-			throw new IllegalArgumentException("payload cannot be 'null'");
-		payload = payloadExt;
-	}
-	
-	/**
-	 * Get the payload associated with this <tt>Item</tt>.  Customising the payload
-	 * parsing from the server can be accomplished as described in {@link ItemProvider}.
-	 * 
-	 * @return The payload as a {@link PacketExtension}.
-	 */
-	public E getPayload()
-	{
-		return payload;
-	}
-	
-	@Override
-	public String toXML()
-	{
-		StringBuilder builder = new StringBuilder("<item");
-		
-		if (getId() != null)
-		{
-			builder.append(" id='");
-			builder.append(getId());
-			builder.append("'");
-		}
-		
-        if (getNode() != null) {
-            builder.append(" node='");
-            builder.append(getNode());
-            builder.append("'");
-        }
-		builder.append(">");
-		builder.append(payload.toXML());
-		builder.append("</item>");
-		
-		return builder.toString();
-	}
-
-	@Override
-	public String toString()
-	{
-		return getClass().getName() + " | Content [" + toXML() + "]";
-	}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import org.jivesoftware.smack.packet.Message;
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smackx.pubsub.provider.ItemProvider;
+
+/**
+ * This class represents an item that has been, or will be published to a
+ * pubsub node.  An <tt>Item</tt> has several properties that are dependent
+ * on the configuration of the node to which it has been or will be published.
+ * 
+ * <h1>An Item received from a node (via {@link LeafNode#getItems()} or {@link LeafNode#addItemEventListener(org.jivesoftware.smackx.pubsub.listener.ItemEventListener)}</b>
+ * <li>Will always have an id (either user or server generated) unless node configuration has both
+ * {@link ConfigureForm#isPersistItems()} and {@link ConfigureForm#isDeliverPayloads()}set to false.
+ * <li>Will have a payload if the node configuration has {@link ConfigureForm#isDeliverPayloads()} set 
+ * to true, otherwise it will be null.
+ * 
+ * <h1>An Item created to send to a node (via {@link LeafNode#send()} or {@link LeafNode#publish()}</b>
+ * <li>The id is optional, since the server will generate one if necessary, but should be used if it is 
+ * meaningful in the context of the node.  This value must be unique within the node that it is sent to, since
+ * resending an item with the same id will overwrite the one that already exists if the items are persisted.
+ * <li>Will require payload if the node configuration has {@link ConfigureForm#isDeliverPayloads()} set
+ * to true. 
+ * 
+ * <p>To customise the payload object being returned from the {@link #getPayload()} method, you can
+ * add a custom parser as explained in {@link ItemProvider}.
+ * 
+ * @author Robin Collier
+ */
+public class PayloadItem<E extends PacketExtension> extends Item
+{
+	private E payload;
+	
+	/**
+	 * Create an <tt>Item</tt> with no id and a payload  The id will be set by the server.  
+	 * 
+	 * @param payloadExt A {@link PacketExtension} which represents the payload data.
+	 */
+	public PayloadItem(E payloadExt)
+	{
+		super();
+		
+		if (payloadExt == null)
+			throw new IllegalArgumentException("payload cannot be 'null'");
+		payload = payloadExt;
+	}
+
+	/**
+	 * Create an <tt>Item</tt> with an id and payload.  
+	 * 
+	 * @param itemId The id of this item.  It can be null if we want the server to set the id.
+	 * @param payloadExt A {@link PacketExtension} which represents the payload data.
+	 */
+	public PayloadItem(String itemId, E payloadExt)
+	{
+		super(itemId);
+		
+		if (payloadExt == null)
+			throw new IllegalArgumentException("payload cannot be 'null'");
+		payload = payloadExt;
+	}
+	
+	/**
+	 * Create an <tt>Item</tt> with an id, node id and payload.  
+	 * 
+	 * <p>
+	 * <b>Note:</b> This is not valid for publishing an item to a node, only receiving from 
+	 * one as part of {@link Message}.  If used to create an Item to publish 
+	 * (via {@link LeafNode#publish(Item)}, the server <i>may</i> return an
+	 * error for an invalid packet.
+	 * 
+	 * @param itemId The id of this item.
+	 * @param nodeId The id of the node the item was published to.
+	 * @param payloadExt A {@link PacketExtension} which represents the payload data.
+	 */
+	public PayloadItem(String itemId, String nodeId, E payloadExt)
+	{
+		super(itemId, nodeId);
+		
+		if (payloadExt == null)
+			throw new IllegalArgumentException("payload cannot be 'null'");
+		payload = payloadExt;
+	}
+	
+	/**
+	 * Get the payload associated with this <tt>Item</tt>.  Customising the payload
+	 * parsing from the server can be accomplished as described in {@link ItemProvider}.
+	 * 
+	 * @return The payload as a {@link PacketExtension}.
+	 */
+	public E getPayload()
+	{
+		return payload;
+	}
+	
+	@Override
+	public String toXML()
+	{
+		StringBuilder builder = new StringBuilder("<item");
+		
+		if (getId() != null)
+		{
+			builder.append(" id='");
+			builder.append(getId());
+			builder.append("'");
+		}
+		
+        if (getNode() != null) {
+            builder.append(" node='");
+            builder.append(getNode());
+            builder.append("'");
+        }
+		builder.append(">");
+		builder.append(payload.toXML());
+		builder.append("</item>");
+		
+		return builder.toString();
+	}
+
+	@Override
+	public String toString()
+	{
+		return getClass().getName() + " | Content [" + toXML() + "]";
+	}
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PresenceState.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PresenceState.java
index 0612fc2..07342e2 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PresenceState.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PresenceState.java
@@ -1,25 +1,25 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-/** 
- * Defines the possible valid presence states for node subscription via
- * {@link SubscribeForm#getShowValues()}.
- * 
- * @author Robin Collier
- */
-public enum PresenceState
-{
-	chat, online, away, xa, dnd
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+/** 
+ * Defines the possible valid presence states for node subscription via
+ * {@link SubscribeForm#getShowValues()}.
+ * 
+ * @author Robin Collier
+ */
+public enum PresenceState
+{
+	chat, online, away, xa, dnd
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PubSubElementType.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PubSubElementType.java
index a887ca2..ff762e9 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PubSubElementType.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PubSubElementType.java
@@ -1,80 +1,80 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
-
-/**
- * Defines all the possible element types as defined for all the pubsub
- * schemas in all 3 namespaces.
- * 
- * @author Robin Collier
- */
-public enum PubSubElementType
-{
-	CREATE("create", PubSubNamespace.BASIC),
-	DELETE("delete", PubSubNamespace.OWNER),
-	DELETE_EVENT("delete", PubSubNamespace.EVENT),
-	CONFIGURE("configure", PubSubNamespace.BASIC),
-	CONFIGURE_OWNER("configure", PubSubNamespace.OWNER),
-	CONFIGURATION("configuration", PubSubNamespace.EVENT),
-	OPTIONS("options", PubSubNamespace.BASIC),
-	DEFAULT("default", PubSubNamespace.OWNER),	
-	ITEMS("items", PubSubNamespace.BASIC),
-	ITEMS_EVENT("items", PubSubNamespace.EVENT),
-	ITEM("item", PubSubNamespace.BASIC),
-	ITEM_EVENT("item", PubSubNamespace.EVENT),
-	PUBLISH("publish", PubSubNamespace.BASIC),
-	PUBLISH_OPTIONS("publish-options", PubSubNamespace.BASIC), 
-	PURGE_OWNER("purge", PubSubNamespace.OWNER),
-	PURGE_EVENT("purge", PubSubNamespace.EVENT),
-	RETRACT("retract", PubSubNamespace.BASIC), 
-	AFFILIATIONS("affiliations", PubSubNamespace.BASIC), 
-	SUBSCRIBE("subscribe", PubSubNamespace.BASIC), 
-	SUBSCRIPTION("subscription", PubSubNamespace.BASIC),
-	SUBSCRIPTIONS("subscriptions", PubSubNamespace.BASIC), 
-	UNSUBSCRIBE("unsubscribe", PubSubNamespace.BASIC);
-
-	private String eName;
-	private PubSubNamespace nSpace;
-	
-	private PubSubElementType(String elemName, PubSubNamespace ns)
-	{
-		eName = elemName;
-		nSpace = ns;
-	}
-	
-	public PubSubNamespace getNamespace()
-	{
-		return nSpace;
-	}
-	
-	public String getElementName()
-	{
-		return eName;
-	}
-	
-	public static PubSubElementType valueOfFromElemName(String elemName, String namespace)
-	{
-		int index = namespace.lastIndexOf('#');
-		String fragment = (index == -1 ? null : namespace.substring(index+1));
-		
-		if (fragment != null)
-		{
-			return valueOf((elemName + '_' + fragment).toUpperCase());
-		}
-		return valueOf(elemName.toUpperCase().replace('-', '_'));
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
+
+/**
+ * Defines all the possible element types as defined for all the pubsub
+ * schemas in all 3 namespaces.
+ * 
+ * @author Robin Collier
+ */
+public enum PubSubElementType
+{
+	CREATE("create", PubSubNamespace.BASIC),
+	DELETE("delete", PubSubNamespace.OWNER),
+	DELETE_EVENT("delete", PubSubNamespace.EVENT),
+	CONFIGURE("configure", PubSubNamespace.BASIC),
+	CONFIGURE_OWNER("configure", PubSubNamespace.OWNER),
+	CONFIGURATION("configuration", PubSubNamespace.EVENT),
+	OPTIONS("options", PubSubNamespace.BASIC),
+	DEFAULT("default", PubSubNamespace.OWNER),	
+	ITEMS("items", PubSubNamespace.BASIC),
+	ITEMS_EVENT("items", PubSubNamespace.EVENT),
+	ITEM("item", PubSubNamespace.BASIC),
+	ITEM_EVENT("item", PubSubNamespace.EVENT),
+	PUBLISH("publish", PubSubNamespace.BASIC),
+	PUBLISH_OPTIONS("publish-options", PubSubNamespace.BASIC), 
+	PURGE_OWNER("purge", PubSubNamespace.OWNER),
+	PURGE_EVENT("purge", PubSubNamespace.EVENT),
+	RETRACT("retract", PubSubNamespace.BASIC), 
+	AFFILIATIONS("affiliations", PubSubNamespace.BASIC), 
+	SUBSCRIBE("subscribe", PubSubNamespace.BASIC), 
+	SUBSCRIPTION("subscription", PubSubNamespace.BASIC),
+	SUBSCRIPTIONS("subscriptions", PubSubNamespace.BASIC), 
+	UNSUBSCRIBE("unsubscribe", PubSubNamespace.BASIC);
+
+	private String eName;
+	private PubSubNamespace nSpace;
+	
+	private PubSubElementType(String elemName, PubSubNamespace ns)
+	{
+		eName = elemName;
+		nSpace = ns;
+	}
+	
+	public PubSubNamespace getNamespace()
+	{
+		return nSpace;
+	}
+	
+	public String getElementName()
+	{
+		return eName;
+	}
+	
+	public static PubSubElementType valueOfFromElemName(String elemName, String namespace)
+	{
+		int index = namespace.lastIndexOf('#');
+		String fragment = (index == -1 ? null : namespace.substring(index+1));
+		
+		if (fragment != null)
+		{
+			return valueOf((elemName + '_' + fragment).toUpperCase());
+		}
+		return valueOf(elemName.toUpperCase().replace('-', '_'));
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PubSubManager.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PubSubManager.java
index 4fb0158..483f6f2 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PubSubManager.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PubSubManager.java
@@ -1,329 +1,329 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.packet.IQ.Type;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smackx.Form;
-import org.jivesoftware.smackx.FormField;
-import org.jivesoftware.smackx.ServiceDiscoveryManager;
-import org.jivesoftware.smackx.packet.DiscoverInfo;
-import org.jivesoftware.smackx.packet.DiscoverItems;
-import org.jivesoftware.smackx.pubsub.packet.PubSub;
-import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
-import org.jivesoftware.smackx.pubsub.packet.SyncPacketSend;
-import org.jivesoftware.smackx.pubsub.util.NodeUtils;
-
-/**
- * This is the starting point for access to the pubsub service.  It
- * will provide access to general information about the service, as
- * well as create or retrieve pubsub {@link LeafNode} instances.  These 
- * instances provide the bulk of the functionality as defined in the 
- * pubsub specification <a href="http://xmpp.org/extensions/xep-0060.html">XEP-0060</a>.
- * 
- * @author Robin Collier
- */
-final public class PubSubManager
-{
-	private Connection con;
-	private String to;
-	private Map<String, Node> nodeMap = new ConcurrentHashMap<String, Node>();
-	
-	/**
-	 * Create a pubsub manager associated to the specified connection.  Defaults the service
-	 * name to <i>pubsub</i>
-	 * 
-	 * @param connection The XMPP connection
-	 */
-	public PubSubManager(Connection connection)
-	{
-		con = connection;
-		to = "pubsub." + connection.getServiceName();
-	}
-	
-	/**
-	 * Create a pubsub manager associated to the specified connection where
-	 * the pubsub requests require a specific to address for packets.
-	 * 
-	 * @param connection The XMPP connection
-	 * @param toAddress The pubsub specific to address (required for some servers)
-	 */
-	public PubSubManager(Connection connection, String toAddress)
-	{
-		con = connection;
-		to = toAddress;
-	}
-	
-	/**
-	 * Creates an instant node, if supported.
-	 * 
-	 * @return The node that was created
-	 * @exception XMPPException
-	 */
-	public LeafNode createNode()
-		throws XMPPException
-	{
-		PubSub reply = (PubSub)sendPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.CREATE));
-		NodeExtension elem = (NodeExtension)reply.getExtension("create", PubSubNamespace.BASIC.getXmlns());
-		
-		LeafNode newNode = new LeafNode(con, elem.getNode());
-		newNode.setTo(to);
-		nodeMap.put(newNode.getId(), newNode);
-		
-		return newNode;
-	}
-	
-	/**
-	 * Creates a node with default configuration.
-	 * 
-	 * @param id The id of the node, which must be unique within the 
-	 * pubsub service
-	 * @return The node that was created
-	 * @exception XMPPException
-	 */
-	public LeafNode createNode(String id)
-		throws XMPPException
-	{
-		return (LeafNode)createNode(id, null);
-	}
-	
-	/**
-	 * Creates a node with specified configuration.
-	 * 
-	 * Note: This is the only way to create a collection node.
-	 * 
-	 * @param name The name of the node, which must be unique within the 
-	 * pubsub service
-	 * @param config The configuration for the node
-	 * @return The node that was created
-	 * @exception XMPPException
-	 */
-	public Node createNode(String name, Form config)
-		throws XMPPException
-	{
-		PubSub request = createPubsubPacket(to, Type.SET, new NodeExtension(PubSubElementType.CREATE, name));
-		boolean isLeafNode = true;
-		
-		if (config != null)
-		{
-			request.addExtension(new FormNode(FormNodeType.CONFIGURE, config));
-			FormField nodeTypeField = config.getField(ConfigureNodeFields.node_type.getFieldName());
-			
-			if (nodeTypeField != null)
-				isLeafNode = nodeTypeField.getValues().next().equals(NodeType.leaf.toString());
-		}
-
-		// Errors will cause exceptions in getReply, so it only returns
-		// on success.
-		sendPubsubPacket(con, to, Type.SET, request);
-		Node newNode = isLeafNode ? new LeafNode(con, name) : new CollectionNode(con, name);
-		newNode.setTo(to);
-		nodeMap.put(newNode.getId(), newNode);
-		
-		return newNode;
-	}
-
-	/**
-	 * Retrieves the requested node, if it exists.  It will throw an 
-	 * exception if it does not.
-	 * 
-	 * @param id - The unique id of the node
-	 * @return the node
-	 * @throws XMPPException The node does not exist
-	 */
-	public <T extends Node> T getNode(String id)
-		throws XMPPException
-	{
-		Node node = nodeMap.get(id);
-		
-		if (node == null)
-		{
-			DiscoverInfo info = new DiscoverInfo();
-			info.setTo(to);
-			info.setNode(id);
-			
-			DiscoverInfo infoReply = (DiscoverInfo)SyncPacketSend.getReply(con, info);
-			
-			if (infoReply.getIdentities().next().getType().equals(NodeType.leaf.toString()))
-				node = new LeafNode(con, id);
-			else
-				node = new CollectionNode(con, id);
-			node.setTo(to);
-			nodeMap.put(id, node);
-		}
-		return (T) node;
-	}
-	
-	/**
-	 * Get all the nodes that currently exist as a child of the specified
-	 * collection node.  If the service does not support collection nodes
-	 * then all nodes will be returned.
-	 * 
-	 * To retrieve contents of the root collection node (if it exists), 
-	 * or there is no root collection node, pass null as the nodeId.
-	 * 
-	 * @param nodeId - The id of the collection node for which the child 
-	 * nodes will be returned.  
-	 * @return {@link DiscoverItems} representing the existing nodes
-	 * 
-	 * @throws XMPPException
-	 */
-	public DiscoverItems discoverNodes(String nodeId)
-		throws XMPPException
-	{
-		DiscoverItems items = new DiscoverItems();
-		
-		if (nodeId != null)
-			items.setNode(nodeId);
-		items.setTo(to);
-		DiscoverItems nodeItems = (DiscoverItems)SyncPacketSend.getReply(con, items);
-		return nodeItems;
-	}
-	
-	/**
-	 * Gets the subscriptions on the root node.
-	 * 
-	 * @return List of exceptions
-	 * 
-	 * @throws XMPPException
-	 */
-	public List<Subscription> getSubscriptions()
-		throws XMPPException
-	{
-		Packet reply = sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.SUBSCRIPTIONS));
-		SubscriptionsExtension subElem = (SubscriptionsExtension)reply.getExtension(PubSubElementType.SUBSCRIPTIONS.getElementName(), PubSubElementType.SUBSCRIPTIONS.getNamespace().getXmlns());
-		return subElem.getSubscriptions();
-	}
-	
-	/**
-	 * Gets the affiliations on the root node.
-	 * 
-	 * @return List of affiliations
-	 * 
-	 * @throws XMPPException
-	 */
-	public List<Affiliation> getAffiliations()
-		throws XMPPException
-	{
-		PubSub reply = (PubSub)sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.AFFILIATIONS));
-		AffiliationsExtension listElem = (AffiliationsExtension)reply.getExtension(PubSubElementType.AFFILIATIONS);
-		return listElem.getAffiliations();
-	}
-
-	/**
-	 * Delete the specified node
-	 * 
-	 * @param nodeId
-	 * @throws XMPPException
-	 */
-	public void deleteNode(String nodeId)
-		throws XMPPException
-	{
-		sendPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.DELETE, nodeId), PubSubElementType.DELETE.getNamespace());
-		nodeMap.remove(nodeId);
-	}
-	
-	/**
-	 * Returns the default settings for Node configuration.
-	 * 
-	 * @return configuration form containing the default settings.
-	 */
-	public ConfigureForm getDefaultConfiguration()
-		throws XMPPException
-	{
-		// Errors will cause exceptions in getReply, so it only returns
-		// on success.
-		PubSub reply = (PubSub)sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.DEFAULT), PubSubElementType.DEFAULT.getNamespace());
-		return NodeUtils.getFormFromPacket(reply, PubSubElementType.DEFAULT);
-	}
-	
-	/**
-	 * Gets the supported features of the servers pubsub implementation
-	 * as a standard {@link DiscoverInfo} instance.
-	 * 
-	 * @return The supported features
-	 * 
-	 * @throws XMPPException
-	 */
-	public DiscoverInfo getSupportedFeatures()
-		throws XMPPException
-	{
-		ServiceDiscoveryManager mgr = ServiceDiscoveryManager.getInstanceFor(con);
-		return mgr.discoverInfo(to);
-	}
-	
-	private Packet sendPubsubPacket(Type type, PacketExtension ext, PubSubNamespace ns)
-		throws XMPPException
-	{
-		return sendPubsubPacket(con, to, type, ext, ns);
-	}
-
-	private Packet sendPubsubPacket(Type type, PacketExtension ext)
-		throws XMPPException
-	{
-		return sendPubsubPacket(type, ext, null);
-	}
-
-	static PubSub createPubsubPacket(String to, Type type, PacketExtension ext)
-	{
-		return createPubsubPacket(to, type, ext, null);
-	}
-	
-	static PubSub createPubsubPacket(String to, Type type, PacketExtension ext, PubSubNamespace ns)
-	{
-		PubSub request = new PubSub();
-		request.setTo(to);
-		request.setType(type);
-		
-		if (ns != null)
-		{
-			request.setPubSubNamespace(ns);
-		}
-		request.addExtension(ext);
-		
-		return request;
-	}
-
-	static Packet sendPubsubPacket(Connection con, String to, Type type, PacketExtension ext)
-		throws XMPPException
-	{
-		return sendPubsubPacket(con, to, type, ext, null);
-	}
-	
-	static Packet sendPubsubPacket(Connection con, String to, Type type, PacketExtension ext, PubSubNamespace ns)
-		throws XMPPException
-	{
-		return SyncPacketSend.getReply(con, createPubsubPacket(to, type, ext, ns));
-	}
-
-	static Packet sendPubsubPacket(Connection con, String to, Type type, PubSub packet)
-		throws XMPPException
-	{
-		return sendPubsubPacket(con, to, type, packet, null);
-	}
-
-	static Packet sendPubsubPacket(Connection con, String to, Type type, PubSub packet, PubSubNamespace ns)
-		throws XMPPException
-	{
-		return SyncPacketSend.getReply(con, packet);
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.packet.IQ.Type;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smackx.Form;
+import org.jivesoftware.smackx.FormField;
+import org.jivesoftware.smackx.ServiceDiscoveryManager;
+import org.jivesoftware.smackx.packet.DiscoverInfo;
+import org.jivesoftware.smackx.packet.DiscoverItems;
+import org.jivesoftware.smackx.pubsub.packet.PubSub;
+import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
+import org.jivesoftware.smackx.pubsub.packet.SyncPacketSend;
+import org.jivesoftware.smackx.pubsub.util.NodeUtils;
+
+/**
+ * This is the starting point for access to the pubsub service.  It
+ * will provide access to general information about the service, as
+ * well as create or retrieve pubsub {@link LeafNode} instances.  These 
+ * instances provide the bulk of the functionality as defined in the 
+ * pubsub specification <a href="http://xmpp.org/extensions/xep-0060.html">XEP-0060</a>.
+ * 
+ * @author Robin Collier
+ */
+final public class PubSubManager
+{
+	private Connection con;
+	private String to;
+	private Map<String, Node> nodeMap = new ConcurrentHashMap<String, Node>();
+	
+	/**
+	 * Create a pubsub manager associated to the specified connection.  Defaults the service
+	 * name to <i>pubsub</i>
+	 * 
+	 * @param connection The XMPP connection
+	 */
+	public PubSubManager(Connection connection)
+	{
+		con = connection;
+		to = "pubsub." + connection.getServiceName();
+	}
+	
+	/**
+	 * Create a pubsub manager associated to the specified connection where
+	 * the pubsub requests require a specific to address for packets.
+	 * 
+	 * @param connection The XMPP connection
+	 * @param toAddress The pubsub specific to address (required for some servers)
+	 */
+	public PubSubManager(Connection connection, String toAddress)
+	{
+		con = connection;
+		to = toAddress;
+	}
+	
+	/**
+	 * Creates an instant node, if supported.
+	 * 
+	 * @return The node that was created
+	 * @exception XMPPException
+	 */
+	public LeafNode createNode()
+		throws XMPPException
+	{
+		PubSub reply = (PubSub)sendPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.CREATE));
+		NodeExtension elem = (NodeExtension)reply.getExtension("create", PubSubNamespace.BASIC.getXmlns());
+		
+		LeafNode newNode = new LeafNode(con, elem.getNode());
+		newNode.setTo(to);
+		nodeMap.put(newNode.getId(), newNode);
+		
+		return newNode;
+	}
+	
+	/**
+	 * Creates a node with default configuration.
+	 * 
+	 * @param id The id of the node, which must be unique within the 
+	 * pubsub service
+	 * @return The node that was created
+	 * @exception XMPPException
+	 */
+	public LeafNode createNode(String id)
+		throws XMPPException
+	{
+		return (LeafNode)createNode(id, null);
+	}
+	
+	/**
+	 * Creates a node with specified configuration.
+	 * 
+	 * Note: This is the only way to create a collection node.
+	 * 
+	 * @param name The name of the node, which must be unique within the 
+	 * pubsub service
+	 * @param config The configuration for the node
+	 * @return The node that was created
+	 * @exception XMPPException
+	 */
+	public Node createNode(String name, Form config)
+		throws XMPPException
+	{
+		PubSub request = createPubsubPacket(to, Type.SET, new NodeExtension(PubSubElementType.CREATE, name));
+		boolean isLeafNode = true;
+		
+		if (config != null)
+		{
+			request.addExtension(new FormNode(FormNodeType.CONFIGURE, config));
+			FormField nodeTypeField = config.getField(ConfigureNodeFields.node_type.getFieldName());
+			
+			if (nodeTypeField != null)
+				isLeafNode = nodeTypeField.getValues().next().equals(NodeType.leaf.toString());
+		}
+
+		// Errors will cause exceptions in getReply, so it only returns
+		// on success.
+		sendPubsubPacket(con, to, Type.SET, request);
+		Node newNode = isLeafNode ? new LeafNode(con, name) : new CollectionNode(con, name);
+		newNode.setTo(to);
+		nodeMap.put(newNode.getId(), newNode);
+		
+		return newNode;
+	}
+
+	/**
+	 * Retrieves the requested node, if it exists.  It will throw an 
+	 * exception if it does not.
+	 * 
+	 * @param id - The unique id of the node
+	 * @return the node
+	 * @throws XMPPException The node does not exist
+	 */
+	public <T extends Node> T getNode(String id)
+		throws XMPPException
+	{
+		Node node = nodeMap.get(id);
+		
+		if (node == null)
+		{
+			DiscoverInfo info = new DiscoverInfo();
+			info.setTo(to);
+			info.setNode(id);
+			
+			DiscoverInfo infoReply = (DiscoverInfo)SyncPacketSend.getReply(con, info);
+			
+			if (infoReply.getIdentities().next().getType().equals(NodeType.leaf.toString()))
+				node = new LeafNode(con, id);
+			else
+				node = new CollectionNode(con, id);
+			node.setTo(to);
+			nodeMap.put(id, node);
+		}
+		return (T) node;
+	}
+	
+	/**
+	 * Get all the nodes that currently exist as a child of the specified
+	 * collection node.  If the service does not support collection nodes
+	 * then all nodes will be returned.
+	 * 
+	 * To retrieve contents of the root collection node (if it exists), 
+	 * or there is no root collection node, pass null as the nodeId.
+	 * 
+	 * @param nodeId - The id of the collection node for which the child 
+	 * nodes will be returned.  
+	 * @return {@link DiscoverItems} representing the existing nodes
+	 * 
+	 * @throws XMPPException
+	 */
+	public DiscoverItems discoverNodes(String nodeId)
+		throws XMPPException
+	{
+		DiscoverItems items = new DiscoverItems();
+		
+		if (nodeId != null)
+			items.setNode(nodeId);
+		items.setTo(to);
+		DiscoverItems nodeItems = (DiscoverItems)SyncPacketSend.getReply(con, items);
+		return nodeItems;
+	}
+	
+	/**
+	 * Gets the subscriptions on the root node.
+	 * 
+	 * @return List of exceptions
+	 * 
+	 * @throws XMPPException
+	 */
+	public List<Subscription> getSubscriptions()
+		throws XMPPException
+	{
+		Packet reply = sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.SUBSCRIPTIONS));
+		SubscriptionsExtension subElem = (SubscriptionsExtension)reply.getExtension(PubSubElementType.SUBSCRIPTIONS.getElementName(), PubSubElementType.SUBSCRIPTIONS.getNamespace().getXmlns());
+		return subElem.getSubscriptions();
+	}
+	
+	/**
+	 * Gets the affiliations on the root node.
+	 * 
+	 * @return List of affiliations
+	 * 
+	 * @throws XMPPException
+	 */
+	public List<Affiliation> getAffiliations()
+		throws XMPPException
+	{
+		PubSub reply = (PubSub)sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.AFFILIATIONS));
+		AffiliationsExtension listElem = (AffiliationsExtension)reply.getExtension(PubSubElementType.AFFILIATIONS);
+		return listElem.getAffiliations();
+	}
+
+	/**
+	 * Delete the specified node
+	 * 
+	 * @param nodeId
+	 * @throws XMPPException
+	 */
+	public void deleteNode(String nodeId)
+		throws XMPPException
+	{
+		sendPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.DELETE, nodeId), PubSubElementType.DELETE.getNamespace());
+		nodeMap.remove(nodeId);
+	}
+	
+	/**
+	 * Returns the default settings for Node configuration.
+	 * 
+	 * @return configuration form containing the default settings.
+	 */
+	public ConfigureForm getDefaultConfiguration()
+		throws XMPPException
+	{
+		// Errors will cause exceptions in getReply, so it only returns
+		// on success.
+		PubSub reply = (PubSub)sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.DEFAULT), PubSubElementType.DEFAULT.getNamespace());
+		return NodeUtils.getFormFromPacket(reply, PubSubElementType.DEFAULT);
+	}
+	
+	/**
+	 * Gets the supported features of the servers pubsub implementation
+	 * as a standard {@link DiscoverInfo} instance.
+	 * 
+	 * @return The supported features
+	 * 
+	 * @throws XMPPException
+	 */
+	public DiscoverInfo getSupportedFeatures()
+		throws XMPPException
+	{
+		ServiceDiscoveryManager mgr = ServiceDiscoveryManager.getInstanceFor(con);
+		return mgr.discoverInfo(to);
+	}
+	
+	private Packet sendPubsubPacket(Type type, PacketExtension ext, PubSubNamespace ns)
+		throws XMPPException
+	{
+		return sendPubsubPacket(con, to, type, ext, ns);
+	}
+
+	private Packet sendPubsubPacket(Type type, PacketExtension ext)
+		throws XMPPException
+	{
+		return sendPubsubPacket(type, ext, null);
+	}
+
+	static PubSub createPubsubPacket(String to, Type type, PacketExtension ext)
+	{
+		return createPubsubPacket(to, type, ext, null);
+	}
+	
+	static PubSub createPubsubPacket(String to, Type type, PacketExtension ext, PubSubNamespace ns)
+	{
+		PubSub request = new PubSub();
+		request.setTo(to);
+		request.setType(type);
+		
+		if (ns != null)
+		{
+			request.setPubSubNamespace(ns);
+		}
+		request.addExtension(ext);
+		
+		return request;
+	}
+
+	static Packet sendPubsubPacket(Connection con, String to, Type type, PacketExtension ext)
+		throws XMPPException
+	{
+		return sendPubsubPacket(con, to, type, ext, null);
+	}
+	
+	static Packet sendPubsubPacket(Connection con, String to, Type type, PacketExtension ext, PubSubNamespace ns)
+		throws XMPPException
+	{
+		return SyncPacketSend.getReply(con, createPubsubPacket(to, type, ext, ns));
+	}
+
+	static Packet sendPubsubPacket(Connection con, String to, Type type, PubSub packet)
+		throws XMPPException
+	{
+		return sendPubsubPacket(con, to, type, packet, null);
+	}
+
+	static Packet sendPubsubPacket(Connection con, String to, Type type, PubSub packet, PubSubNamespace ns)
+		throws XMPPException
+	{
+		return SyncPacketSend.getReply(con, packet);
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PublishItem.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PublishItem.java
index ffbd705..15282ea 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PublishItem.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PublishItem.java
@@ -1,70 +1,70 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Represents a request to publish an item(s) to a specific node.
- * 
- * @author Robin Collier
- */
-public class PublishItem <T extends Item> extends NodeExtension
-{
-	protected Collection<T> items;
-	
-	/**
-	 * Construct a request to publish an item to a node.
-	 * 
-	 * @param nodeId The node to publish to
-	 * @param toPublish The {@link Item} to publish
-	 */
-	public PublishItem(String nodeId, T toPublish)
-	{
-		super(PubSubElementType.PUBLISH, nodeId);
-		items = new ArrayList<T>(1);
-		items.add(toPublish);
-	}
-
-	/**
-	 * Construct a request to publish multiple items to a node.
-	 * 
-	 * @param nodeId The node to publish to
-	 * @param toPublish The list of {@link Item} to publish
-	 */
-	public PublishItem(String nodeId, Collection<T> toPublish)
-	{
-		super(PubSubElementType.PUBLISH, nodeId);
-		items = toPublish;
-	}
-
-	@Override
-	public String toXML()
-	{
-		StringBuilder builder = new StringBuilder("<");
-		builder.append(getElementName());
-		builder.append(" node='");
-		builder.append(getNode());
-		builder.append("'>");
-		
-		for (Item item : items)
-		{
-			builder.append(item.toXML());
-		}
-		builder.append("</publish>");
-		
-		return builder.toString();
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Represents a request to publish an item(s) to a specific node.
+ * 
+ * @author Robin Collier
+ */
+public class PublishItem <T extends Item> extends NodeExtension
+{
+	protected Collection<T> items;
+	
+	/**
+	 * Construct a request to publish an item to a node.
+	 * 
+	 * @param nodeId The node to publish to
+	 * @param toPublish The {@link Item} to publish
+	 */
+	public PublishItem(String nodeId, T toPublish)
+	{
+		super(PubSubElementType.PUBLISH, nodeId);
+		items = new ArrayList<T>(1);
+		items.add(toPublish);
+	}
+
+	/**
+	 * Construct a request to publish multiple items to a node.
+	 * 
+	 * @param nodeId The node to publish to
+	 * @param toPublish The list of {@link Item} to publish
+	 */
+	public PublishItem(String nodeId, Collection<T> toPublish)
+	{
+		super(PubSubElementType.PUBLISH, nodeId);
+		items = toPublish;
+	}
+
+	@Override
+	public String toXML()
+	{
+		StringBuilder builder = new StringBuilder("<");
+		builder.append(getElementName());
+		builder.append(" node='");
+		builder.append(getNode());
+		builder.append("'>");
+		
+		for (Item item : items)
+		{
+			builder.append(item.toXML());
+		}
+		builder.append("</publish>");
+		
+		return builder.toString();
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PublishModel.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PublishModel.java
index 4b5a851..b94d50f 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PublishModel.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/PublishModel.java
@@ -1,32 +1,32 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-/**
- * Determines who may publish to a node.  Denotes possible values 
- * for {@link ConfigureForm#setPublishModel(PublishModel)}.
- * 
- * @author Robin Collier
- */
-public enum PublishModel
-{
-	/** Only publishers may publish */
-	publishers,
-	
-	/** Only subscribers may publish */
-	subscribers,
-	
-	/** Anyone may publish */
-	open;
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+/**
+ * Determines who may publish to a node.  Denotes possible values 
+ * for {@link ConfigureForm#setPublishModel(PublishModel)}.
+ * 
+ * @author Robin Collier
+ */
+public enum PublishModel
+{
+	/** Only publishers may publish */
+	publishers,
+	
+	/** Only subscribers may publish */
+	subscribers,
+	
+	/** Anyone may publish */
+	open;
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/RetractItem.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/RetractItem.java
index 97db5cc..1e6cc49 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/RetractItem.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/RetractItem.java
@@ -1,59 +1,59 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
-
-/**
- * Represents and item that has been deleted from a node.
- * 
- * @author Robin Collier
- */
-public class RetractItem implements PacketExtension
-{
-	private String id;
-
-	/**
-	 * Construct a <tt>RetractItem</tt> with the specified id.
-	 * 
-	 * @param itemId The id if the item deleted
-	 */
-	public RetractItem(String itemId)
-	{
-		if (itemId == null)
-			throw new IllegalArgumentException("itemId must not be 'null'");
-		id = itemId;
-	}
-	
-	public String getId()
-	{
-		return id;
-	}
-
-	public String getElementName()
-	{
-		return "retract";
-	}
-
-	public String getNamespace()
-	{
-		return PubSubNamespace.EVENT.getXmlns();
-	}
-
-	public String toXML()
-	{
-		return "<retract id='" + id + "'/>";
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
+
+/**
+ * Represents and item that has been deleted from a node.
+ * 
+ * @author Robin Collier
+ */
+public class RetractItem implements PacketExtension
+{
+	private String id;
+
+	/**
+	 * Construct a <tt>RetractItem</tt> with the specified id.
+	 * 
+	 * @param itemId The id if the item deleted
+	 */
+	public RetractItem(String itemId)
+	{
+		if (itemId == null)
+			throw new IllegalArgumentException("itemId must not be 'null'");
+		id = itemId;
+	}
+	
+	public String getId()
+	{
+		return id;
+	}
+
+	public String getElementName()
+	{
+		return "retract";
+	}
+
+	public String getNamespace()
+	{
+		return PubSubNamespace.EVENT.getXmlns();
+	}
+
+	public String toXML()
+	{
+		return "<retract id='" + id + "'/>";
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SimplePayload.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SimplePayload.java
index 9d114b0..644c1f3 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SimplePayload.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SimplePayload.java
@@ -1,65 +1,65 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-
-/**
- * The default payload representation for {@link Item#getPayload()}.  It simply 
- * stores the XML payload as a string.
- *  
- * @author Robin Collier
- */
-public class SimplePayload implements PacketExtension
-{
-	private String elemName;
-	private String ns;
-	private String payload;
-	
-	/**
-	 * Construct a <tt>SimplePayload</tt> object with the specified element name, 
-	 * namespace and content.  The content must be well formed XML.
-	 * 
-	 * @param elementName The root element name (of the payload)
-	 * @param namespace The namespace of the payload, null if there is none
-	 * @param xmlPayload The payload data
-	 */
-	public SimplePayload(String elementName, String namespace, String xmlPayload)
-	{
-		elemName = elementName;
-		payload = xmlPayload;
-		ns = namespace;
-	}
-
-	public String getElementName()
-	{
-		return elemName;
-	}
-
-	public String getNamespace()
-	{
-		return ns;
-	}
-
-	public String toXML()
-	{
-		return payload;
-	}
-
-	@Override
-	public String toString()
-	{
-		return getClass().getName() + "payload [" + toXML() + "]";
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+
+/**
+ * The default payload representation for {@link Item#getPayload()}.  It simply 
+ * stores the XML payload as a string.
+ *  
+ * @author Robin Collier
+ */
+public class SimplePayload implements PacketExtension
+{
+	private String elemName;
+	private String ns;
+	private String payload;
+	
+	/**
+	 * Construct a <tt>SimplePayload</tt> object with the specified element name, 
+	 * namespace and content.  The content must be well formed XML.
+	 * 
+	 * @param elementName The root element name (of the payload)
+	 * @param namespace The namespace of the payload, null if there is none
+	 * @param xmlPayload The payload data
+	 */
+	public SimplePayload(String elementName, String namespace, String xmlPayload)
+	{
+		elemName = elementName;
+		payload = xmlPayload;
+		ns = namespace;
+	}
+
+	public String getElementName()
+	{
+		return elemName;
+	}
+
+	public String getNamespace()
+	{
+		return ns;
+	}
+
+	public String toXML()
+	{
+		return payload;
+	}
+
+	@Override
+	public String toString()
+	{
+		return getClass().getName() + "payload [" + toXML() + "]";
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscribeExtension.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscribeExtension.java
index daf8db7..5245ece 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscribeExtension.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscribeExtension.java
@@ -1,60 +1,60 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-/**
- * Represents a request to subscribe to a node.
- * 
- * @author Robin Collier
- */
-public class SubscribeExtension extends NodeExtension
-{
-	protected String jid;
-	
-	public SubscribeExtension(String subscribeJid)
-	{
-		super(PubSubElementType.SUBSCRIBE);
-		jid = subscribeJid;
-	}
-	
-	public SubscribeExtension(String subscribeJid, String nodeId)
-	{
-		super(PubSubElementType.SUBSCRIBE, nodeId);
-		jid = subscribeJid;
-	}
-
-	public String getJid()
-	{
-		return jid;
-	}
-
-	@Override
-	public String toXML()
-	{
-		StringBuilder builder = new StringBuilder("<");
-		builder.append(getElementName());
-		
-		if (getNode() != null)
-		{
-			builder.append(" node='");
-			builder.append(getNode());
-			builder.append("'");
-		}
-		builder.append(" jid='");
-		builder.append(getJid());
-		builder.append("'/>");
-		
-		return builder.toString();
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+/**
+ * Represents a request to subscribe to a node.
+ * 
+ * @author Robin Collier
+ */
+public class SubscribeExtension extends NodeExtension
+{
+	protected String jid;
+	
+	public SubscribeExtension(String subscribeJid)
+	{
+		super(PubSubElementType.SUBSCRIBE);
+		jid = subscribeJid;
+	}
+	
+	public SubscribeExtension(String subscribeJid, String nodeId)
+	{
+		super(PubSubElementType.SUBSCRIBE, nodeId);
+		jid = subscribeJid;
+	}
+
+	public String getJid()
+	{
+		return jid;
+	}
+
+	@Override
+	public String toXML()
+	{
+		StringBuilder builder = new StringBuilder("<");
+		builder.append(getElementName());
+		
+		if (getNode() != null)
+		{
+			builder.append(" node='");
+			builder.append(getNode());
+			builder.append("'");
+		}
+		builder.append(" jid='");
+		builder.append(getJid());
+		builder.append("'/>");
+		
+		return builder.toString();
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscribeForm.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscribeForm.java
index 53f2606..71cad14 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscribeForm.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscribeForm.java
@@ -1,241 +1,241 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.UnknownFormatConversionException;
-
-import org.jivesoftware.smack.util.StringUtils;
-import org.jivesoftware.smackx.Form;
-import org.jivesoftware.smackx.FormField;
-import org.jivesoftware.smackx.packet.DataForm;
-
-/**
- * A decorator for a {@link Form} to easily enable reading and updating
- * of subscription options.  All operations read or update the underlying {@link DataForm}.
- * 
- * <p>Unlike the {@link Form}.setAnswer(XXX)} methods, which throw an exception if the field does not
- * exist, all <b>SubscribeForm.setXXX</b> methods will create the field in the wrapped form
- * if it does not already exist.
- * 
- * @author Robin Collier
- */
-public class SubscribeForm extends Form
-{	
-	public SubscribeForm(DataForm configDataForm)
-	{
-		super(configDataForm);
-	}
-	
-	public SubscribeForm(Form subscribeOptionsForm)
-	{
-		super(subscribeOptionsForm.getDataFormToSend());
-	}
-	
-	public SubscribeForm(FormType formType)
-	{
-		super(formType.toString());
-	}
-	
-	/**
-	 * Determines if an entity wants to receive notifications.
-	 * 
-	 * @return true if want to receive, false otherwise
-	 */
-	public boolean isDeliverOn()
-	{
-		return parseBoolean(getFieldValue(SubscribeOptionFields.deliver));
-	}
-	
-	/**
-	 * Sets whether an entity wants to receive notifications.
-	 *
-	 * @param deliverNotifications
-	 */
-	public void setDeliverOn(boolean deliverNotifications)
-	{
-		addField(SubscribeOptionFields.deliver, FormField.TYPE_BOOLEAN);
-		setAnswer(SubscribeOptionFields.deliver.getFieldName(), deliverNotifications);
-	}
-
-	/**
-	 * Determines if notifications should be delivered as aggregations or not.
-	 * 
-	 * @return true to aggregate, false otherwise
-	 */
-	public boolean isDigestOn()
-	{
-		return parseBoolean(getFieldValue(SubscribeOptionFields.digest));
-	}
-	
-	/**
-	 * Sets whether notifications should be delivered as aggregations or not.
-	 * 
-	 * @param digestOn true to aggregate, false otherwise 
-	 */
-	public void setDigestOn(boolean digestOn)
-	{
-		addField(SubscribeOptionFields.deliver, FormField.TYPE_BOOLEAN);
-		setAnswer(SubscribeOptionFields.deliver.getFieldName(), digestOn);
-	}
-
-	/**
-	 * Gets the minimum number of milliseconds between sending notification digests
-	 * 
-	 * @return The frequency in milliseconds
-	 */
-	public int getDigestFrequency()
-	{
-		return Integer.parseInt(getFieldValue(SubscribeOptionFields.digest_frequency));
-	}
-
-	/**
-	 * Sets the minimum number of milliseconds between sending notification digests
-	 * 
-	 * @param frequency The frequency in milliseconds
-	 */
-	public void setDigestFrequency(int frequency)
-	{
-		addField(SubscribeOptionFields.digest_frequency, FormField.TYPE_TEXT_SINGLE);
-		setAnswer(SubscribeOptionFields.digest_frequency.getFieldName(), frequency);
-	}
-
-	/**
-	 * Get the time at which the leased subscription will expire, or has expired.
-	 * 
-	 * @return The expiry date
-	 */
-	public Date getExpiry()
-	{
-		String dateTime = getFieldValue(SubscribeOptionFields.expire);
-		try
-		{
-			return StringUtils.parseDate(dateTime);
-		}
-		catch (ParseException e)
-		{
-			UnknownFormatConversionException exc = new UnknownFormatConversionException(dateTime);
-			exc.initCause(e);
-			throw exc;
-		}
-	}
-	
-	/**
-	 * Sets the time at which the leased subscription will expire, or has expired.
-	 * 
-	 * @param expire The expiry date
-	 */
-	public void setExpiry(Date expire)
-	{
-		addField(SubscribeOptionFields.expire, FormField.TYPE_TEXT_SINGLE);
-		setAnswer(SubscribeOptionFields.expire.getFieldName(), StringUtils.formatXEP0082Date(expire));
-	}
-	
-	/**
-	 * Determines whether the entity wants to receive an XMPP message body in 
-	 * addition to the payload format.
-	 * 
-	 * @return true to receive the message body, false otherwise
-	 */
-	public boolean isIncludeBody()
-	{
-		return parseBoolean(getFieldValue(SubscribeOptionFields.include_body));
-	}
-	
-	/**
-	 * Sets whether the entity wants to receive an XMPP message body in 
-	 * addition to the payload format.
-	 * 
-	 * @param include true to receive the message body, false otherwise
-	 */
-	public void setIncludeBody(boolean include)
-	{
-		addField(SubscribeOptionFields.include_body, FormField.TYPE_BOOLEAN);
-		setAnswer(SubscribeOptionFields.include_body.getFieldName(), include);
-	}
-
-	/**
-	 * Gets the {@link PresenceState} for which an entity wants to receive 
-	 * notifications.
-	 * 
-	 * @return iterator over the list of states
-	 */
-	public Iterator<PresenceState> getShowValues()
-	{
-		ArrayList<PresenceState> result = new ArrayList<PresenceState>(5);
-		Iterator<String > it = getFieldValues(SubscribeOptionFields.show_values);
-		
-		while (it.hasNext())
-		{
-			String state = it.next();
-			result.add(PresenceState.valueOf(state));
-		}
-		return result.iterator();
-	}
-	
-	/**
-	 * Sets the list of {@link PresenceState} for which an entity wants
-	 * to receive notifications.
-	 * 
-	 * @param stateValues The list of states
-	 */
-	public void setShowValues(Collection<PresenceState> stateValues)
-	{
-		ArrayList<String> values = new ArrayList<String>(stateValues.size());
-		
-		for (PresenceState state : stateValues)
-		{
-			values.add(state.toString());
-		}
-		addField(SubscribeOptionFields.show_values, FormField.TYPE_LIST_MULTI);
-		setAnswer(SubscribeOptionFields.show_values.getFieldName(), values);
-	}
-	
-	
-	static private boolean parseBoolean(String fieldValue)
-	{
-		return ("1".equals(fieldValue) || "true".equals(fieldValue));
-	}
-
-	private String getFieldValue(SubscribeOptionFields field)
-	{
-		FormField formField = getField(field.getFieldName());
-		
-		return formField.getValues().next();
-	}
-
-	private Iterator<String> getFieldValues(SubscribeOptionFields field)
-	{
-		FormField formField = getField(field.getFieldName());
-		
-		return formField.getValues();
-	}
-
-	private void addField(SubscribeOptionFields nodeField, String type)
-	{
-		String fieldName = nodeField.getFieldName();
-		
-		if (getField(fieldName) == null)
-		{
-			FormField field = new FormField(fieldName);
-			field.setType(type);
-			addField(field);
-		}
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.UnknownFormatConversionException;
+
+import org.jivesoftware.smack.util.StringUtils;
+import org.jivesoftware.smackx.Form;
+import org.jivesoftware.smackx.FormField;
+import org.jivesoftware.smackx.packet.DataForm;
+
+/**
+ * A decorator for a {@link Form} to easily enable reading and updating
+ * of subscription options.  All operations read or update the underlying {@link DataForm}.
+ * 
+ * <p>Unlike the {@link Form}.setAnswer(XXX)} methods, which throw an exception if the field does not
+ * exist, all <b>SubscribeForm.setXXX</b> methods will create the field in the wrapped form
+ * if it does not already exist.
+ * 
+ * @author Robin Collier
+ */
+public class SubscribeForm extends Form
+{	
+	public SubscribeForm(DataForm configDataForm)
+	{
+		super(configDataForm);
+	}
+	
+	public SubscribeForm(Form subscribeOptionsForm)
+	{
+		super(subscribeOptionsForm.getDataFormToSend());
+	}
+	
+	public SubscribeForm(FormType formType)
+	{
+		super(formType.toString());
+	}
+	
+	/**
+	 * Determines if an entity wants to receive notifications.
+	 * 
+	 * @return true if want to receive, false otherwise
+	 */
+	public boolean isDeliverOn()
+	{
+		return parseBoolean(getFieldValue(SubscribeOptionFields.deliver));
+	}
+	
+	/**
+	 * Sets whether an entity wants to receive notifications.
+	 *
+	 * @param deliverNotifications
+	 */
+	public void setDeliverOn(boolean deliverNotifications)
+	{
+		addField(SubscribeOptionFields.deliver, FormField.TYPE_BOOLEAN);
+		setAnswer(SubscribeOptionFields.deliver.getFieldName(), deliverNotifications);
+	}
+
+	/**
+	 * Determines if notifications should be delivered as aggregations or not.
+	 * 
+	 * @return true to aggregate, false otherwise
+	 */
+	public boolean isDigestOn()
+	{
+		return parseBoolean(getFieldValue(SubscribeOptionFields.digest));
+	}
+	
+	/**
+	 * Sets whether notifications should be delivered as aggregations or not.
+	 * 
+	 * @param digestOn true to aggregate, false otherwise 
+	 */
+	public void setDigestOn(boolean digestOn)
+	{
+		addField(SubscribeOptionFields.deliver, FormField.TYPE_BOOLEAN);
+		setAnswer(SubscribeOptionFields.deliver.getFieldName(), digestOn);
+	}
+
+	/**
+	 * Gets the minimum number of milliseconds between sending notification digests
+	 * 
+	 * @return The frequency in milliseconds
+	 */
+	public int getDigestFrequency()
+	{
+		return Integer.parseInt(getFieldValue(SubscribeOptionFields.digest_frequency));
+	}
+
+	/**
+	 * Sets the minimum number of milliseconds between sending notification digests
+	 * 
+	 * @param frequency The frequency in milliseconds
+	 */
+	public void setDigestFrequency(int frequency)
+	{
+		addField(SubscribeOptionFields.digest_frequency, FormField.TYPE_TEXT_SINGLE);
+		setAnswer(SubscribeOptionFields.digest_frequency.getFieldName(), frequency);
+	}
+
+	/**
+	 * Get the time at which the leased subscription will expire, or has expired.
+	 * 
+	 * @return The expiry date
+	 */
+	public Date getExpiry()
+	{
+		String dateTime = getFieldValue(SubscribeOptionFields.expire);
+		try
+		{
+			return StringUtils.parseDate(dateTime);
+		}
+		catch (ParseException e)
+		{
+			UnknownFormatConversionException exc = new UnknownFormatConversionException(dateTime);
+			exc.initCause(e);
+			throw exc;
+		}
+	}
+	
+	/**
+	 * Sets the time at which the leased subscription will expire, or has expired.
+	 * 
+	 * @param expire The expiry date
+	 */
+	public void setExpiry(Date expire)
+	{
+		addField(SubscribeOptionFields.expire, FormField.TYPE_TEXT_SINGLE);
+		setAnswer(SubscribeOptionFields.expire.getFieldName(), StringUtils.formatXEP0082Date(expire));
+	}
+	
+	/**
+	 * Determines whether the entity wants to receive an XMPP message body in 
+	 * addition to the payload format.
+	 * 
+	 * @return true to receive the message body, false otherwise
+	 */
+	public boolean isIncludeBody()
+	{
+		return parseBoolean(getFieldValue(SubscribeOptionFields.include_body));
+	}
+	
+	/**
+	 * Sets whether the entity wants to receive an XMPP message body in 
+	 * addition to the payload format.
+	 * 
+	 * @param include true to receive the message body, false otherwise
+	 */
+	public void setIncludeBody(boolean include)
+	{
+		addField(SubscribeOptionFields.include_body, FormField.TYPE_BOOLEAN);
+		setAnswer(SubscribeOptionFields.include_body.getFieldName(), include);
+	}
+
+	/**
+	 * Gets the {@link PresenceState} for which an entity wants to receive 
+	 * notifications.
+	 * 
+	 * @return iterator over the list of states
+	 */
+	public Iterator<PresenceState> getShowValues()
+	{
+		ArrayList<PresenceState> result = new ArrayList<PresenceState>(5);
+		Iterator<String > it = getFieldValues(SubscribeOptionFields.show_values);
+		
+		while (it.hasNext())
+		{
+			String state = it.next();
+			result.add(PresenceState.valueOf(state));
+		}
+		return result.iterator();
+	}
+	
+	/**
+	 * Sets the list of {@link PresenceState} for which an entity wants
+	 * to receive notifications.
+	 * 
+	 * @param stateValues The list of states
+	 */
+	public void setShowValues(Collection<PresenceState> stateValues)
+	{
+		ArrayList<String> values = new ArrayList<String>(stateValues.size());
+		
+		for (PresenceState state : stateValues)
+		{
+			values.add(state.toString());
+		}
+		addField(SubscribeOptionFields.show_values, FormField.TYPE_LIST_MULTI);
+		setAnswer(SubscribeOptionFields.show_values.getFieldName(), values);
+	}
+	
+	
+	static private boolean parseBoolean(String fieldValue)
+	{
+		return ("1".equals(fieldValue) || "true".equals(fieldValue));
+	}
+
+	private String getFieldValue(SubscribeOptionFields field)
+	{
+		FormField formField = getField(field.getFieldName());
+		
+		return formField.getValues().next();
+	}
+
+	private Iterator<String> getFieldValues(SubscribeOptionFields field)
+	{
+		FormField formField = getField(field.getFieldName());
+		
+		return formField.getValues();
+	}
+
+	private void addField(SubscribeOptionFields nodeField, String type)
+	{
+		String fieldName = nodeField.getFieldName();
+		
+		if (getField(fieldName) == null)
+		{
+			FormField field = new FormField(fieldName);
+			field.setType(type);
+			addField(field);
+		}
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscribeOptionFields.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscribeOptionFields.java
index dfca601..463a40f 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscribeOptionFields.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscribeOptionFields.java
@@ -1,99 +1,99 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import java.util.Calendar;
-
-/**
- * Defines the possible field options for a subscribe options form as defined 
- * by <a href="http://xmpp.org/extensions/xep-0060.html#registrar-formtypes-subscribe">Section 16.4.2</a>.
- * 
- * @author Robin Collier
- */
-public enum SubscribeOptionFields
-{
-	/**
-	 * Whether an entity wants to receive or disable notifications
-	 * 
-	 * <p><b>Value: boolean</b></p>
-	 */
-	deliver,
-
-	/**
-	 * Whether an entity wants to receive digests (aggregations) of 
-	 * notifications or all notifications individually.
-	 * 
-	 * <p><b>Value: boolean</b></p>
-	 */
-	digest,
-	
-	/**
-	 * The minimum number of seconds between sending any two notifications digests
-	 * 
-	 * <p><b>Value: int</b></p>
-	 */
-	digest_frequency,
-
-	/**
-	 * The DateTime at which a leased subsscription will end ro has ended.
-	 * 
-	 * <p><b>Value: {@link Calendar}</b></p>
-	 */
-	expire,
-
-	/**
-	 * Whether an entity wants to receive an XMPP message body in addition to 
-	 * the payload format.
-	 *
-	 * <p><b>Value: boolean</b></p>
-	 */
-	include_body,
-	
-	/**
-	 * The presence states for which an entity wants to receive notifications.
-	 *
-	 * <p><b>Value: {@link PresenceState}</b></p>
-	 */
-	show_values,
-	
-	/**
-	 * 
-	 * 
-	 * <p><b>Value: </b></p>
-	 */
-	subscription_type,
-	
-	/**
-	 * 
-	 * <p><b>Value: </b></p>
-	 */
-	subscription_depth;
-	
-	public String getFieldName()
-	{
-		if (this == show_values)
-			return "pubsub#" + toString().replace('_', '-');
-		return "pubsub#" + toString();
-	}
-	
-	static public SubscribeOptionFields valueOfFromElement(String elementName)
-	{
-		String portion = elementName.substring(elementName.lastIndexOf('#' + 1));
-		
-		if ("show-values".equals(portion))
-			return show_values;
-		else
-			return valueOf(portion);
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import java.util.Calendar;
+
+/**
+ * Defines the possible field options for a subscribe options form as defined 
+ * by <a href="http://xmpp.org/extensions/xep-0060.html#registrar-formtypes-subscribe">Section 16.4.2</a>.
+ * 
+ * @author Robin Collier
+ */
+public enum SubscribeOptionFields
+{
+	/**
+	 * Whether an entity wants to receive or disable notifications
+	 * 
+	 * <p><b>Value: boolean</b></p>
+	 */
+	deliver,
+
+	/**
+	 * Whether an entity wants to receive digests (aggregations) of 
+	 * notifications or all notifications individually.
+	 * 
+	 * <p><b>Value: boolean</b></p>
+	 */
+	digest,
+	
+	/**
+	 * The minimum number of seconds between sending any two notifications digests
+	 * 
+	 * <p><b>Value: int</b></p>
+	 */
+	digest_frequency,
+
+	/**
+	 * The DateTime at which a leased subsscription will end ro has ended.
+	 * 
+	 * <p><b>Value: {@link Calendar}</b></p>
+	 */
+	expire,
+
+	/**
+	 * Whether an entity wants to receive an XMPP message body in addition to 
+	 * the payload format.
+	 *
+	 * <p><b>Value: boolean</b></p>
+	 */
+	include_body,
+	
+	/**
+	 * The presence states for which an entity wants to receive notifications.
+	 *
+	 * <p><b>Value: {@link PresenceState}</b></p>
+	 */
+	show_values,
+	
+	/**
+	 * 
+	 * 
+	 * <p><b>Value: </b></p>
+	 */
+	subscription_type,
+	
+	/**
+	 * 
+	 * <p><b>Value: </b></p>
+	 */
+	subscription_depth;
+	
+	public String getFieldName()
+	{
+		if (this == show_values)
+			return "pubsub#" + toString().replace('_', '-');
+		return "pubsub#" + toString();
+	}
+	
+	static public SubscribeOptionFields valueOfFromElement(String elementName)
+	{
+		String portion = elementName.substring(elementName.lastIndexOf('#' + 1));
+		
+		if ("show-values".equals(portion))
+			return show_values;
+		else
+			return valueOf(portion);
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/Subscription.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/Subscription.java
index 19ad8a8..49d9a4a 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/Subscription.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/Subscription.java
@@ -1,160 +1,160 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-/**
- * Represents a subscription to node for both requests and replies.
- * 
- * @author Robin Collier
- */
-public class Subscription extends NodeExtension
-{
-	protected String jid;
-	protected String id;
-	protected State state;
-	protected boolean configRequired = false;
-	
-	public enum State
-	{
-		subscribed, unconfigured, pending, none 
-	}
-
-	/**
-	 * Used to constructs a subscription request to the root node with the specified
-	 * JID.
-	 * 
-	 * @param subscriptionJid The subscriber JID
-	 */
-	public Subscription(String subscriptionJid)
-	{
-		this(subscriptionJid, null, null, null);
-	}
-	
-	/**
-	 * Used to constructs a subscription request to the specified node with the specified
-	 * JID.
-	 * 
-	 * @param subscriptionJid The subscriber JID
-	 * @param nodeId The node id
-	 */
-	public Subscription(String subscriptionJid, String nodeId)
-	{
-		this(subscriptionJid, nodeId, null, null);
-	}
-	
-	/**
-	 * Constructs a representation of a subscription reply to the specified node 
-	 * and JID.  The server	will have supplied the subscription id and current state.
-	 * 
-	 * @param jid The JID the request was made under
-	 * @param nodeId The node subscribed to
-	 * @param subscriptionId The id of this subscription
-	 * @param state The current state of the subscription
-	 */
-	public Subscription(String jid, String nodeId, String subscriptionId, State state)
-	{
-		super(PubSubElementType.SUBSCRIPTION, nodeId);
-		this.jid = jid;
-		id = subscriptionId;
-		this.state = state;
-	}
-	
-	/**
-	 * Constructs a representation of a subscription reply to the specified node 
-	 * and JID.  The server	will have supplied the subscription id and current state
-	 * and whether the subscription need to be configured.
-	 * 
-	 * @param jid The JID the request was made under
-	 * @param nodeId The node subscribed to
-	 * @param subscriptionId The id of this subscription
-	 * @param state The current state of the subscription
-	 * @param configRequired Is configuration required to complete the subscription 
-	 */
-	public Subscription(String jid, String nodeId, String subscriptionId, State state, boolean configRequired)
-	{
-		super(PubSubElementType.SUBSCRIPTION, nodeId);
-		this.jid = jid;
-		id = subscriptionId;
-		this.state = state;
-		this.configRequired = configRequired;
-	}
-	
-	/**
-	 * Gets the JID the subscription is created for
-	 * 
-	 * @return The JID
-	 */
-	public String getJid()
-	{
-		return jid;
-	}
-	
-	/**
-	 * Gets the subscription id
-	 * 
-	 * @return The subscription id
-	 */
-	public String getId()
-	{
-		return id;
-	}
-	
-	/**
-	 * Gets the current subscription state.
-	 * 
-	 * @return Current subscription state
-	 */
-	public State getState()
-	{
-		return state;
-	}
-
-	/**
-	 * This value is only relevant when the {@link #getState()} is {@link State#unconfigured}
-	 * 
-	 * @return true if configuration is required, false otherwise
-	 */
-	public boolean isConfigRequired()
-	{
-		return configRequired;
-	}
-	
-	public String toXML()
-	{
-		StringBuilder builder = new StringBuilder("<subscription");
-		appendAttribute(builder, "jid", jid);
-		
-		if (getNode() != null)
-			appendAttribute(builder, "node", getNode());
-		
-		if (id != null)
-			appendAttribute(builder, "subid", id);
-		
-		if (state != null)
-			appendAttribute(builder, "subscription", state.toString());
-		
-		builder.append("/>");
-		return builder.toString();
-	}
-
-	private void appendAttribute(StringBuilder builder, String att, String value)
-	{
-		builder.append(" ");
-		builder.append(att);
-		builder.append("='");
-		builder.append(value);
-		builder.append("'");
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+/**
+ * Represents a subscription to node for both requests and replies.
+ * 
+ * @author Robin Collier
+ */
+public class Subscription extends NodeExtension
+{
+	protected String jid;
+	protected String id;
+	protected State state;
+	protected boolean configRequired = false;
+	
+	public enum State
+	{
+		subscribed, unconfigured, pending, none 
+	}
+
+	/**
+	 * Used to constructs a subscription request to the root node with the specified
+	 * JID.
+	 * 
+	 * @param subscriptionJid The subscriber JID
+	 */
+	public Subscription(String subscriptionJid)
+	{
+		this(subscriptionJid, null, null, null);
+	}
+	
+	/**
+	 * Used to constructs a subscription request to the specified node with the specified
+	 * JID.
+	 * 
+	 * @param subscriptionJid The subscriber JID
+	 * @param nodeId The node id
+	 */
+	public Subscription(String subscriptionJid, String nodeId)
+	{
+		this(subscriptionJid, nodeId, null, null);
+	}
+	
+	/**
+	 * Constructs a representation of a subscription reply to the specified node 
+	 * and JID.  The server	will have supplied the subscription id and current state.
+	 * 
+	 * @param jid The JID the request was made under
+	 * @param nodeId The node subscribed to
+	 * @param subscriptionId The id of this subscription
+	 * @param state The current state of the subscription
+	 */
+	public Subscription(String jid, String nodeId, String subscriptionId, State state)
+	{
+		super(PubSubElementType.SUBSCRIPTION, nodeId);
+		this.jid = jid;
+		id = subscriptionId;
+		this.state = state;
+	}
+	
+	/**
+	 * Constructs a representation of a subscription reply to the specified node 
+	 * and JID.  The server	will have supplied the subscription id and current state
+	 * and whether the subscription need to be configured.
+	 * 
+	 * @param jid The JID the request was made under
+	 * @param nodeId The node subscribed to
+	 * @param subscriptionId The id of this subscription
+	 * @param state The current state of the subscription
+	 * @param configRequired Is configuration required to complete the subscription 
+	 */
+	public Subscription(String jid, String nodeId, String subscriptionId, State state, boolean configRequired)
+	{
+		super(PubSubElementType.SUBSCRIPTION, nodeId);
+		this.jid = jid;
+		id = subscriptionId;
+		this.state = state;
+		this.configRequired = configRequired;
+	}
+	
+	/**
+	 * Gets the JID the subscription is created for
+	 * 
+	 * @return The JID
+	 */
+	public String getJid()
+	{
+		return jid;
+	}
+	
+	/**
+	 * Gets the subscription id
+	 * 
+	 * @return The subscription id
+	 */
+	public String getId()
+	{
+		return id;
+	}
+	
+	/**
+	 * Gets the current subscription state.
+	 * 
+	 * @return Current subscription state
+	 */
+	public State getState()
+	{
+		return state;
+	}
+
+	/**
+	 * This value is only relevant when the {@link #getState()} is {@link State#unconfigured}
+	 * 
+	 * @return true if configuration is required, false otherwise
+	 */
+	public boolean isConfigRequired()
+	{
+		return configRequired;
+	}
+	
+	public String toXML()
+	{
+		StringBuilder builder = new StringBuilder("<subscription");
+		appendAttribute(builder, "jid", jid);
+		
+		if (getNode() != null)
+			appendAttribute(builder, "node", getNode());
+		
+		if (id != null)
+			appendAttribute(builder, "subid", id);
+		
+		if (state != null)
+			appendAttribute(builder, "subscription", state.toString());
+		
+		builder.append("/>");
+		return builder.toString();
+	}
+
+	private void appendAttribute(StringBuilder builder, String att, String value)
+	{
+		builder.append(" ");
+		builder.append(att);
+		builder.append("='");
+		builder.append(value);
+		builder.append("'");
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscriptionEvent.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscriptionEvent.java
index 99f18d5..a721452 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscriptionEvent.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscriptionEvent.java
@@ -1,75 +1,75 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Base class to represents events that are associated to subscriptions.
- * 
- * @author Robin Collier
- */
-abstract public class SubscriptionEvent extends NodeEvent
-{
-	private List<String> subIds = Collections.EMPTY_LIST;
-
-	/**
-	 * Construct an event with no subscription id's.  This can 
-	 * occur when there is only one subscription to a node.  The
-	 * event may or may not report the subscription id along 
-	 * with the event.
-	 * 
-	 * @param nodeId The id of the node the event came from
-	 */
-	protected SubscriptionEvent(String nodeId)
-	{
-		super(nodeId);
-	}
-
-	/**
-	 * Construct an event with multiple subscriptions.
-	 * 
-	 * @param nodeId The id of the node the event came from
-	 * @param subscriptionIds The list of subscription id's
-	 */
-	protected SubscriptionEvent(String nodeId, List<String> subscriptionIds)
-	{
-		super(nodeId);
-		
-		if (subscriptionIds != null)
-			subIds = subscriptionIds;
-	}
-
-	/** 
-	 * Get the subscriptions this event is associated with.
-	 * 
-	 * @return List of subscription id's
-	 */
-	public List<String> getSubscriptions()
-	{
-		return Collections.unmodifiableList(subIds);
-	}
-	
-	/**
-	 * Set the list of subscription id's for this event.
-	 * 
-	 * @param subscriptionIds The list of subscription id's
-	 */
-	protected void setSubscriptions(List<String> subscriptionIds)
-	{
-		if (subscriptionIds != null)
-			subIds = subscriptionIds;
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Base class to represents events that are associated to subscriptions.
+ * 
+ * @author Robin Collier
+ */
+abstract public class SubscriptionEvent extends NodeEvent
+{
+	private List<String> subIds = Collections.EMPTY_LIST;
+
+	/**
+	 * Construct an event with no subscription id's.  This can 
+	 * occur when there is only one subscription to a node.  The
+	 * event may or may not report the subscription id along 
+	 * with the event.
+	 * 
+	 * @param nodeId The id of the node the event came from
+	 */
+	protected SubscriptionEvent(String nodeId)
+	{
+		super(nodeId);
+	}
+
+	/**
+	 * Construct an event with multiple subscriptions.
+	 * 
+	 * @param nodeId The id of the node the event came from
+	 * @param subscriptionIds The list of subscription id's
+	 */
+	protected SubscriptionEvent(String nodeId, List<String> subscriptionIds)
+	{
+		super(nodeId);
+		
+		if (subscriptionIds != null)
+			subIds = subscriptionIds;
+	}
+
+	/** 
+	 * Get the subscriptions this event is associated with.
+	 * 
+	 * @return List of subscription id's
+	 */
+	public List<String> getSubscriptions()
+	{
+		return Collections.unmodifiableList(subIds);
+	}
+	
+	/**
+	 * Set the list of subscription id's for this event.
+	 * 
+	 * @param subscriptionIds The list of subscription id's
+	 */
+	protected void setSubscriptions(List<String> subscriptionIds)
+	{
+		if (subscriptionIds != null)
+			subIds = subscriptionIds;
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscriptionsExtension.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscriptionsExtension.java
index a28cbe2..396b36d 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscriptionsExtension.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/SubscriptionsExtension.java
@@ -1,96 +1,96 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Represents the element holding the list of subscription elements.
- * 
- * @author Robin Collier
- */
-public class SubscriptionsExtension extends NodeExtension
-{
-	protected List<Subscription> items = Collections.EMPTY_LIST;
-	
-	/**
-	 * Subscriptions to the root node
-	 * 
-	 * @param subList The list of subscriptions
-	 */
-	public SubscriptionsExtension(List<Subscription> subList)
-	{
-		super(PubSubElementType.SUBSCRIPTIONS);
-		
-		if (subList != null)
-			items = subList;
-	}
-
-	/**
-	 * Subscriptions to the specified node.
-	 * 
-	 * @param nodeId The node subscribed to
-	 * @param subList The list of subscriptions
-	 */
-	public SubscriptionsExtension(String nodeId, List<Subscription> subList)
-	{
-		super(PubSubElementType.SUBSCRIPTIONS, nodeId);
-
-		if (subList != null)
-			items = subList;
-	}
-
-	/**
-	 * Gets the list of subscriptions.
-	 * 
-	 * @return List of subscriptions
-	 */
-	public List<Subscription> getSubscriptions()
-	{
-		return items;
-	}
-
-	@Override
-	public String toXML()
-	{
-		if ((items == null) || (items.size() == 0))
-		{
-			return super.toXML();
-		}
-		else
-		{
-			StringBuilder builder = new StringBuilder("<");
-			builder.append(getElementName());
-			
-			if (getNode() != null)
-			{
-				builder.append(" node='");
-				builder.append(getNode());
-				builder.append("'");
-			}
-			builder.append(">");
-			
-			for (Subscription item : items)
-			{
-				builder.append(item.toXML());
-			}
-			
-			builder.append("</");
-			builder.append(getElementName());
-			builder.append(">");
-			return builder.toString();
-		}
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Represents the element holding the list of subscription elements.
+ * 
+ * @author Robin Collier
+ */
+public class SubscriptionsExtension extends NodeExtension
+{
+	protected List<Subscription> items = Collections.EMPTY_LIST;
+	
+	/**
+	 * Subscriptions to the root node
+	 * 
+	 * @param subList The list of subscriptions
+	 */
+	public SubscriptionsExtension(List<Subscription> subList)
+	{
+		super(PubSubElementType.SUBSCRIPTIONS);
+		
+		if (subList != null)
+			items = subList;
+	}
+
+	/**
+	 * Subscriptions to the specified node.
+	 * 
+	 * @param nodeId The node subscribed to
+	 * @param subList The list of subscriptions
+	 */
+	public SubscriptionsExtension(String nodeId, List<Subscription> subList)
+	{
+		super(PubSubElementType.SUBSCRIPTIONS, nodeId);
+
+		if (subList != null)
+			items = subList;
+	}
+
+	/**
+	 * Gets the list of subscriptions.
+	 * 
+	 * @return List of subscriptions
+	 */
+	public List<Subscription> getSubscriptions()
+	{
+		return items;
+	}
+
+	@Override
+	public String toXML()
+	{
+		if ((items == null) || (items.size() == 0))
+		{
+			return super.toXML();
+		}
+		else
+		{
+			StringBuilder builder = new StringBuilder("<");
+			builder.append(getElementName());
+			
+			if (getNode() != null)
+			{
+				builder.append(" node='");
+				builder.append(getNode());
+				builder.append("'");
+			}
+			builder.append(">");
+			
+			for (Subscription item : items)
+			{
+				builder.append(item.toXML());
+			}
+			
+			builder.append("</");
+			builder.append(getElementName());
+			builder.append(">");
+			return builder.toString();
+		}
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/UnsubscribeExtension.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/UnsubscribeExtension.java
index ac14c60..dc815ca 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/UnsubscribeExtension.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/UnsubscribeExtension.java
@@ -1,73 +1,73 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub;
-
-import org.jivesoftware.smackx.pubsub.util.XmlUtils;
-
-
-/**
- * Represents an unsubscribe element.
- * 
- * @author Robin Collier
- */
-public class UnsubscribeExtension extends NodeExtension
-{
-	protected String jid;
-	protected String id;
-	
-	public UnsubscribeExtension(String subscriptionJid)
-	{
-		this(subscriptionJid, null, null);
-	}
-	
-	public UnsubscribeExtension(String subscriptionJid, String nodeId)
-	{
-		this(subscriptionJid, nodeId, null);
-	}
-	
-	public UnsubscribeExtension(String jid, String nodeId, String subscriptionId)
-	{
-		super(PubSubElementType.UNSUBSCRIBE, nodeId);
-		this.jid = jid;
-		id = subscriptionId;
-	}
-	
-	public String getJid()
-	{
-		return jid;
-	}
-	
-	public String getId()
-	{
-		return id;
-	}
-	
-	@Override
-	public String toXML()
-	{
-		StringBuilder builder = new StringBuilder("<");
-		builder.append(getElementName());
-		XmlUtils.appendAttribute(builder, "jid", jid);
-		
-		if (getNode() != null)
-			XmlUtils.appendAttribute(builder, "node", getNode());
-		
-		if (id != null)
-			XmlUtils.appendAttribute(builder, "subid", id);
-		
-		builder.append("/>");
-		return builder.toString();
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub;
+
+import org.jivesoftware.smackx.pubsub.util.XmlUtils;
+
+
+/**
+ * Represents an unsubscribe element.
+ * 
+ * @author Robin Collier
+ */
+public class UnsubscribeExtension extends NodeExtension
+{
+	protected String jid;
+	protected String id;
+	
+	public UnsubscribeExtension(String subscriptionJid)
+	{
+		this(subscriptionJid, null, null);
+	}
+	
+	public UnsubscribeExtension(String subscriptionJid, String nodeId)
+	{
+		this(subscriptionJid, nodeId, null);
+	}
+	
+	public UnsubscribeExtension(String jid, String nodeId, String subscriptionId)
+	{
+		super(PubSubElementType.UNSUBSCRIBE, nodeId);
+		this.jid = jid;
+		id = subscriptionId;
+	}
+	
+	public String getJid()
+	{
+		return jid;
+	}
+	
+	public String getId()
+	{
+		return id;
+	}
+	
+	@Override
+	public String toXML()
+	{
+		StringBuilder builder = new StringBuilder("<");
+		builder.append(getElementName());
+		XmlUtils.appendAttribute(builder, "jid", jid);
+		
+		if (getNode() != null)
+			XmlUtils.appendAttribute(builder, "node", getNode());
+		
+		if (id != null)
+			XmlUtils.appendAttribute(builder, "subid", id);
+		
+		builder.append("/>");
+		return builder.toString();
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/listener/ItemDeleteListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/listener/ItemDeleteListener.java
index d228e8f..9b9c310 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/listener/ItemDeleteListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/listener/ItemDeleteListener.java
@@ -1,41 +1,41 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.listener;
-
-import org.jivesoftware.smackx.pubsub.ItemDeleteEvent;
-import org.jivesoftware.smackx.pubsub.LeafNode;
-
-/**
- * Defines the listener for item deletion events from a node.
- * 
- * @see LeafNode#addItemDeleteListener(ItemDeleteListener)
- * 
- * @author Robin Collier
- */
-public interface ItemDeleteListener
-{
-	/**
-	 * Called when items are deleted from a node the listener is 
-	 * registered with.
-	 * 
-	 * @param items The event with item deletion details
-	 */
-	void handleDeletedItems(ItemDeleteEvent items);
-	
-	/**
-	 * Called when <b>all</b> items are deleted from a node the listener is 
-	 * registered with. 
-	 */
-	void handlePurge();
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.listener;
+
+import org.jivesoftware.smackx.pubsub.ItemDeleteEvent;
+import org.jivesoftware.smackx.pubsub.LeafNode;
+
+/**
+ * Defines the listener for item deletion events from a node.
+ * 
+ * @see LeafNode#addItemDeleteListener(ItemDeleteListener)
+ * 
+ * @author Robin Collier
+ */
+public interface ItemDeleteListener
+{
+	/**
+	 * Called when items are deleted from a node the listener is 
+	 * registered with.
+	 * 
+	 * @param items The event with item deletion details
+	 */
+	void handleDeletedItems(ItemDeleteEvent items);
+	
+	/**
+	 * Called when <b>all</b> items are deleted from a node the listener is 
+	 * registered with. 
+	 */
+	void handlePurge();
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/listener/ItemEventListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/listener/ItemEventListener.java
index 714b2c0..0556eea 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/listener/ItemEventListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/listener/ItemEventListener.java
@@ -1,36 +1,36 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.listener;
-
-import org.jivesoftware.smackx.pubsub.Item;
-import org.jivesoftware.smackx.pubsub.ItemPublishEvent;
-import org.jivesoftware.smackx.pubsub.LeafNode;
-
-/**
- * Defines the listener for items being published to a node.
- * 
- * @see LeafNode#addItemEventListener(ItemEventListener)
- *
- * @author Robin Collier
- */
-public interface ItemEventListener <T extends Item> 
-{
-	/**
-	 * Called whenever an item is published to the node the listener
-	 * is registered with.
-	 * 
-	 * @param items The publishing details.
-	 */
-	void handlePublishedItems(ItemPublishEvent<T> items);
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.listener;
+
+import org.jivesoftware.smackx.pubsub.Item;
+import org.jivesoftware.smackx.pubsub.ItemPublishEvent;
+import org.jivesoftware.smackx.pubsub.LeafNode;
+
+/**
+ * Defines the listener for items being published to a node.
+ * 
+ * @see LeafNode#addItemEventListener(ItemEventListener)
+ *
+ * @author Robin Collier
+ */
+public interface ItemEventListener <T extends Item> 
+{
+	/**
+	 * Called whenever an item is published to the node the listener
+	 * is registered with.
+	 * 
+	 * @param items The publishing details.
+	 */
+	void handlePublishedItems(ItemPublishEvent<T> items);
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/listener/NodeConfigListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/listener/NodeConfigListener.java
index 39db5a5..096ed68 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/listener/NodeConfigListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/listener/NodeConfigListener.java
@@ -1,35 +1,35 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.listener;
-
-import org.jivesoftware.smackx.pubsub.ConfigurationEvent;
-import org.jivesoftware.smackx.pubsub.LeafNode;
-
-/**
- * Defines the listener for a node being configured.
- * 
- * @see LeafNode#addConfigurationListener(NodeConfigListener)
- *
- * @author Robin Collier
- */
-public interface NodeConfigListener
-{
-	/**
-	 * Called whenever the node the listener
-	 * is registered with is configured.
-	 * 
-	 * @param config The configuration details.
-	 */
-	void handleNodeConfiguration(ConfigurationEvent config);
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.listener;
+
+import org.jivesoftware.smackx.pubsub.ConfigurationEvent;
+import org.jivesoftware.smackx.pubsub.LeafNode;
+
+/**
+ * Defines the listener for a node being configured.
+ * 
+ * @see LeafNode#addConfigurationListener(NodeConfigListener)
+ *
+ * @author Robin Collier
+ */
+public interface NodeConfigListener
+{
+	/**
+	 * Called whenever the node the listener
+	 * is registered with is configured.
+	 * 
+	 * @param config The configuration details.
+	 */
+	void handleNodeConfiguration(ConfigurationEvent config);
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/packet/PubSub.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/packet/PubSub.java
index 5aa4865..fb7f643 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/packet/PubSub.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/packet/PubSub.java
@@ -1,106 +1,106 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.packet;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smackx.pubsub.PubSubElementType;
-
-/**
- * The standard PubSub extension of an {@link IQ} packet.  This is the topmost
- * element of all pubsub requests and replies as defined in the <a href="http://xmpp.org/extensions/xep-0060">Publish-Subscribe</a> 
- * specification.
- * 
- * @author Robin Collier
- */
-public class PubSub extends IQ
-{
-	private PubSubNamespace ns = PubSubNamespace.BASIC;
-	
-	/**
-    * Returns the XML element name of the extension sub-packet root element.
-    *
-    * @return the XML element name of the packet extension.
-    */
-    public String getElementName() {
-        return "pubsub";
-    }
-
-    /** 
-     * Returns the XML namespace of the extension sub-packet root element.
-     * According the specification the namespace is 
-     * http://jabber.org/protocol/pubsub with a specific fragment depending
-     * on the request.  The namespace is defined at <a href="http://xmpp.org/registrar/namespaces.html">XMPP Registrar</a> at
-     * 
-     * The default value has no fragment.
-     * 
-     * @return the XML namespace of the packet extension.
-     */
-    public String getNamespace() 
-    {
-        return ns.getXmlns();
-    }
-
-    /**
-     * Set the namespace for the packet if it something other than the default
-     * case of {@link PubSubNamespace#BASIC}.  The {@link #getNamespace()} method will return 
-     * the result of calling {@link PubSubNamespace#getXmlns()} on the specified enum.
-     * 
-     * @param ns - The new value for the namespace.
-     */
-	public void setPubSubNamespace(PubSubNamespace ns)
-	{
-		this.ns = ns;
-	}
-
-	public PacketExtension getExtension(PubSubElementType elem)
-	{
-		return getExtension(elem.getElementName(), elem.getNamespace().getXmlns());
-	}
-
-	/**
-	 * Returns the current value of the namespace.  The {@link #getNamespace()} method will return 
-     * the result of calling {@link PubSubNamespace#getXmlns()} this value.
-	 * 
-	 * @return The current value of the namespace.
-	 */
-	public PubSubNamespace getPubSubNamespace()
-	{
-		return ns;
-	}
-    /**
-     * Returns the XML representation of a pubsub element according the specification.
-     * 
-     * The XML representation will be inside of an iq packet like
-     * in the following example:
-     * <pre>
-     * &lt;iq type='set' id="MlIpV-4" to="pubsub.gato.home" from="gato3@gato.home/Smack"&gt;
-     *     &lt;pubsub xmlns="http://jabber.org/protocol/pubsub"&gt;
-     *                      :
-     *         Specific request extension
-     *                      :
-     *     &lt;/pubsub&gt;
-     * &lt;/iq&gt;
-     * </pre>
-     * 
-     */
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append("\">");
-        buf.append(getExtensionsXML());
-        buf.append("</").append(getElementName()).append(">");
-        return buf.toString();
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.packet;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smackx.pubsub.PubSubElementType;
+
+/**
+ * The standard PubSub extension of an {@link IQ} packet.  This is the topmost
+ * element of all pubsub requests and replies as defined in the <a href="http://xmpp.org/extensions/xep-0060">Publish-Subscribe</a> 
+ * specification.
+ * 
+ * @author Robin Collier
+ */
+public class PubSub extends IQ
+{
+	private PubSubNamespace ns = PubSubNamespace.BASIC;
+	
+	/**
+    * Returns the XML element name of the extension sub-packet root element.
+    *
+    * @return the XML element name of the packet extension.
+    */
+    public String getElementName() {
+        return "pubsub";
+    }
+
+    /** 
+     * Returns the XML namespace of the extension sub-packet root element.
+     * According the specification the namespace is 
+     * http://jabber.org/protocol/pubsub with a specific fragment depending
+     * on the request.  The namespace is defined at <a href="http://xmpp.org/registrar/namespaces.html">XMPP Registrar</a> at
+     * 
+     * The default value has no fragment.
+     * 
+     * @return the XML namespace of the packet extension.
+     */
+    public String getNamespace() 
+    {
+        return ns.getXmlns();
+    }
+
+    /**
+     * Set the namespace for the packet if it something other than the default
+     * case of {@link PubSubNamespace#BASIC}.  The {@link #getNamespace()} method will return 
+     * the result of calling {@link PubSubNamespace#getXmlns()} on the specified enum.
+     * 
+     * @param ns - The new value for the namespace.
+     */
+	public void setPubSubNamespace(PubSubNamespace ns)
+	{
+		this.ns = ns;
+	}
+
+	public PacketExtension getExtension(PubSubElementType elem)
+	{
+		return getExtension(elem.getElementName(), elem.getNamespace().getXmlns());
+	}
+
+	/**
+	 * Returns the current value of the namespace.  The {@link #getNamespace()} method will return 
+     * the result of calling {@link PubSubNamespace#getXmlns()} this value.
+	 * 
+	 * @return The current value of the namespace.
+	 */
+	public PubSubNamespace getPubSubNamespace()
+	{
+		return ns;
+	}
+    /**
+     * Returns the XML representation of a pubsub element according the specification.
+     * 
+     * The XML representation will be inside of an iq packet like
+     * in the following example:
+     * <pre>
+     * &lt;iq type='set' id="MlIpV-4" to="pubsub.gato.home" from="gato3@gato.home/Smack"&gt;
+     *     &lt;pubsub xmlns="http://jabber.org/protocol/pubsub"&gt;
+     *                      :
+     *         Specific request extension
+     *                      :
+     *     &lt;/pubsub&gt;
+     * &lt;/iq&gt;
+     * </pre>
+     * 
+     */
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append("\">");
+        buf.append(getExtensionsXML());
+        buf.append("</").append(getElementName()).append(">");
+        return buf.toString();
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/packet/PubSubNamespace.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/packet/PubSubNamespace.java
index eecf959..4fa8ad2 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/packet/PubSubNamespace.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/packet/PubSubNamespace.java
@@ -1,63 +1,63 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.packet;
-
-/**
- * Defines all the valid namespaces that are used with the {@link PubSub} packet
- * as defined by the specification.
- * 
- * @author Robin Collier
- */
-public enum PubSubNamespace
-{
-	BASIC(null),
-	ERROR("errors"),
-	EVENT("event"),
-	OWNER("owner");
-	
-	private String fragment;
-	
-	private PubSubNamespace(String fragment)
-	{
-		this.fragment = fragment;
-	}
-	
-	public String getXmlns()
-	{
-		String ns = "http://jabber.org/protocol/pubsub";
-		
-		if (fragment != null)
-			ns += '#' + fragment;
-		
-		return ns;
-	}
-	
-	public String getFragment()
-	{
-		return fragment;
-	}
-
-	public static PubSubNamespace valueOfFromXmlns(String ns)
-	{
-		int index = ns.lastIndexOf('#');
-		
-		if (index != -1)
-		{
-			String suffix = ns.substring(ns.lastIndexOf('#')+1);
-			return valueOf(suffix.toUpperCase());
-		}
-		else
-			return BASIC;
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.packet;
+
+/**
+ * Defines all the valid namespaces that are used with the {@link PubSub} packet
+ * as defined by the specification.
+ * 
+ * @author Robin Collier
+ */
+public enum PubSubNamespace
+{
+	BASIC(null),
+	ERROR("errors"),
+	EVENT("event"),
+	OWNER("owner");
+	
+	private String fragment;
+	
+	private PubSubNamespace(String fragment)
+	{
+		this.fragment = fragment;
+	}
+	
+	public String getXmlns()
+	{
+		String ns = "http://jabber.org/protocol/pubsub";
+		
+		if (fragment != null)
+			ns += '#' + fragment;
+		
+		return ns;
+	}
+	
+	public String getFragment()
+	{
+		return fragment;
+	}
+
+	public static PubSubNamespace valueOfFromXmlns(String ns)
+	{
+		int index = ns.lastIndexOf('#');
+		
+		if (index != -1)
+		{
+			String suffix = ns.substring(ns.lastIndexOf('#')+1);
+			return valueOf(suffix.toUpperCase());
+		}
+		else
+			return BASIC;
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/packet/SyncPacketSend.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/packet/SyncPacketSend.java
index 080129b..ff730c4 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/packet/SyncPacketSend.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/packet/SyncPacketSend.java
@@ -1,63 +1,63 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.packet;
-
-import org.jivesoftware.smack.PacketCollector;
-import org.jivesoftware.smack.SmackConfiguration;
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.filter.PacketFilter;
-import org.jivesoftware.smack.filter.PacketIDFilter;
-import org.jivesoftware.smack.packet.Packet;
-
-/**
- * Utility class for doing synchronous calls to the server.  Provides several
- * methods for sending a packet to the server and waiting for the reply.
- * 
- * @author Robin Collier
- */
-final public class SyncPacketSend
-{
-	private SyncPacketSend()
-	{	}
-	
-	static public Packet getReply(Connection connection, Packet packet, long timeout)
-		throws XMPPException
-	{
-        PacketFilter responseFilter = new PacketIDFilter(packet.getPacketID());
-        PacketCollector response = connection.createPacketCollector(responseFilter);
-        
-        connection.sendPacket(packet);
-
-        // Wait up to a certain number of seconds for a reply.
-        Packet result = response.nextResult(timeout);
-
-        // Stop queuing results
-        response.cancel();
-
-        if (result == null) {
-            throw new XMPPException("No response from server.");
-        }
-        else if (result.getError() != null) {
-            throw new XMPPException(result.getError());
-        }
-        return result;
-	}
-
-	static public Packet getReply(Connection connection, Packet packet)
-		throws XMPPException
-	{
-		return getReply(connection, packet, SmackConfiguration.getPacketReplyTimeout());
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.packet;
+
+import org.jivesoftware.smack.PacketCollector;
+import org.jivesoftware.smack.SmackConfiguration;
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.filter.PacketIDFilter;
+import org.jivesoftware.smack.packet.Packet;
+
+/**
+ * Utility class for doing synchronous calls to the server.  Provides several
+ * methods for sending a packet to the server and waiting for the reply.
+ * 
+ * @author Robin Collier
+ */
+final public class SyncPacketSend
+{
+	private SyncPacketSend()
+	{	}
+	
+	static public Packet getReply(Connection connection, Packet packet, long timeout)
+		throws XMPPException
+	{
+        PacketFilter responseFilter = new PacketIDFilter(packet.getPacketID());
+        PacketCollector response = connection.createPacketCollector(responseFilter);
+        
+        connection.sendPacket(packet);
+
+        // Wait up to a certain number of seconds for a reply.
+        Packet result = response.nextResult(timeout);
+
+        // Stop queuing results
+        response.cancel();
+
+        if (result == null) {
+            throw new XMPPException("No response from server.");
+        }
+        else if (result.getError() != null) {
+            throw new XMPPException(result.getError());
+        }
+        return result;
+	}
+
+	static public Packet getReply(Connection connection, Packet packet)
+		throws XMPPException
+	{
+		return getReply(connection, packet, SmackConfiguration.getPacketReplyTimeout());
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/AffiliationProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/AffiliationProvider.java
index 4e27c50..771c5e9 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/AffiliationProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/AffiliationProvider.java
@@ -1,37 +1,37 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.provider;
-
-import java.util.List;
-import java.util.Map;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
-import org.jivesoftware.smackx.pubsub.Affiliation;
-
-/**
- * Parses the affiliation element out of the reply stanza from the server
- * as specified in the <a href="http://xmpp.org/extensions/xep-0060.html#schemas-pubsub">affiliation schema</a>.
- * 
- * @author Robin Collier
- */
-public class AffiliationProvider extends EmbeddedExtensionProvider
-{
-	@Override
-	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content)
-	{
-		return new Affiliation(attributeMap.get("node"), Affiliation.Type.valueOf(attributeMap.get("affiliation")));
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.provider;
+
+import java.util.List;
+import java.util.Map;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
+import org.jivesoftware.smackx.pubsub.Affiliation;
+
+/**
+ * Parses the affiliation element out of the reply stanza from the server
+ * as specified in the <a href="http://xmpp.org/extensions/xep-0060.html#schemas-pubsub">affiliation schema</a>.
+ * 
+ * @author Robin Collier
+ */
+public class AffiliationProvider extends EmbeddedExtensionProvider
+{
+	@Override
+	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content)
+	{
+		return new Affiliation(attributeMap.get("node"), Affiliation.Type.valueOf(attributeMap.get("affiliation")));
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/AffiliationsProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/AffiliationsProvider.java
index 9bfeb81..0ccd596 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/AffiliationsProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/AffiliationsProvider.java
@@ -1,38 +1,38 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.pubsub.provider;
-
-import java.util.List;
-import java.util.Map;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
-import org.jivesoftware.smackx.pubsub.Affiliation;
-import org.jivesoftware.smackx.pubsub.AffiliationsExtension;
-
-/**
- * Parses the affiliations element out of the reply stanza from the server
- * as specified in the <a href="http://xmpp.org/extensions/xep-0060.html#schemas-pubsub">affiliation schema</a>.
- * 
- * @author Robin Collier
- */public class AffiliationsProvider extends EmbeddedExtensionProvider
-{
-	@Override
-	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content)
-	{
-        return new AffiliationsExtension((List<Affiliation>)content);
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.pubsub.provider;
+
+import java.util.List;
+import java.util.Map;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
+import org.jivesoftware.smackx.pubsub.Affiliation;
+import org.jivesoftware.smackx.pubsub.AffiliationsExtension;
+
+/**
+ * Parses the affiliations element out of the reply stanza from the server
+ * as specified in the <a href="http://xmpp.org/extensions/xep-0060.html#schemas-pubsub">affiliation schema</a>.
+ * 
+ * @author Robin Collier
+ */public class AffiliationsProvider extends EmbeddedExtensionProvider
+{
+	@Override
+	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content)
+	{
+        return new AffiliationsExtension((List<Affiliation>)content);
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/ConfigEventProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/ConfigEventProvider.java
index 30e3017..5c1d88d 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/ConfigEventProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/ConfigEventProvider.java
@@ -1,42 +1,42 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.pubsub.provider;
-
-import java.util.List;
-import java.util.Map;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smackx.packet.DataForm;
-import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
-import org.jivesoftware.smackx.pubsub.ConfigurationEvent;
-import org.jivesoftware.smackx.pubsub.ConfigureForm;
-
-/**
- * Parses the node configuration element out of the message event stanza from 
- * the server as specified in the <a href="http://xmpp.org/extensions/xep-0060.html#schemas-event">configuration schema</a>.
- * 
- * @author Robin Collier
- */
-public class ConfigEventProvider extends EmbeddedExtensionProvider
-{
-	@Override
-	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attMap, List<? extends PacketExtension> content)
-	{
-		if (content.size() == 0)
-			return new ConfigurationEvent(attMap.get("node"));
-		else
-			return new ConfigurationEvent(attMap.get("node"), new ConfigureForm((DataForm)content.iterator().next()));
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.pubsub.provider;
+
+import java.util.List;
+import java.util.Map;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smackx.packet.DataForm;
+import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
+import org.jivesoftware.smackx.pubsub.ConfigurationEvent;
+import org.jivesoftware.smackx.pubsub.ConfigureForm;
+
+/**
+ * Parses the node configuration element out of the message event stanza from 
+ * the server as specified in the <a href="http://xmpp.org/extensions/xep-0060.html#schemas-event">configuration schema</a>.
+ * 
+ * @author Robin Collier
+ */
+public class ConfigEventProvider extends EmbeddedExtensionProvider
+{
+	@Override
+	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attMap, List<? extends PacketExtension> content)
+	{
+		if (content.size() == 0)
+			return new ConfigurationEvent(attMap.get("node"));
+		else
+			return new ConfigurationEvent(attMap.get("node"), new ConfigureForm((DataForm)content.iterator().next()));
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/EventProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/EventProvider.java
index ef5671e..b216335 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/EventProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/EventProvider.java
@@ -1,38 +1,38 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.provider;
-
-import java.util.List;
-import java.util.Map;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
-import org.jivesoftware.smackx.pubsub.EventElement;
-import org.jivesoftware.smackx.pubsub.EventElementType;
-import org.jivesoftware.smackx.pubsub.NodeExtension;
-
-/**
- * Parses the event element out of the message stanza from 
- * the server as specified in the <a href="http://xmpp.org/extensions/xep-0060.html#schemas-event">event schema</a>.
- * 
- * @author Robin Collier
- */
-public class EventProvider extends EmbeddedExtensionProvider
-{
-	@Override
-	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attMap, List<? extends PacketExtension> content)
-	{
-	   	return new EventElement(EventElementType.valueOf(content.get(0).getElementName()), (NodeExtension)content.get(0));
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.provider;
+
+import java.util.List;
+import java.util.Map;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
+import org.jivesoftware.smackx.pubsub.EventElement;
+import org.jivesoftware.smackx.pubsub.EventElementType;
+import org.jivesoftware.smackx.pubsub.NodeExtension;
+
+/**
+ * Parses the event element out of the message stanza from 
+ * the server as specified in the <a href="http://xmpp.org/extensions/xep-0060.html#schemas-event">event schema</a>.
+ * 
+ * @author Robin Collier
+ */
+public class EventProvider extends EmbeddedExtensionProvider
+{
+	@Override
+	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attMap, List<? extends PacketExtension> content)
+	{
+	   	return new EventElement(EventElementType.valueOf(content.get(0).getElementName()), (NodeExtension)content.get(0));
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/FormNodeProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/FormNodeProvider.java
index da75b24..5a11529 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/FormNodeProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/FormNodeProvider.java
@@ -1,39 +1,39 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.provider;
-
-import java.util.List;
-import java.util.Map;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smackx.Form;
-import org.jivesoftware.smackx.packet.DataForm;
-import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
-import org.jivesoftware.smackx.pubsub.FormNode;
-import org.jivesoftware.smackx.pubsub.FormNodeType;
-
-/**
- * Parses one of several elements used in pubsub that contain a form of some kind as a child element.  The
- * elements and namespaces supported is defined in {@link FormNodeType}.
- * 
- * @author Robin Collier
- */
-public class FormNodeProvider extends EmbeddedExtensionProvider
-{
-	@Override
-	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content)
-	{
-        return new FormNode(FormNodeType.valueOfFromElementName(currentElement, currentNamespace), attributeMap.get("node"), new Form((DataForm)content.iterator().next()));
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.provider;
+
+import java.util.List;
+import java.util.Map;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smackx.Form;
+import org.jivesoftware.smackx.packet.DataForm;
+import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
+import org.jivesoftware.smackx.pubsub.FormNode;
+import org.jivesoftware.smackx.pubsub.FormNodeType;
+
+/**
+ * Parses one of several elements used in pubsub that contain a form of some kind as a child element.  The
+ * elements and namespaces supported is defined in {@link FormNodeType}.
+ * 
+ * @author Robin Collier
+ */
+public class FormNodeProvider extends EmbeddedExtensionProvider
+{
+	@Override
+	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content)
+	{
+        return new FormNode(FormNodeType.valueOfFromElementName(currentElement, currentNamespace), attributeMap.get("node"), new Form((DataForm)content.iterator().next()));
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java
index 7b06af3..b1cbd2b 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java
@@ -1,109 +1,109 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.provider;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.jivesoftware.smack.provider.ProviderManager;
-import org.jivesoftware.smack.util.PacketParserUtils;
-import org.jivesoftware.smackx.pubsub.Item;
-import org.jivesoftware.smackx.pubsub.PayloadItem;
-import org.jivesoftware.smackx.pubsub.SimplePayload;
-import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * Parses an <b>item</b> element as is defined in both the {@link PubSubNamespace#BASIC} and
- * {@link PubSubNamespace#EVENT} namespaces. To parse the item contents, it will use whatever
- * {@link PacketExtensionProvider} is registered in <b>smack.providers</b> for its element name and namespace. If no
- * provider is registered, it will return a {@link SimplePayload}.
- * 
- * @author Robin Collier
- */
-public class ItemProvider implements PacketExtensionProvider 
-{
-    public PacketExtension parseExtension(XmlPullParser parser) throws Exception 
-    {
-        String id = parser.getAttributeValue(null, "id");
-        String node = parser.getAttributeValue(null, "node");
-        String elem = parser.getName();
-
-        int tag = parser.next();
-
-        if (tag == XmlPullParser.END_TAG) 
-        {
-            return new Item(id, node);
-        }
-        else 
-        {
-            String payloadElemName = parser.getName();
-            String payloadNS = parser.getNamespace();
-
-            if (ProviderManager.getInstance().getExtensionProvider(payloadElemName, payloadNS) == null) 
-            {
-                boolean done = false;
-                boolean isEmptyElement = false;
-                StringBuilder payloadText = new StringBuilder();
-
-                while (!done) 
-                {
-                    if (tag == XmlPullParser.END_TAG && parser.getName().equals(elem)) 
-                    {
-                        done = true;
-                    }
-                    else if (parser.getEventType() == XmlPullParser.START_TAG) 
-                    {
-                        payloadText.append("<").append(parser.getName());
-
-                        if (parser.getName().equals(payloadElemName) && (payloadNS.length() > 0))
-                            payloadText.append(" xmlns=\"").append(payloadNS).append("\"");
-                        int n = parser.getAttributeCount();
-
-                        for (int i = 0; i < n; i++) 
-                            payloadText.append(" ").append(parser.getAttributeName(i)).append("=\"")
-                                    .append(parser.getAttributeValue(i)).append("\"");
-
-                        if (parser.isEmptyElementTag()) 
-                        {
-                            payloadText.append("/>");
-                            isEmptyElement = true;
-                        }
-                        else 
-                        {
-                            payloadText.append(">");
-                        }
-                    }
-                    else if (parser.getEventType() == XmlPullParser.END_TAG) 
-                    {
-                        if (isEmptyElement) 
-                            isEmptyElement = false;
-                        else 
-                            payloadText.append("</").append(parser.getName()).append(">");
-                    }
-                    else if (parser.getEventType() == XmlPullParser.TEXT) 
-                    {
-                        payloadText.append(parser.getText());
-                    }
-                    tag = parser.next();
-                }
-                return new PayloadItem<SimplePayload>(id, node, new SimplePayload(payloadElemName, payloadNS, payloadText.toString()));
-            }
-            else {
-                return new PayloadItem<PacketExtension>(id, node, PacketParserUtils.parsePacketExtension(
-                        payloadElemName, payloadNS, parser));
-            }
-        }
-    }
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.provider;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.jivesoftware.smack.provider.ProviderManager;
+import org.jivesoftware.smack.util.PacketParserUtils;
+import org.jivesoftware.smackx.pubsub.Item;
+import org.jivesoftware.smackx.pubsub.PayloadItem;
+import org.jivesoftware.smackx.pubsub.SimplePayload;
+import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * Parses an <b>item</b> element as is defined in both the {@link PubSubNamespace#BASIC} and
+ * {@link PubSubNamespace#EVENT} namespaces. To parse the item contents, it will use whatever
+ * {@link PacketExtensionProvider} is registered in <b>smack.providers</b> for its element name and namespace. If no
+ * provider is registered, it will return a {@link SimplePayload}.
+ * 
+ * @author Robin Collier
+ */
+public class ItemProvider implements PacketExtensionProvider 
+{
+    public PacketExtension parseExtension(XmlPullParser parser) throws Exception 
+    {
+        String id = parser.getAttributeValue(null, "id");
+        String node = parser.getAttributeValue(null, "node");
+        String elem = parser.getName();
+
+        int tag = parser.next();
+
+        if (tag == XmlPullParser.END_TAG) 
+        {
+            return new Item(id, node);
+        }
+        else 
+        {
+            String payloadElemName = parser.getName();
+            String payloadNS = parser.getNamespace();
+
+            if (ProviderManager.getInstance().getExtensionProvider(payloadElemName, payloadNS) == null) 
+            {
+                boolean done = false;
+                boolean isEmptyElement = false;
+                StringBuilder payloadText = new StringBuilder();
+
+                while (!done) 
+                {
+                    if (tag == XmlPullParser.END_TAG && parser.getName().equals(elem)) 
+                    {
+                        done = true;
+                    }
+                    else if (parser.getEventType() == XmlPullParser.START_TAG) 
+                    {
+                        payloadText.append("<").append(parser.getName());
+
+                        if (parser.getName().equals(payloadElemName) && (payloadNS.length() > 0))
+                            payloadText.append(" xmlns=\"").append(payloadNS).append("\"");
+                        int n = parser.getAttributeCount();
+
+                        for (int i = 0; i < n; i++) 
+                            payloadText.append(" ").append(parser.getAttributeName(i)).append("=\"")
+                                    .append(parser.getAttributeValue(i)).append("\"");
+
+                        if (parser.isEmptyElementTag()) 
+                        {
+                            payloadText.append("/>");
+                            isEmptyElement = true;
+                        }
+                        else 
+                        {
+                            payloadText.append(">");
+                        }
+                    }
+                    else if (parser.getEventType() == XmlPullParser.END_TAG) 
+                    {
+                        if (isEmptyElement) 
+                            isEmptyElement = false;
+                        else 
+                            payloadText.append("</").append(parser.getName()).append(">");
+                    }
+                    else if (parser.getEventType() == XmlPullParser.TEXT) 
+                    {
+                        payloadText.append(parser.getText());
+                    }
+                    tag = parser.next();
+                }
+                return new PayloadItem<SimplePayload>(id, node, new SimplePayload(payloadElemName, payloadNS, payloadText.toString()));
+            }
+            else {
+                return new PayloadItem<PacketExtension>(id, node, PacketParserUtils.parsePacketExtension(
+                        payloadElemName, payloadNS, parser));
+            }
+        }
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/ItemsProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/ItemsProvider.java
index 01cb9d4..5657dd3 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/ItemsProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/ItemsProvider.java
@@ -1,38 +1,38 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.provider;
-
-import java.util.List;
-import java.util.Map;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
-import org.jivesoftware.smackx.pubsub.ItemsExtension;
-
-/**
- * Parses the <b>items</b> element out of the message event stanza from 
- * the server as specified in the <a href="http://xmpp.org/extensions/xep-0060.html#schemas-event">items schema</a>.
- * 
- * @author Robin Collier
- */
-public class ItemsProvider extends EmbeddedExtensionProvider
-{
-
-	@Override
-	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content)
-	{
-        return new ItemsExtension(ItemsExtension.ItemsElementType.items, attributeMap.get("node"), content);
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.provider;
+
+import java.util.List;
+import java.util.Map;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
+import org.jivesoftware.smackx.pubsub.ItemsExtension;
+
+/**
+ * Parses the <b>items</b> element out of the message event stanza from 
+ * the server as specified in the <a href="http://xmpp.org/extensions/xep-0060.html#schemas-event">items schema</a>.
+ * 
+ * @author Robin Collier
+ */
+public class ItemsProvider extends EmbeddedExtensionProvider
+{
+
+	@Override
+	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content)
+	{
+        return new ItemsExtension(ItemsExtension.ItemsElementType.items, attributeMap.get("node"), content);
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/PubSubProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/PubSubProvider.java
index 742f219..3fd34f5 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/PubSubProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/PubSubProvider.java
@@ -1,62 +1,62 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.provider;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.jivesoftware.smack.util.PacketParserUtils;
-import org.jivesoftware.smackx.pubsub.packet.PubSub;
-import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * Parses the root pubsub packet extensions of the {@link IQ} packet and returns
- * a {@link PubSub} instance.
- * 
- * @author Robin Collier
- */
-public class PubSubProvider implements IQProvider
-{
-	public IQ parseIQ(XmlPullParser parser) throws Exception
-	{
-        PubSub pubsub = new PubSub();
-        String namespace = parser.getNamespace();
-        pubsub.setPubSubNamespace(PubSubNamespace.valueOfFromXmlns(namespace));
-        boolean done = false;
-
-        while (!done) 
-        {
-            int eventType = parser.next();
-            
-            if (eventType == XmlPullParser.START_TAG) 
-            {
-            	PacketExtension ext = PacketParserUtils.parsePacketExtension(parser.getName(), namespace, parser);
-            	
-            	if (ext != null)
-            	{
-            		pubsub.addExtension(ext);
-            	}
-            }
-            else if (eventType == XmlPullParser.END_TAG) 
-            {
-                if (parser.getName().equals("pubsub")) 
-                {
-                    done = true;
-                }
-            }
-        }
-        return pubsub;
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.provider;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.jivesoftware.smack.util.PacketParserUtils;
+import org.jivesoftware.smackx.pubsub.packet.PubSub;
+import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * Parses the root pubsub packet extensions of the {@link IQ} packet and returns
+ * a {@link PubSub} instance.
+ * 
+ * @author Robin Collier
+ */
+public class PubSubProvider implements IQProvider
+{
+	public IQ parseIQ(XmlPullParser parser) throws Exception
+	{
+        PubSub pubsub = new PubSub();
+        String namespace = parser.getNamespace();
+        pubsub.setPubSubNamespace(PubSubNamespace.valueOfFromXmlns(namespace));
+        boolean done = false;
+
+        while (!done) 
+        {
+            int eventType = parser.next();
+            
+            if (eventType == XmlPullParser.START_TAG) 
+            {
+            	PacketExtension ext = PacketParserUtils.parsePacketExtension(parser.getName(), namespace, parser);
+            	
+            	if (ext != null)
+            	{
+            		pubsub.addExtension(ext);
+            	}
+            }
+            else if (eventType == XmlPullParser.END_TAG) 
+            {
+                if (parser.getName().equals("pubsub")) 
+                {
+                    done = true;
+                }
+            }
+        }
+        return pubsub;
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/RetractEventProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/RetractEventProvider.java
index 8fa3337..f182de8 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/RetractEventProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/RetractEventProvider.java
@@ -1,38 +1,38 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.provider;
-
-import java.util.List;
-import java.util.Map;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
-import org.jivesoftware.smackx.pubsub.RetractItem;
-
-/**
- * Parses the <b>retract</b> element out of the message event stanza from 
- * the server as specified in the <a href="http://xmpp.org/extensions/xep-0060.html#schemas-event">retract schema</a>.
- * This element is a child of the <b>items</b> element.
- * 
- * @author Robin Collier
- */
-public class RetractEventProvider extends EmbeddedExtensionProvider
-{
-	@Override
-	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content)
-	{
-		return new RetractItem(attributeMap.get("id"));
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.provider;
+
+import java.util.List;
+import java.util.Map;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
+import org.jivesoftware.smackx.pubsub.RetractItem;
+
+/**
+ * Parses the <b>retract</b> element out of the message event stanza from 
+ * the server as specified in the <a href="http://xmpp.org/extensions/xep-0060.html#schemas-event">retract schema</a>.
+ * This element is a child of the <b>items</b> element.
+ * 
+ * @author Robin Collier
+ */
+public class RetractEventProvider extends EmbeddedExtensionProvider
+{
+	@Override
+	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content)
+	{
+		return new RetractItem(attributeMap.get("id"));
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/SimpleNodeProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/SimpleNodeProvider.java
index d2b7d30..b57f04a 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/SimpleNodeProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/SimpleNodeProvider.java
@@ -1,37 +1,37 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.provider;
-
-import java.util.List;
-import java.util.Map;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
-import org.jivesoftware.smackx.pubsub.NodeExtension;
-import org.jivesoftware.smackx.pubsub.PubSubElementType;
-
-/**
- * Parses simple elements that only contain a <b>node</b> attribute.  This is common amongst many of the 
- * elements defined in the pubsub specification.  For this common case a {@link NodeExtension} is returned. 
- * 
- * @author Robin Collier
- */
-public class SimpleNodeProvider extends EmbeddedExtensionProvider
-{
-	@Override
-	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content)
-	{
-        return new NodeExtension(PubSubElementType.valueOfFromElemName(currentElement, currentNamespace), attributeMap.get("node"));
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.provider;
+
+import java.util.List;
+import java.util.Map;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
+import org.jivesoftware.smackx.pubsub.NodeExtension;
+import org.jivesoftware.smackx.pubsub.PubSubElementType;
+
+/**
+ * Parses simple elements that only contain a <b>node</b> attribute.  This is common amongst many of the 
+ * elements defined in the pubsub specification.  For this common case a {@link NodeExtension} is returned. 
+ * 
+ * @author Robin Collier
+ */
+public class SimpleNodeProvider extends EmbeddedExtensionProvider
+{
+	@Override
+	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content)
+	{
+        return new NodeExtension(PubSubElementType.valueOfFromElemName(currentElement, currentNamespace), attributeMap.get("node"));
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/SubscriptionProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/SubscriptionProvider.java
index eccbe08..a35e6a1 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/SubscriptionProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/SubscriptionProvider.java
@@ -1,52 +1,52 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.provider;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.jivesoftware.smackx.pubsub.Subscription;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * Parses the <b>subscription</b> element out of the pubsub IQ message from 
- * the server as specified in the <a href="http://xmpp.org/extensions/xep-0060.html#schemas-pubsub">subscription schema</a>.
- * 
- * @author Robin Collier
- */
-public class SubscriptionProvider implements PacketExtensionProvider
-{
-	public PacketExtension parseExtension(XmlPullParser parser) throws Exception
-	{
-		String jid = parser.getAttributeValue(null, "jid");
-		String nodeId = parser.getAttributeValue(null, "node");
-		String subId = parser.getAttributeValue(null, "subid");
-		String state = parser.getAttributeValue(null, "subscription");
-		boolean isRequired = false;
-
-		int tag = parser.next();
-		
-		if ((tag == XmlPullParser.START_TAG) && parser.getName().equals("subscribe-options"))
-		{
-			tag = parser.next();
-			
-			if ((tag == XmlPullParser.START_TAG) && parser.getName().equals("required"))
-				isRequired = true;
-			
-			while (parser.next() != XmlPullParser.END_TAG && parser.getName() != "subscribe-options");
-		}
-		while (parser.getEventType() != XmlPullParser.END_TAG) parser.next();
-		return new Subscription(jid, nodeId, subId, (state == null ? null : Subscription.State.valueOf(state)), isRequired);
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.provider;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.jivesoftware.smackx.pubsub.Subscription;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * Parses the <b>subscription</b> element out of the pubsub IQ message from 
+ * the server as specified in the <a href="http://xmpp.org/extensions/xep-0060.html#schemas-pubsub">subscription schema</a>.
+ * 
+ * @author Robin Collier
+ */
+public class SubscriptionProvider implements PacketExtensionProvider
+{
+	public PacketExtension parseExtension(XmlPullParser parser) throws Exception
+	{
+		String jid = parser.getAttributeValue(null, "jid");
+		String nodeId = parser.getAttributeValue(null, "node");
+		String subId = parser.getAttributeValue(null, "subid");
+		String state = parser.getAttributeValue(null, "subscription");
+		boolean isRequired = false;
+
+		int tag = parser.next();
+		
+		if ((tag == XmlPullParser.START_TAG) && parser.getName().equals("subscribe-options"))
+		{
+			tag = parser.next();
+			
+			if ((tag == XmlPullParser.START_TAG) && parser.getName().equals("required"))
+				isRequired = true;
+			
+			while (parser.next() != XmlPullParser.END_TAG && parser.getName() != "subscribe-options");
+		}
+		while (parser.getEventType() != XmlPullParser.END_TAG) parser.next();
+		return new Subscription(jid, nodeId, subId, (state == null ? null : Subscription.State.valueOf(state)), isRequired);
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/SubscriptionsProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/SubscriptionsProvider.java
index 94dc61d..3b2aabb 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/SubscriptionsProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/provider/SubscriptionsProvider.java
@@ -1,38 +1,38 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.provider;
-
-import java.util.List;
-import java.util.Map;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
-import org.jivesoftware.smackx.pubsub.Subscription;
-import org.jivesoftware.smackx.pubsub.SubscriptionsExtension;
-
-/**
- * Parses the <b>subscriptions</b> element out of the pubsub IQ message from 
- * the server as specified in the <a href="http://xmpp.org/extensions/xep-0060.html#schemas-pubsub">subscriptions schema</a>.
- * 
- * @author Robin Collier
- */
-public class SubscriptionsProvider extends EmbeddedExtensionProvider
-{
-	@Override
-	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content)
-	{
-		return new SubscriptionsExtension(attributeMap.get("node"), (List<Subscription>)content);
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.provider;
+
+import java.util.List;
+import java.util.Map;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
+import org.jivesoftware.smackx.pubsub.Subscription;
+import org.jivesoftware.smackx.pubsub.SubscriptionsExtension;
+
+/**
+ * Parses the <b>subscriptions</b> element out of the pubsub IQ message from 
+ * the server as specified in the <a href="http://xmpp.org/extensions/xep-0060.html#schemas-pubsub">subscriptions schema</a>.
+ * 
+ * @author Robin Collier
+ */
+public class SubscriptionsProvider extends EmbeddedExtensionProvider
+{
+	@Override
+	protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content)
+	{
+		return new SubscriptionsExtension(attributeMap.get("node"), (List<Subscription>)content);
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/util/NodeUtils.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/util/NodeUtils.java
index 414601f..48cafa7 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/util/NodeUtils.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/util/NodeUtils.java
@@ -1,43 +1,43 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.util;
-
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smackx.Form;
-import org.jivesoftware.smackx.pubsub.ConfigureForm;
-import org.jivesoftware.smackx.pubsub.FormNode;
-import org.jivesoftware.smackx.pubsub.PubSubElementType;
-
-/**
- * Utility for extracting information from packets.
- * 
- * @author Robin Collier
- */
-public class NodeUtils
-{
-	/** 
-	 * Get a {@link ConfigureForm} from a packet.
-	 * 
-	 * @param packet
-	 * @param elem
-	 * @return The configuration form
-	 */
-	public static ConfigureForm getFormFromPacket(Packet packet, PubSubElementType elem)
-	{
-		FormNode config = (FormNode)packet.getExtension(elem.getElementName(), elem.getNamespace().getXmlns());
-		Form formReply = config.getForm();
-		return new ConfigureForm(formReply);
-
-	}
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.util;
+
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smackx.Form;
+import org.jivesoftware.smackx.pubsub.ConfigureForm;
+import org.jivesoftware.smackx.pubsub.FormNode;
+import org.jivesoftware.smackx.pubsub.PubSubElementType;
+
+/**
+ * Utility for extracting information from packets.
+ * 
+ * @author Robin Collier
+ */
+public class NodeUtils
+{
+	/** 
+	 * Get a {@link ConfigureForm} from a packet.
+	 * 
+	 * @param packet
+	 * @param elem
+	 * @return The configuration form
+	 */
+	public static ConfigureForm getFormFromPacket(Packet packet, PubSubElementType elem)
+	{
+		FormNode config = (FormNode)packet.getExtension(elem.getElementName(), elem.getNamespace().getXmlns());
+		Form formReply = config.getForm();
+		return new ConfigureForm(formReply);
+
+	}
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/util/XmlUtils.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/util/XmlUtils.java
index f594871..c42e373 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/util/XmlUtils.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/pubsub/util/XmlUtils.java
@@ -1,67 +1,67 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.pubsub.util;
-
-import java.io.StringReader;
-
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
-
-/**
- * Simple utility for pretty printing xml.
- * 
- * @author Robin Collier
- */
-public class XmlUtils
-{
-	/**
-	 * 
-	 * @param header Just a title for the stanza for readability.  Single word no spaces since
-	 * it is inserted as the root element in the output.
-	 * @param xml The string to pretty print
-	 */
-	static public void prettyPrint(String header, String xml)
-	{
-		try
-		{
-			Transformer transformer = TransformerFactory.newInstance().newTransformer();
-			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
-			transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "3");
-
-			if (header != null)
-			{
-				xml = "\n<" + header + ">" + xml + "</" + header + '>';
-			}
-			transformer.transform(new StreamSource(new StringReader(xml)), new StreamResult(System.out));
-		}
-		catch (Exception e)
-		{
-			System.out.println("Something wrong with xml in \n---------------\n" + xml + "\n---------------");
-			e.printStackTrace();
-		}
-	}
-
-	static public void appendAttribute(StringBuilder builder, String att, String value)
-	{
-		builder.append(" ");
-		builder.append(att);
-		builder.append("='");
-		builder.append(value);
-		builder.append("'");
-	}
-
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.util;
+
+import java.io.StringReader;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+/**
+ * Simple utility for pretty printing xml.
+ * 
+ * @author Robin Collier
+ */
+public class XmlUtils
+{
+	/**
+	 * 
+	 * @param header Just a title for the stanza for readability.  Single word no spaces since
+	 * it is inserted as the root element in the output.
+	 * @param xml The string to pretty print
+	 */
+	static public void prettyPrint(String header, String xml)
+	{
+		try
+		{
+			Transformer transformer = TransformerFactory.newInstance().newTransformer();
+			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+			transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "3");
+
+			if (header != null)
+			{
+				xml = "\n<" + header + ">" + xml + "</" + header + '>';
+			}
+			transformer.transform(new StreamSource(new StringReader(xml)), new StreamResult(System.out));
+		}
+		catch (Exception e)
+		{
+			System.out.println("Something wrong with xml in \n---------------\n" + xml + "\n---------------");
+			e.printStackTrace();
+		}
+	}
+
+	static public void appendAttribute(StringBuilder builder, String att, String value)
+	{
+		builder.append(" ");
+		builder.append(att);
+		builder.append("='");
+		builder.append(value);
+		builder.append("'");
+	}
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/receipts/DeliveryReceipt.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/receipts/DeliveryReceipt.java
index 9020556..d58fab2 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/receipts/DeliveryReceipt.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/receipts/DeliveryReceipt.java
@@ -1,77 +1,77 @@
-/**
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.receipts;
-
-import java.util.List;
-import java.util.Map;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.EmbeddedExtensionProvider;
-
-/**
- * Represents a <b>message delivery receipt</b> entry as specified by
- * <a href="http://xmpp.org/extensions/xep-0184.html">Message Delivery Receipts</a>.
- *
- * @author Georg Lukas
- */
-public class DeliveryReceipt implements PacketExtension
-{
-    public static final String NAMESPACE = "urn:xmpp:receipts";
-    public static final String ELEMENT = "received";
-
-    private String id; /// original ID of the delivered message
-
-    public DeliveryReceipt(String id)
-    {
-        this.id = id;
-    }
-
-    public String getId()
-    {
-        return id;
-    }
-
-    @Override
-    public String getElementName()
-    {
-        return ELEMENT;
-    }
-
-    @Override
-    public String getNamespace()
-    {
-        return NAMESPACE;
-    }
-
-    @Override
-    public String toXML()
-    {
-        return "<received xmlns='" + NAMESPACE + "' id='" + id + "'/>";
-    }
-
-    /**
-     * This Provider parses and returns DeliveryReceipt packets.
-     */
-    public static class Provider extends EmbeddedExtensionProvider
-    {
-
-        @Override
-        protected PacketExtension createReturnExtension(String currentElement, String currentNamespace,
-                Map<String, String> attributeMap, List<? extends PacketExtension> content)
-        {
-            return new DeliveryReceipt(attributeMap.get("id"));
-        }
-
-    }
-}
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.receipts;
+
+import java.util.List;
+import java.util.Map;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.EmbeddedExtensionProvider;
+
+/**
+ * Represents a <b>message delivery receipt</b> entry as specified by
+ * <a href="http://xmpp.org/extensions/xep-0184.html">Message Delivery Receipts</a>.
+ *
+ * @author Georg Lukas
+ */
+public class DeliveryReceipt implements PacketExtension
+{
+    public static final String NAMESPACE = "urn:xmpp:receipts";
+    public static final String ELEMENT = "received";
+
+    private String id; /// original ID of the delivered message
+
+    public DeliveryReceipt(String id)
+    {
+        this.id = id;
+    }
+
+    public String getId()
+    {
+        return id;
+    }
+
+    @Override
+    public String getElementName()
+    {
+        return ELEMENT;
+    }
+
+    @Override
+    public String getNamespace()
+    {
+        return NAMESPACE;
+    }
+
+    @Override
+    public String toXML()
+    {
+        return "<received xmlns='" + NAMESPACE + "' id='" + id + "'/>";
+    }
+
+    /**
+     * This Provider parses and returns DeliveryReceipt packets.
+     */
+    public static class Provider extends EmbeddedExtensionProvider
+    {
+
+        @Override
+        protected PacketExtension createReturnExtension(String currentElement, String currentNamespace,
+                Map<String, String> attributeMap, List<? extends PacketExtension> content)
+        {
+            return new DeliveryReceipt(attributeMap.get("id"));
+        }
+
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/receipts/DeliveryReceiptRequest.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/receipts/DeliveryReceiptRequest.java
index 1b5ed3b..28bd0c8 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/receipts/DeliveryReceiptRequest.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/receipts/DeliveryReceiptRequest.java
@@ -1,54 +1,54 @@
-/*
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.receipts;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * Represents a <b>message delivery receipt request</b> entry as specified by
- * <a href="http://xmpp.org/extensions/xep-0184.html">Message Delivery Receipts</a>.
- *
- * @author Georg Lukas
- */
-public class DeliveryReceiptRequest implements PacketExtension
-{
-    public static final String ELEMENT = "request";
-
-    public String getElementName()
-    {
-        return ELEMENT;
-    }
-
-    public String getNamespace()
-    {
-        return DeliveryReceipt.NAMESPACE;
-    }
-
-    public String toXML()
-    {
-        return "<request xmlns='" + DeliveryReceipt.NAMESPACE + "'/>";
-    }
-
-    /**
-     * This Provider parses and returns DeliveryReceiptRequest packets.
-     */
-    public static class Provider implements PacketExtensionProvider {
-        @Override
-        public PacketExtension parseExtension(XmlPullParser parser) {
-            return new DeliveryReceiptRequest();
-        }
-    }
-}
+/*
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.receipts;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * Represents a <b>message delivery receipt request</b> entry as specified by
+ * <a href="http://xmpp.org/extensions/xep-0184.html">Message Delivery Receipts</a>.
+ *
+ * @author Georg Lukas
+ */
+public class DeliveryReceiptRequest implements PacketExtension
+{
+    public static final String ELEMENT = "request";
+
+    public String getElementName()
+    {
+        return ELEMENT;
+    }
+
+    public String getNamespace()
+    {
+        return DeliveryReceipt.NAMESPACE;
+    }
+
+    public String toXML()
+    {
+        return "<request xmlns='" + DeliveryReceipt.NAMESPACE + "'/>";
+    }
+
+    /**
+     * This Provider parses and returns DeliveryReceiptRequest packets.
+     */
+    public static class Provider implements PacketExtensionProvider {
+        @Override
+        public PacketExtension parseExtension(XmlPullParser parser) {
+            return new DeliveryReceiptRequest();
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/receipts/ReceiptReceivedListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/receipts/ReceiptReceivedListener.java
index 3183113..4f613d3 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/receipts/ReceiptReceivedListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/receipts/ReceiptReceivedListener.java
@@ -1,26 +1,26 @@
-/**
- * Copyright 2013 Georg Lukas
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.receipts;
-
-/**
- * Interface for received receipt notifications.
- * 
- * Implement this and add a listener to get notified. 
- */
-public interface ReceiptReceivedListener {
-    void onReceiptReceived(String fromJid, String toJid, String receiptId);
+/**
+ * Copyright 2013 Georg Lukas
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.receipts;
+
+/**
+ * Interface for received receipt notifications.
+ * 
+ * Implement this and add a listener to get notified. 
+ */
+public interface ReceiptReceivedListener {
+    void onReceiptReceived(String fromJid, String toJid, String receiptId);
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/MetaData.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/MetaData.java
index 115a79c..707bcb5 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/MetaData.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/MetaData.java
@@ -1,68 +1,68 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup;
-
-import java.util.List;
-import java.util.Map;
-
-import org.jivesoftware.smackx.workgroup.util.MetaDataUtils;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-
-/**
- * MetaData packet extension.
- */
-public class MetaData implements PacketExtension {
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "metadata";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
-
-    private Map<String, List<String>> metaData;
-
-    public MetaData(Map<String, List<String>> metaData) {
-        this.metaData = metaData;
-    }
-
-    /**
-     * @return the Map of metadata contained by this instance
-     */
-    public Map<String, List<String>> getMetaData() {
-        return metaData;
-    }
-
-    public String getElementName() {
-        return ELEMENT_NAME;
-    }
-
-    public String getNamespace() {
-        return NAMESPACE;
-    }
-
-    public String toXML() {
-        return MetaDataUtils.serializeMetaData(this.getMetaData());
-    }
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup;
+
+import java.util.List;
+import java.util.Map;
+
+import org.jivesoftware.smackx.workgroup.util.MetaDataUtils;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+
+/**
+ * MetaData packet extension.
+ */
+public class MetaData implements PacketExtension {
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "metadata";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
+
+    private Map<String, List<String>> metaData;
+
+    public MetaData(Map<String, List<String>> metaData) {
+        this.metaData = metaData;
+    }
+
+    /**
+     * @return the Map of metadata contained by this instance
+     */
+    public Map<String, List<String>> getMetaData() {
+        return metaData;
+    }
+
+    public String getElementName() {
+        return ELEMENT_NAME;
+    }
+
+    public String getNamespace() {
+        return NAMESPACE;
+    }
+
+    public String toXML() {
+        return MetaDataUtils.serializeMetaData(this.getMetaData());
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/QueueUser.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/QueueUser.java
index 89a1899..da83061 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/QueueUser.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/QueueUser.java
@@ -1,85 +1,85 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup;
-
-import java.util.Date;
-
-/**
- * An immutable class which wraps up customer-in-queue data return from the server; depending on
- * the type of information dispatched from the server, not all information will be available in
- * any given instance.
- *
- * @author loki der quaeler
- */
-public class QueueUser {
-
-    private String userID;
-
-    private int queuePosition;
-    private int estimatedTime;
-    private Date joinDate;
-
-    /**
-     * @param uid the user jid of the customer in the queue
-     * @param position the position customer sits in the queue
-     * @param time the estimate of how much longer the customer will be in the queue in seconds
-     * @param joinedAt the timestamp of when the customer entered the queue
-     */
-    public QueueUser (String uid, int position, int time, Date joinedAt) {
-        super();
-
-        this.userID = uid;
-        this.queuePosition = position;
-        this.estimatedTime = time;
-        this.joinDate = joinedAt;
-    }
-
-    /**
-     * @return the user jid of the customer in the queue
-     */
-    public String getUserID () {
-        return this.userID;
-    }
-
-    /**
-     * @return the position in the queue at which the customer sits, or -1 if the update which
-     *          this instance embodies is only a time update instead
-     */
-    public int getQueuePosition () {
-        return this.queuePosition;
-    }
-
-    /**
-     * @return the estimated time remaining of the customer in the queue in seconds, or -1 if
-     *          if the update which this instance embodies is only a position update instead
-     */
-    public int getEstimatedRemainingTime () {
-        return this.estimatedTime;
-    }
-
-    /**
-     * @return the timestamp of when this customer entered the queue, or null if the server did not
-     *          provide this information
-     */
-    public Date getQueueJoinTimestamp () {
-        return this.joinDate;
-    }
-
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup;
+
+import java.util.Date;
+
+/**
+ * An immutable class which wraps up customer-in-queue data return from the server; depending on
+ * the type of information dispatched from the server, not all information will be available in
+ * any given instance.
+ *
+ * @author loki der quaeler
+ */
+public class QueueUser {
+
+    private String userID;
+
+    private int queuePosition;
+    private int estimatedTime;
+    private Date joinDate;
+
+    /**
+     * @param uid the user jid of the customer in the queue
+     * @param position the position customer sits in the queue
+     * @param time the estimate of how much longer the customer will be in the queue in seconds
+     * @param joinedAt the timestamp of when the customer entered the queue
+     */
+    public QueueUser (String uid, int position, int time, Date joinedAt) {
+        super();
+
+        this.userID = uid;
+        this.queuePosition = position;
+        this.estimatedTime = time;
+        this.joinDate = joinedAt;
+    }
+
+    /**
+     * @return the user jid of the customer in the queue
+     */
+    public String getUserID () {
+        return this.userID;
+    }
+
+    /**
+     * @return the position in the queue at which the customer sits, or -1 if the update which
+     *          this instance embodies is only a time update instead
+     */
+    public int getQueuePosition () {
+        return this.queuePosition;
+    }
+
+    /**
+     * @return the estimated time remaining of the customer in the queue in seconds, or -1 if
+     *          if the update which this instance embodies is only a position update instead
+     */
+    public int getEstimatedRemainingTime () {
+        return this.estimatedTime;
+    }
+
+    /**
+     * @return the timestamp of when this customer entered the queue, or null if the server did not
+     *          provide this information
+     */
+    public Date getQueueJoinTimestamp () {
+        return this.joinDate;
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/WorkgroupInvitation.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/WorkgroupInvitation.java
index ac3b5b6..10a84d5 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/WorkgroupInvitation.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/WorkgroupInvitation.java
@@ -1,134 +1,134 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * An immutable class wrapping up the basic information which comprises a group chat invitation.
- *
- * @author loki der quaeler
- */
-public class WorkgroupInvitation {
-
-    protected String uniqueID;
-
-    protected String sessionID;
-
-    protected String groupChatName;
-    protected String issuingWorkgroupName;
-    protected String messageBody;
-    protected String invitationSender;
-    protected Map<String, List<String>> metaData;
-
-    /**
-     * This calls the 5-argument constructor with a null MetaData argument value
-     *
-     * @param jid the jid string with which the issuing AgentSession or Workgroup instance
-     *                  was created
-     * @param group the jid of the room to which the person is invited
-     * @param workgroup the jid of the workgroup issuing the invitation
-     * @param sessID the session id associated with the pending chat
-     * @param msgBody the body of the message which contained the invitation
-     * @param from the user jid who issued the invitation, if known, null otherwise
-     */
-    public WorkgroupInvitation (String jid, String group, String workgroup,
-                       String sessID, String msgBody, String from) {
-        this(jid, group, workgroup, sessID, msgBody, from, null);
-    }
-
-    /**
-     * @param jid the jid string with which the issuing AgentSession or Workgroup instance
-     *                  was created
-     * @param group the jid of the room to which the person is invited
-     * @param workgroup the jid of the workgroup issuing the invitation
-     * @param sessID the session id associated with the pending chat
-     * @param msgBody the body of the message which contained the invitation
-     * @param from the user jid who issued the invitation, if known, null otherwise
-     * @param metaData the metadata sent with the invitation
-     */
-    public WorkgroupInvitation (String jid, String group, String workgroup, String sessID, String msgBody,
-                       String from, Map<String, List<String>> metaData) {
-        super();
-
-        this.uniqueID = jid;
-        this.sessionID = sessID;
-        this.groupChatName = group;
-        this.issuingWorkgroupName = workgroup;
-        this.messageBody = msgBody;
-        this.invitationSender = from;
-        this.metaData = metaData;
-    }
-
-    /**
-     * @return the jid string with which the issuing AgentSession or Workgroup instance
-     *  was created.
-     */
-    public String getUniqueID () {
-        return this.uniqueID;
-    }
-
-    /**
-     * @return the session id associated with the pending chat; working backwards temporally,
-     *              this session id should match the session id to the corresponding offer request
-     *              which resulted in this invitation.
-     */
-    public String getSessionID () {
-        return this.sessionID;
-    }
-
-    /**
-     * @return the jid of the room to which the person is invited.
-     */
-    public String getGroupChatName () {
-        return this.groupChatName;
-    }
-
-    /**
-     * @return the name of the workgroup from which the invitation was issued.
-     */
-    public String getWorkgroupName () {
-        return this.issuingWorkgroupName;
-    }
-
-    /**
-     * @return the contents of the body-block of the message that housed this invitation.
-     */
-    public String getMessageBody () {
-        return this.messageBody;
-    }
-
-    /**
-     * @return the user who issued the invitation, or null if it wasn't known.
-     */
-    public String getInvitationSender () {
-        return this.invitationSender;
-    }
-
-    /**
-     * @return the meta data associated with the invitation, or null if this instance was
-     *              constructed with none
-     */
-    public Map<String, List<String>> getMetaData () {
-        return this.metaData;
-    }
-
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An immutable class wrapping up the basic information which comprises a group chat invitation.
+ *
+ * @author loki der quaeler
+ */
+public class WorkgroupInvitation {
+
+    protected String uniqueID;
+
+    protected String sessionID;
+
+    protected String groupChatName;
+    protected String issuingWorkgroupName;
+    protected String messageBody;
+    protected String invitationSender;
+    protected Map<String, List<String>> metaData;
+
+    /**
+     * This calls the 5-argument constructor with a null MetaData argument value
+     *
+     * @param jid the jid string with which the issuing AgentSession or Workgroup instance
+     *                  was created
+     * @param group the jid of the room to which the person is invited
+     * @param workgroup the jid of the workgroup issuing the invitation
+     * @param sessID the session id associated with the pending chat
+     * @param msgBody the body of the message which contained the invitation
+     * @param from the user jid who issued the invitation, if known, null otherwise
+     */
+    public WorkgroupInvitation (String jid, String group, String workgroup,
+                       String sessID, String msgBody, String from) {
+        this(jid, group, workgroup, sessID, msgBody, from, null);
+    }
+
+    /**
+     * @param jid the jid string with which the issuing AgentSession or Workgroup instance
+     *                  was created
+     * @param group the jid of the room to which the person is invited
+     * @param workgroup the jid of the workgroup issuing the invitation
+     * @param sessID the session id associated with the pending chat
+     * @param msgBody the body of the message which contained the invitation
+     * @param from the user jid who issued the invitation, if known, null otherwise
+     * @param metaData the metadata sent with the invitation
+     */
+    public WorkgroupInvitation (String jid, String group, String workgroup, String sessID, String msgBody,
+                       String from, Map<String, List<String>> metaData) {
+        super();
+
+        this.uniqueID = jid;
+        this.sessionID = sessID;
+        this.groupChatName = group;
+        this.issuingWorkgroupName = workgroup;
+        this.messageBody = msgBody;
+        this.invitationSender = from;
+        this.metaData = metaData;
+    }
+
+    /**
+     * @return the jid string with which the issuing AgentSession or Workgroup instance
+     *  was created.
+     */
+    public String getUniqueID () {
+        return this.uniqueID;
+    }
+
+    /**
+     * @return the session id associated with the pending chat; working backwards temporally,
+     *              this session id should match the session id to the corresponding offer request
+     *              which resulted in this invitation.
+     */
+    public String getSessionID () {
+        return this.sessionID;
+    }
+
+    /**
+     * @return the jid of the room to which the person is invited.
+     */
+    public String getGroupChatName () {
+        return this.groupChatName;
+    }
+
+    /**
+     * @return the name of the workgroup from which the invitation was issued.
+     */
+    public String getWorkgroupName () {
+        return this.issuingWorkgroupName;
+    }
+
+    /**
+     * @return the contents of the body-block of the message that housed this invitation.
+     */
+    public String getMessageBody () {
+        return this.messageBody;
+    }
+
+    /**
+     * @return the user who issued the invitation, or null if it wasn't known.
+     */
+    public String getInvitationSender () {
+        return this.invitationSender;
+    }
+
+    /**
+     * @return the meta data associated with the invitation, or null if this instance was
+     *              constructed with none
+     */
+    public Map<String, List<String>> getMetaData () {
+        return this.metaData;
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/WorkgroupInvitationListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/WorkgroupInvitationListener.java
index bc73242..06634d7 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/WorkgroupInvitationListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/WorkgroupInvitationListener.java
@@ -1,39 +1,39 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup;
-
-/**
- * An interface which all classes interested in hearing about group chat invitations should
- *  implement.
- *
- * @author loki der quaeler
- */
-public interface WorkgroupInvitationListener {
-
-    /**
-     * The implementing class instance will be notified via this method when an invitation
-     *  to join a group chat has been received from the server.
-     *
-     * @param invitation an Invitation instance embodying the information pertaining to the
-     *                      invitation
-     */
-    public void invitationReceived(WorkgroupInvitation invitation);
-
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup;
+
+/**
+ * An interface which all classes interested in hearing about group chat invitations should
+ *  implement.
+ *
+ * @author loki der quaeler
+ */
+public interface WorkgroupInvitationListener {
+
+    /**
+     * The implementing class instance will be notified via this method when an invitation
+     *  to join a group chat has been received from the server.
+     *
+     * @param invitation an Invitation instance embodying the information pertaining to the
+     *                      invitation
+     */
+    public void invitationReceived(WorkgroupInvitation invitation);
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/Agent.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/Agent.java
index bebac37..d7e4fa2 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/Agent.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/Agent.java
@@ -1,138 +1,138 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.agent;
-
-import org.jivesoftware.smackx.workgroup.packet.AgentInfo;
-import org.jivesoftware.smackx.workgroup.packet.AgentWorkgroups;
-import org.jivesoftware.smack.PacketCollector;
-import org.jivesoftware.smack.SmackConfiguration;
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.filter.PacketIDFilter;
-import org.jivesoftware.smack.packet.IQ;
-
-import java.util.Collection;
-
-/**
- * The <code>Agent</code> class is used to represent one agent in a Workgroup Queue.
- *
- * @author Derek DeMoro
- */
-public class Agent {
-    private Connection connection;
-    private String workgroupJID;
-
-    public static Collection<String> getWorkgroups(String serviceJID, String agentJID, Connection connection) throws XMPPException {
-        AgentWorkgroups request = new AgentWorkgroups(agentJID);
-        request.setTo(serviceJID);
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
-        // Send the request
-        connection.sendPacket(request);
-
-        AgentWorkgroups response = (AgentWorkgroups)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server on status set.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response.getWorkgroups();
-    }
-
-    /**
-     * Constructs an Agent.
-     */
-    Agent(Connection connection, String workgroupJID) {
-        this.connection = connection;
-        this.workgroupJID = workgroupJID;
-    }
-
-    /**
-     * Return the agents JID
-     *
-     * @return - the agents JID.
-     */
-    public String getUser() {
-        return connection.getUser();
-    }
-
-    /**
-     * Return the agents name.
-     *
-     * @return - the agents name.
-     */
-    public String getName() throws XMPPException {
-        AgentInfo agentInfo = new AgentInfo();
-        agentInfo.setType(IQ.Type.GET);
-        agentInfo.setTo(workgroupJID);
-        agentInfo.setFrom(getUser());
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(agentInfo.getPacketID()));
-        // Send the request
-        connection.sendPacket(agentInfo);
-
-        AgentInfo response = (AgentInfo)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server on status set.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response.getName();
-    }
-
-    /**
-     * Changes the name of the agent in the server. The server may have this functionality
-     * disabled for all the agents or for this agent in particular. If the agent is not
-     * allowed to change his name then an exception will be thrown with a service_unavailable
-     * error code.
-     *
-     * @param newName the new name of the agent.
-     * @throws XMPPException if the agent is not allowed to change his name or no response was
-     *                       obtained from the server.
-     */
-    public void setName(String newName) throws XMPPException {
-        AgentInfo agentInfo = new AgentInfo();
-        agentInfo.setType(IQ.Type.SET);
-        agentInfo.setTo(workgroupJID);
-        agentInfo.setFrom(getUser());
-        agentInfo.setName(newName);
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(agentInfo.getPacketID()));
-        // Send the request
-        connection.sendPacket(agentInfo);
-
-        IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server on status set.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return;
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.agent;
+
+import org.jivesoftware.smackx.workgroup.packet.AgentInfo;
+import org.jivesoftware.smackx.workgroup.packet.AgentWorkgroups;
+import org.jivesoftware.smack.PacketCollector;
+import org.jivesoftware.smack.SmackConfiguration;
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.filter.PacketIDFilter;
+import org.jivesoftware.smack.packet.IQ;
+
+import java.util.Collection;
+
+/**
+ * The <code>Agent</code> class is used to represent one agent in a Workgroup Queue.
+ *
+ * @author Derek DeMoro
+ */
+public class Agent {
+    private Connection connection;
+    private String workgroupJID;
+
+    public static Collection<String> getWorkgroups(String serviceJID, String agentJID, Connection connection) throws XMPPException {
+        AgentWorkgroups request = new AgentWorkgroups(agentJID);
+        request.setTo(serviceJID);
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
+        // Send the request
+        connection.sendPacket(request);
+
+        AgentWorkgroups response = (AgentWorkgroups)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server on status set.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response.getWorkgroups();
+    }
+
+    /**
+     * Constructs an Agent.
+     */
+    Agent(Connection connection, String workgroupJID) {
+        this.connection = connection;
+        this.workgroupJID = workgroupJID;
+    }
+
+    /**
+     * Return the agents JID
+     *
+     * @return - the agents JID.
+     */
+    public String getUser() {
+        return connection.getUser();
+    }
+
+    /**
+     * Return the agents name.
+     *
+     * @return - the agents name.
+     */
+    public String getName() throws XMPPException {
+        AgentInfo agentInfo = new AgentInfo();
+        agentInfo.setType(IQ.Type.GET);
+        agentInfo.setTo(workgroupJID);
+        agentInfo.setFrom(getUser());
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(agentInfo.getPacketID()));
+        // Send the request
+        connection.sendPacket(agentInfo);
+
+        AgentInfo response = (AgentInfo)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server on status set.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response.getName();
+    }
+
+    /**
+     * Changes the name of the agent in the server. The server may have this functionality
+     * disabled for all the agents or for this agent in particular. If the agent is not
+     * allowed to change his name then an exception will be thrown with a service_unavailable
+     * error code.
+     *
+     * @param newName the new name of the agent.
+     * @throws XMPPException if the agent is not allowed to change his name or no response was
+     *                       obtained from the server.
+     */
+    public void setName(String newName) throws XMPPException {
+        AgentInfo agentInfo = new AgentInfo();
+        agentInfo.setType(IQ.Type.SET);
+        agentInfo.setTo(workgroupJID);
+        agentInfo.setFrom(getUser());
+        agentInfo.setName(newName);
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(agentInfo.getPacketID()));
+        // Send the request
+        connection.sendPacket(agentInfo);
+
+        IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server on status set.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return;
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java
index 70c95ee..edeb195 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java
@@ -1,386 +1,386 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.agent;
-
-import org.jivesoftware.smackx.workgroup.packet.AgentStatus;
-import org.jivesoftware.smackx.workgroup.packet.AgentStatusRequest;
-import org.jivesoftware.smack.PacketListener;
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.filter.PacketFilter;
-import org.jivesoftware.smack.filter.PacketTypeFilter;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smack.packet.Presence;
-import org.jivesoftware.smack.util.StringUtils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Manges information about the agents in a workgroup and their presence.
- *
- * @author Matt Tucker
- * @see AgentSession#getAgentRoster()
- */
-public class AgentRoster {
-
-    private static final int EVENT_AGENT_ADDED = 0;
-    private static final int EVENT_AGENT_REMOVED = 1;
-    private static final int EVENT_PRESENCE_CHANGED = 2;
-
-    private Connection connection;
-    private String workgroupJID;
-    private List<String> entries;
-    private List<AgentRosterListener> listeners;
-    private Map<String, Map<String, Presence>> presenceMap;
-    // The roster is marked as initialized when at least a single roster packet
-    // has been recieved and processed.
-    boolean rosterInitialized = false;
-
-    /**
-     * Constructs a new AgentRoster.
-     *
-     * @param connection an XMPP connection.
-     */
-    AgentRoster(Connection connection, String workgroupJID) {
-        this.connection = connection;
-        this.workgroupJID = workgroupJID;
-        entries = new ArrayList<String>();
-        listeners = new ArrayList<AgentRosterListener>();
-        presenceMap = new HashMap<String, Map<String, Presence>>();
-        // Listen for any roster packets.
-        PacketFilter rosterFilter = new PacketTypeFilter(AgentStatusRequest.class);
-        connection.addPacketListener(new AgentStatusListener(), rosterFilter);
-        // Listen for any presence packets.
-        connection.addPacketListener(new PresencePacketListener(),
-                new PacketTypeFilter(Presence.class));
-
-        // Send request for roster.
-        AgentStatusRequest request = new AgentStatusRequest();
-        request.setTo(workgroupJID);
-        connection.sendPacket(request);
-    }
-
-    /**
-     * Reloads the entire roster from the server. This is an asynchronous operation,
-     * which means the method will return immediately, and the roster will be
-     * reloaded at a later point when the server responds to the reload request.
-     */
-    public void reload() {
-        AgentStatusRequest request = new AgentStatusRequest();
-        request.setTo(workgroupJID);
-        connection.sendPacket(request);
-    }
-
-    /**
-     * Adds a listener to this roster. The listener will be fired anytime one or more
-     * changes to the roster are pushed from the server.
-     *
-     * @param listener an agent roster listener.
-     */
-    public void addListener(AgentRosterListener listener) {
-        synchronized (listeners) {
-            if (!listeners.contains(listener)) {
-                listeners.add(listener);
-
-                // Fire events for the existing entries and presences in the roster
-                for (Iterator<String> it = getAgents().iterator(); it.hasNext();) {
-                    String jid = it.next();
-                    // Check again in case the agent is no longer in the roster (highly unlikely
-                    // but possible)
-                    if (entries.contains(jid)) {
-                        // Fire the agent added event
-                        listener.agentAdded(jid);
-                        Map<String,Presence> userPresences = presenceMap.get(jid);
-                        if (userPresences != null) {
-                            Iterator<Presence> presences = userPresences.values().iterator();
-                            while (presences.hasNext()) {
-                                // Fire the presence changed event
-                                listener.presenceChanged(presences.next());
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Removes a listener from this roster. The listener will be fired anytime one or more
-     * changes to the roster are pushed from the server.
-     *
-     * @param listener a roster listener.
-     */
-    public void removeListener(AgentRosterListener listener) {
-        synchronized (listeners) {
-            listeners.remove(listener);
-        }
-    }
-
-    /**
-     * Returns a count of all agents in the workgroup.
-     *
-     * @return the number of agents in the workgroup.
-     */
-    public int getAgentCount() {
-        return entries.size();
-    }
-
-    /**
-     * Returns all agents (String JID values) in the workgroup.
-     *
-     * @return all entries in the roster.
-     */
-    public Set<String> getAgents() {
-        Set<String> agents = new HashSet<String>();
-        synchronized (entries) {
-            for (Iterator<String> i = entries.iterator(); i.hasNext();) {
-                agents.add(i.next());
-            }
-        }
-        return Collections.unmodifiableSet(agents);
-    }
-
-    /**
-     * Returns true if the specified XMPP address is an agent in the workgroup.
-     *
-     * @param jid the XMPP address of the agent (eg "jsmith@example.com"). The
-     *            address can be in any valid format (e.g. "domain/resource", "user@domain"
-     *            or "user@domain/resource").
-     * @return true if the XMPP address is an agent in the workgroup.
-     */
-    public boolean contains(String jid) {
-        if (jid == null) {
-            return false;
-        }
-        synchronized (entries) {
-            for (Iterator<String> i = entries.iterator(); i.hasNext();) {
-                String entry = i.next();
-                if (entry.toLowerCase().equals(jid.toLowerCase())) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns the presence info for a particular agent, or <tt>null</tt> if the agent
-     * is unavailable (offline) or if no presence information is available.<p>
-     *
-     * @param user a fully qualified xmpp JID. The address could be in any valid format (e.g.
-     *             "domain/resource", "user@domain" or "user@domain/resource").
-     * @return the agent's current presence, or <tt>null</tt> if the agent is unavailable
-     *         or if no presence information is available..
-     */
-    public Presence getPresence(String user) {
-        String key = getPresenceMapKey(user);
-        Map<String, Presence> userPresences = presenceMap.get(key);
-        if (userPresences == null) {
-            Presence presence = new Presence(Presence.Type.unavailable);
-            presence.setFrom(user);
-            return presence;
-        }
-        else {
-            // Find the resource with the highest priority
-            // Might be changed to use the resource with the highest availability instead.
-            Iterator<String> it = userPresences.keySet().iterator();
-            Presence p;
-            Presence presence = null;
-
-            while (it.hasNext()) {
-                p = (Presence)userPresences.get(it.next());
-                if (presence == null){
-                    presence = p;
-                }
-                else {
-                    if (p.getPriority() > presence.getPriority()) {
-                        presence = p;
-                    }
-                }
-            }
-            if (presence == null) {
-                presence = new Presence(Presence.Type.unavailable);
-                presence.setFrom(user);
-                return presence;
-            }
-            else {
-                return presence;
-            }
-        }
-    }
-
-    /**
-     * Returns the key to use in the presenceMap for a fully qualified xmpp ID. The roster
-     * can contain any valid address format such us "domain/resource", "user@domain" or
-     * "user@domain/resource". If the roster contains an entry associated with the fully qualified
-     * xmpp ID then use the fully qualified xmpp ID as the key in presenceMap, otherwise use the
-     * bare address. Note: When the key in presenceMap is a fully qualified xmpp ID, the
-     * userPresences is useless since it will always contain one entry for the user.
-     *
-     * @param user the fully qualified xmpp ID, e.g. jdoe@example.com/Work.
-     * @return the key to use in the presenceMap for the fully qualified xmpp ID.
-     */
-    private String getPresenceMapKey(String user) {
-        String key = user;
-        if (!contains(user)) {
-            key = StringUtils.parseBareAddress(user).toLowerCase();
-        }
-        return key;
-    }
-
-    /**
-     * Fires event to listeners.
-     */
-    private void fireEvent(int eventType, Object eventObject) {
-        AgentRosterListener[] listeners = null;
-        synchronized (this.listeners) {
-            listeners = new AgentRosterListener[this.listeners.size()];
-            this.listeners.toArray(listeners);
-        }
-        for (int i = 0; i < listeners.length; i++) {
-            switch (eventType) {
-                case EVENT_AGENT_ADDED:
-                    listeners[i].agentAdded((String)eventObject);
-                    break;
-                case EVENT_AGENT_REMOVED:
-                    listeners[i].agentRemoved((String)eventObject);
-                    break;
-                case EVENT_PRESENCE_CHANGED:
-                    listeners[i].presenceChanged((Presence)eventObject);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Listens for all presence packets and processes them.
-     */
-    private class PresencePacketListener implements PacketListener {
-        public void processPacket(Packet packet) {
-            Presence presence = (Presence)packet;
-            String from = presence.getFrom();
-            if (from == null) {
-                // TODO Check if we need to ignore these presences or this is a server bug?
-                System.out.println("Presence with no FROM: " + presence.toXML());
-                return;
-            }
-            String key = getPresenceMapKey(from);
-
-            // If an "available" packet, add it to the presence map. Each presence map will hold
-            // for a particular user a map with the presence packets saved for each resource.
-            if (presence.getType() == Presence.Type.available) {
-                // Ignore the presence packet unless it has an agent status extension.
-                AgentStatus agentStatus = (AgentStatus)presence.getExtension(
-                        AgentStatus.ELEMENT_NAME, AgentStatus.NAMESPACE);
-                if (agentStatus == null) {
-                    return;
-                }
-                // Ensure that this presence is coming from an Agent of the same workgroup
-                // of this Agent
-                else if (!workgroupJID.equals(agentStatus.getWorkgroupJID())) {
-                    return;
-                }
-                Map<String, Presence> userPresences;
-                // Get the user presence map
-                if (presenceMap.get(key) == null) {
-                    userPresences = new HashMap<String, Presence>();
-                    presenceMap.put(key, userPresences);
-                }
-                else {
-                    userPresences = presenceMap.get(key);
-                }
-                // Add the new presence, using the resources as a key.
-                synchronized (userPresences) {
-                    userPresences.put(StringUtils.parseResource(from), presence);
-                }
-                // Fire an event.
-                synchronized (entries) {
-                    for (Iterator<String> i = entries.iterator(); i.hasNext();) {
-                        String entry = i.next();
-                        if (entry.toLowerCase().equals(StringUtils.parseBareAddress(key).toLowerCase())) {
-                            fireEvent(EVENT_PRESENCE_CHANGED, packet);
-                        }
-                    }
-                }
-            }
-            // If an "unavailable" packet, remove any entries in the presence map.
-            else if (presence.getType() == Presence.Type.unavailable) {
-                if (presenceMap.get(key) != null) {
-                    Map<String,Presence> userPresences = presenceMap.get(key);
-                    synchronized (userPresences) {
-                        userPresences.remove(StringUtils.parseResource(from));
-                    }
-                    if (userPresences.isEmpty()) {
-                        presenceMap.remove(key);
-                    }
-                }
-                // Fire an event.
-                synchronized (entries) {
-                    for (Iterator<String> i = entries.iterator(); i.hasNext();) {
-                        String entry = (String)i.next();
-                        if (entry.toLowerCase().equals(StringUtils.parseBareAddress(key).toLowerCase())) {
-                            fireEvent(EVENT_PRESENCE_CHANGED, packet);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Listens for all roster packets and processes them.
-     */
-    private class AgentStatusListener implements PacketListener {
-
-        public void processPacket(Packet packet) {
-            if (packet instanceof AgentStatusRequest) {
-                AgentStatusRequest statusRequest = (AgentStatusRequest)packet;
-                for (Iterator<AgentStatusRequest.Item> i = statusRequest.getAgents().iterator(); i.hasNext();) {
-                    AgentStatusRequest.Item item = i.next();
-                    String agentJID = item.getJID();
-                    if ("remove".equals(item.getType())) {
-
-                        // Removing the user from the roster, so remove any presence information
-                        // about them.
-                        String key = StringUtils.parseName(StringUtils.parseName(agentJID) + "@" +
-                                StringUtils.parseServer(agentJID));
-                        presenceMap.remove(key);
-                        // Fire event for roster listeners.
-                        fireEvent(EVENT_AGENT_REMOVED, agentJID);
-                    }
-                    else {
-                        entries.add(agentJID);
-                        // Fire event for roster listeners.
-                        fireEvent(EVENT_AGENT_ADDED, agentJID);
-                    }
-                }
-
-                // Mark the roster as initialized.
-                rosterInitialized = true;
-            }
-        }
-    }
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.agent;
+
+import org.jivesoftware.smackx.workgroup.packet.AgentStatus;
+import org.jivesoftware.smackx.workgroup.packet.AgentStatusRequest;
+import org.jivesoftware.smack.PacketListener;
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.filter.PacketTypeFilter;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.packet.Presence;
+import org.jivesoftware.smack.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Manges information about the agents in a workgroup and their presence.
+ *
+ * @author Matt Tucker
+ * @see AgentSession#getAgentRoster()
+ */
+public class AgentRoster {
+
+    private static final int EVENT_AGENT_ADDED = 0;
+    private static final int EVENT_AGENT_REMOVED = 1;
+    private static final int EVENT_PRESENCE_CHANGED = 2;
+
+    private Connection connection;
+    private String workgroupJID;
+    private List<String> entries;
+    private List<AgentRosterListener> listeners;
+    private Map<String, Map<String, Presence>> presenceMap;
+    // The roster is marked as initialized when at least a single roster packet
+    // has been recieved and processed.
+    boolean rosterInitialized = false;
+
+    /**
+     * Constructs a new AgentRoster.
+     *
+     * @param connection an XMPP connection.
+     */
+    AgentRoster(Connection connection, String workgroupJID) {
+        this.connection = connection;
+        this.workgroupJID = workgroupJID;
+        entries = new ArrayList<String>();
+        listeners = new ArrayList<AgentRosterListener>();
+        presenceMap = new HashMap<String, Map<String, Presence>>();
+        // Listen for any roster packets.
+        PacketFilter rosterFilter = new PacketTypeFilter(AgentStatusRequest.class);
+        connection.addPacketListener(new AgentStatusListener(), rosterFilter);
+        // Listen for any presence packets.
+        connection.addPacketListener(new PresencePacketListener(),
+                new PacketTypeFilter(Presence.class));
+
+        // Send request for roster.
+        AgentStatusRequest request = new AgentStatusRequest();
+        request.setTo(workgroupJID);
+        connection.sendPacket(request);
+    }
+
+    /**
+     * Reloads the entire roster from the server. This is an asynchronous operation,
+     * which means the method will return immediately, and the roster will be
+     * reloaded at a later point when the server responds to the reload request.
+     */
+    public void reload() {
+        AgentStatusRequest request = new AgentStatusRequest();
+        request.setTo(workgroupJID);
+        connection.sendPacket(request);
+    }
+
+    /**
+     * Adds a listener to this roster. The listener will be fired anytime one or more
+     * changes to the roster are pushed from the server.
+     *
+     * @param listener an agent roster listener.
+     */
+    public void addListener(AgentRosterListener listener) {
+        synchronized (listeners) {
+            if (!listeners.contains(listener)) {
+                listeners.add(listener);
+
+                // Fire events for the existing entries and presences in the roster
+                for (Iterator<String> it = getAgents().iterator(); it.hasNext();) {
+                    String jid = it.next();
+                    // Check again in case the agent is no longer in the roster (highly unlikely
+                    // but possible)
+                    if (entries.contains(jid)) {
+                        // Fire the agent added event
+                        listener.agentAdded(jid);
+                        Map<String,Presence> userPresences = presenceMap.get(jid);
+                        if (userPresences != null) {
+                            Iterator<Presence> presences = userPresences.values().iterator();
+                            while (presences.hasNext()) {
+                                // Fire the presence changed event
+                                listener.presenceChanged(presences.next());
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Removes a listener from this roster. The listener will be fired anytime one or more
+     * changes to the roster are pushed from the server.
+     *
+     * @param listener a roster listener.
+     */
+    public void removeListener(AgentRosterListener listener) {
+        synchronized (listeners) {
+            listeners.remove(listener);
+        }
+    }
+
+    /**
+     * Returns a count of all agents in the workgroup.
+     *
+     * @return the number of agents in the workgroup.
+     */
+    public int getAgentCount() {
+        return entries.size();
+    }
+
+    /**
+     * Returns all agents (String JID values) in the workgroup.
+     *
+     * @return all entries in the roster.
+     */
+    public Set<String> getAgents() {
+        Set<String> agents = new HashSet<String>();
+        synchronized (entries) {
+            for (Iterator<String> i = entries.iterator(); i.hasNext();) {
+                agents.add(i.next());
+            }
+        }
+        return Collections.unmodifiableSet(agents);
+    }
+
+    /**
+     * Returns true if the specified XMPP address is an agent in the workgroup.
+     *
+     * @param jid the XMPP address of the agent (eg "jsmith@example.com"). The
+     *            address can be in any valid format (e.g. "domain/resource", "user@domain"
+     *            or "user@domain/resource").
+     * @return true if the XMPP address is an agent in the workgroup.
+     */
+    public boolean contains(String jid) {
+        if (jid == null) {
+            return false;
+        }
+        synchronized (entries) {
+            for (Iterator<String> i = entries.iterator(); i.hasNext();) {
+                String entry = i.next();
+                if (entry.toLowerCase().equals(jid.toLowerCase())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the presence info for a particular agent, or <tt>null</tt> if the agent
+     * is unavailable (offline) or if no presence information is available.<p>
+     *
+     * @param user a fully qualified xmpp JID. The address could be in any valid format (e.g.
+     *             "domain/resource", "user@domain" or "user@domain/resource").
+     * @return the agent's current presence, or <tt>null</tt> if the agent is unavailable
+     *         or if no presence information is available..
+     */
+    public Presence getPresence(String user) {
+        String key = getPresenceMapKey(user);
+        Map<String, Presence> userPresences = presenceMap.get(key);
+        if (userPresences == null) {
+            Presence presence = new Presence(Presence.Type.unavailable);
+            presence.setFrom(user);
+            return presence;
+        }
+        else {
+            // Find the resource with the highest priority
+            // Might be changed to use the resource with the highest availability instead.
+            Iterator<String> it = userPresences.keySet().iterator();
+            Presence p;
+            Presence presence = null;
+
+            while (it.hasNext()) {
+                p = (Presence)userPresences.get(it.next());
+                if (presence == null){
+                    presence = p;
+                }
+                else {
+                    if (p.getPriority() > presence.getPriority()) {
+                        presence = p;
+                    }
+                }
+            }
+            if (presence == null) {
+                presence = new Presence(Presence.Type.unavailable);
+                presence.setFrom(user);
+                return presence;
+            }
+            else {
+                return presence;
+            }
+        }
+    }
+
+    /**
+     * Returns the key to use in the presenceMap for a fully qualified xmpp ID. The roster
+     * can contain any valid address format such us "domain/resource", "user@domain" or
+     * "user@domain/resource". If the roster contains an entry associated with the fully qualified
+     * xmpp ID then use the fully qualified xmpp ID as the key in presenceMap, otherwise use the
+     * bare address. Note: When the key in presenceMap is a fully qualified xmpp ID, the
+     * userPresences is useless since it will always contain one entry for the user.
+     *
+     * @param user the fully qualified xmpp ID, e.g. jdoe@example.com/Work.
+     * @return the key to use in the presenceMap for the fully qualified xmpp ID.
+     */
+    private String getPresenceMapKey(String user) {
+        String key = user;
+        if (!contains(user)) {
+            key = StringUtils.parseBareAddress(user).toLowerCase();
+        }
+        return key;
+    }
+
+    /**
+     * Fires event to listeners.
+     */
+    private void fireEvent(int eventType, Object eventObject) {
+        AgentRosterListener[] listeners = null;
+        synchronized (this.listeners) {
+            listeners = new AgentRosterListener[this.listeners.size()];
+            this.listeners.toArray(listeners);
+        }
+        for (int i = 0; i < listeners.length; i++) {
+            switch (eventType) {
+                case EVENT_AGENT_ADDED:
+                    listeners[i].agentAdded((String)eventObject);
+                    break;
+                case EVENT_AGENT_REMOVED:
+                    listeners[i].agentRemoved((String)eventObject);
+                    break;
+                case EVENT_PRESENCE_CHANGED:
+                    listeners[i].presenceChanged((Presence)eventObject);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Listens for all presence packets and processes them.
+     */
+    private class PresencePacketListener implements PacketListener {
+        public void processPacket(Packet packet) {
+            Presence presence = (Presence)packet;
+            String from = presence.getFrom();
+            if (from == null) {
+                // TODO Check if we need to ignore these presences or this is a server bug?
+                System.out.println("Presence with no FROM: " + presence.toXML());
+                return;
+            }
+            String key = getPresenceMapKey(from);
+
+            // If an "available" packet, add it to the presence map. Each presence map will hold
+            // for a particular user a map with the presence packets saved for each resource.
+            if (presence.getType() == Presence.Type.available) {
+                // Ignore the presence packet unless it has an agent status extension.
+                AgentStatus agentStatus = (AgentStatus)presence.getExtension(
+                        AgentStatus.ELEMENT_NAME, AgentStatus.NAMESPACE);
+                if (agentStatus == null) {
+                    return;
+                }
+                // Ensure that this presence is coming from an Agent of the same workgroup
+                // of this Agent
+                else if (!workgroupJID.equals(agentStatus.getWorkgroupJID())) {
+                    return;
+                }
+                Map<String, Presence> userPresences;
+                // Get the user presence map
+                if (presenceMap.get(key) == null) {
+                    userPresences = new HashMap<String, Presence>();
+                    presenceMap.put(key, userPresences);
+                }
+                else {
+                    userPresences = presenceMap.get(key);
+                }
+                // Add the new presence, using the resources as a key.
+                synchronized (userPresences) {
+                    userPresences.put(StringUtils.parseResource(from), presence);
+                }
+                // Fire an event.
+                synchronized (entries) {
+                    for (Iterator<String> i = entries.iterator(); i.hasNext();) {
+                        String entry = i.next();
+                        if (entry.toLowerCase().equals(StringUtils.parseBareAddress(key).toLowerCase())) {
+                            fireEvent(EVENT_PRESENCE_CHANGED, packet);
+                        }
+                    }
+                }
+            }
+            // If an "unavailable" packet, remove any entries in the presence map.
+            else if (presence.getType() == Presence.Type.unavailable) {
+                if (presenceMap.get(key) != null) {
+                    Map<String,Presence> userPresences = presenceMap.get(key);
+                    synchronized (userPresences) {
+                        userPresences.remove(StringUtils.parseResource(from));
+                    }
+                    if (userPresences.isEmpty()) {
+                        presenceMap.remove(key);
+                    }
+                }
+                // Fire an event.
+                synchronized (entries) {
+                    for (Iterator<String> i = entries.iterator(); i.hasNext();) {
+                        String entry = (String)i.next();
+                        if (entry.toLowerCase().equals(StringUtils.parseBareAddress(key).toLowerCase())) {
+                            fireEvent(EVENT_PRESENCE_CHANGED, packet);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Listens for all roster packets and processes them.
+     */
+    private class AgentStatusListener implements PacketListener {
+
+        public void processPacket(Packet packet) {
+            if (packet instanceof AgentStatusRequest) {
+                AgentStatusRequest statusRequest = (AgentStatusRequest)packet;
+                for (Iterator<AgentStatusRequest.Item> i = statusRequest.getAgents().iterator(); i.hasNext();) {
+                    AgentStatusRequest.Item item = i.next();
+                    String agentJID = item.getJID();
+                    if ("remove".equals(item.getType())) {
+
+                        // Removing the user from the roster, so remove any presence information
+                        // about them.
+                        String key = StringUtils.parseName(StringUtils.parseName(agentJID) + "@" +
+                                StringUtils.parseServer(agentJID));
+                        presenceMap.remove(key);
+                        // Fire event for roster listeners.
+                        fireEvent(EVENT_AGENT_REMOVED, agentJID);
+                    }
+                    else {
+                        entries.add(agentJID);
+                        // Fire event for roster listeners.
+                        fireEvent(EVENT_AGENT_ADDED, agentJID);
+                    }
+                }
+
+                // Mark the roster as initialized.
+                rosterInitialized = true;
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/AgentRosterListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/AgentRosterListener.java
index 4db9203..afea9ff 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/AgentRosterListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/AgentRosterListener.java
@@ -1,35 +1,35 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.agent;
-
-import org.jivesoftware.smack.packet.Presence;
-
-/**
- *
- * @author Matt Tucker
- */
-public interface AgentRosterListener {
-
-    public void agentAdded(String jid);
-
-    public void agentRemoved(String jid);
-
-    public void presenceChanged(Presence presence);
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.agent;
+
+import org.jivesoftware.smack.packet.Presence;
+
+/**
+ *
+ * @author Matt Tucker
+ */
+public interface AgentRosterListener {
+
+    public void agentAdded(String jid);
+
+    public void agentRemoved(String jid);
+
+    public void presenceChanged(Presence presence);
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/AgentSession.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/AgentSession.java
index 46d19d0..0600644 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/AgentSession.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/AgentSession.java
@@ -1,1185 +1,1185 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.agent;
-
-import org.jivesoftware.smackx.workgroup.MetaData;
-import org.jivesoftware.smackx.workgroup.QueueUser;
-import org.jivesoftware.smackx.workgroup.WorkgroupInvitation;
-import org.jivesoftware.smackx.workgroup.WorkgroupInvitationListener;
-import org.jivesoftware.smackx.workgroup.ext.history.AgentChatHistory;
-import org.jivesoftware.smackx.workgroup.ext.history.ChatMetadata;
-import org.jivesoftware.smackx.workgroup.ext.macros.MacroGroup;
-import org.jivesoftware.smackx.workgroup.ext.macros.Macros;
-import org.jivesoftware.smackx.workgroup.ext.notes.ChatNotes;
-import org.jivesoftware.smackx.workgroup.packet.*;
-import org.jivesoftware.smackx.workgroup.settings.GenericSettings;
-import org.jivesoftware.smackx.workgroup.settings.SearchSettings;
-import org.jivesoftware.smack.*;
-import org.jivesoftware.smack.filter.*;
-import org.jivesoftware.smack.packet.*;
-import org.jivesoftware.smack.util.StringUtils;
-import org.jivesoftware.smackx.Form;
-import org.jivesoftware.smackx.ReportedData;
-import org.jivesoftware.smackx.packet.MUCUser;
-
-import java.util.*;
-
-/**
- * This class embodies the agent's active presence within a given workgroup. The application
- * should have N instances of this class, where N is the number of workgroups to which the
- * owning agent of the application belongs. This class provides all functionality that a
- * session within a given workgroup is expected to have from an agent's perspective -- setting
- * the status, tracking the status of queues to which the agent belongs within the workgroup, and
- * dequeuing customers.
- *
- * @author Matt Tucker
- * @author Derek DeMoro
- */
-public class AgentSession {
-
-    private Connection connection;
-
-    private String workgroupJID;
-
-    private boolean online = false;
-    private Presence.Mode presenceMode;
-    private int maxChats;
-    private final Map<String, List<String>> metaData;
-
-    private Map<String, WorkgroupQueue> queues;
-
-    private final List<OfferListener> offerListeners;
-    private final List<WorkgroupInvitationListener> invitationListeners;
-    private final List<QueueUsersListener> queueUsersListeners;
-
-    private AgentRoster agentRoster = null;
-    private TranscriptManager transcriptManager;
-    private TranscriptSearchManager transcriptSearchManager;
-    private Agent agent;
-    private PacketListener packetListener;
-
-    /**
-     * Constructs a new agent session instance. Note, the {@link #setOnline(boolean)}
-     * method must be called with an argument of <tt>true</tt> to mark the agent
-     * as available to accept chat requests.
-     *
-     * @param connection   a connection instance which must have already gone through
-     *                     authentication.
-     * @param workgroupJID the fully qualified JID of the workgroup.
-     */
-    public AgentSession(String workgroupJID, Connection connection) {
-        // Login must have been done before passing in connection.
-        if (!connection.isAuthenticated()) {
-            throw new IllegalStateException("Must login to server before creating workgroup.");
-        }
-
-        this.workgroupJID = workgroupJID;
-        this.connection = connection;
-        this.transcriptManager = new TranscriptManager(connection);
-        this.transcriptSearchManager = new TranscriptSearchManager(connection);
-
-        this.maxChats = -1;
-
-        this.metaData = new HashMap<String, List<String>>();
-
-        this.queues = new HashMap<String, WorkgroupQueue>();
-
-        offerListeners = new ArrayList<OfferListener>();
-        invitationListeners = new ArrayList<WorkgroupInvitationListener>();
-        queueUsersListeners = new ArrayList<QueueUsersListener>();
-
-        // Create a filter to listen for packets we're interested in.
-        OrFilter filter = new OrFilter();
-        filter.addFilter(new PacketTypeFilter(OfferRequestProvider.OfferRequestPacket.class));
-        filter.addFilter(new PacketTypeFilter(OfferRevokeProvider.OfferRevokePacket.class));
-        filter.addFilter(new PacketTypeFilter(Presence.class));
-        filter.addFilter(new PacketTypeFilter(Message.class));
-
-        packetListener = new PacketListener() {
-            public void processPacket(Packet packet) {
-                try {
-                    handlePacket(packet);
-                }
-                catch (Exception e) {
-                    e.printStackTrace();
-                }
-            }
-        };
-        connection.addPacketListener(packetListener, filter);
-        // Create the agent associated to this session
-        agent = new Agent(connection, workgroupJID);
-    }
-
-    /**
-     * Close the agent session. The underlying connection will remain opened but the
-     * packet listeners that were added by this agent session will be removed.
-     */
-    public void close() {
-        connection.removePacketListener(packetListener);
-    }
-
-    /**
-     * Returns the agent roster for the workgroup, which contains
-     *
-     * @return the AgentRoster
-     */
-    public AgentRoster getAgentRoster() {
-        if (agentRoster == null) {
-            agentRoster = new AgentRoster(connection, workgroupJID);
-        }
-
-        // This might be the first time the user has asked for the roster. If so, we
-        // want to wait up to 2 seconds for the server to send back the list of agents.
-        // This behavior shields API users from having to worry about the fact that the
-        // operation is asynchronous, although they'll still have to listen for changes
-        // to the roster.
-        int elapsed = 0;
-        while (!agentRoster.rosterInitialized && elapsed <= 2000) {
-            try {
-                Thread.sleep(500);
-            }
-            catch (Exception e) {
-                // Ignore
-            }
-            elapsed += 500;
-        }
-        return agentRoster;
-    }
-
-    /**
-     * Returns the agent's current presence mode.
-     *
-     * @return the agent's current presence mode.
-     */
-    public Presence.Mode getPresenceMode() {
-        return presenceMode;
-    }
-
-    /**
-     * Returns the maximum number of chats the agent can participate in.
-     *
-     * @return the maximum number of chats the agent can participate in.
-     */
-    public int getMaxChats() {
-        return maxChats;
-    }
-
-    /**
-     * Returns true if the agent is online with the workgroup.
-     *
-     * @return true if the agent is online with the workgroup.
-     */
-    public boolean isOnline() {
-        return online;
-    }
-
-    /**
-     * Allows the addition of a new key-value pair to the agent's meta data, if the value is
-     * new data, the revised meta data will be rebroadcast in an agent's presence broadcast.
-     *
-     * @param key the meta data key
-     * @param val the non-null meta data value
-     * @throws XMPPException if an exception occurs.
-     */
-    public void setMetaData(String key, String val) throws XMPPException {
-        synchronized (this.metaData) {
-            List<String> oldVals = metaData.get(key);
-
-            if ((oldVals == null) || (!oldVals.get(0).equals(val))) {
-                oldVals.set(0, val);
-
-                setStatus(presenceMode, maxChats);
-            }
-        }
-    }
-
-    /**
-     * Allows the removal of data from the agent's meta data, if the key represents existing data,
-     * the revised meta data will be rebroadcast in an agent's presence broadcast.
-     *
-     * @param key the meta data key.
-     * @throws XMPPException if an exception occurs.
-     */
-    public void removeMetaData(String key) throws XMPPException {
-        synchronized (this.metaData) {
-            List<String> oldVal = metaData.remove(key);
-
-            if (oldVal != null) {
-                setStatus(presenceMode, maxChats);
-            }
-        }
-    }
-
-    /**
-     * Allows the retrieval of meta data for a specified key.
-     *
-     * @param key the meta data key
-     * @return the meta data value associated with the key or <tt>null</tt> if the meta-data
-     *         doesn't exist..
-     */
-    public List<String> getMetaData(String key) {
-        return metaData.get(key);
-    }
-
-    /**
-     * Sets whether the agent is online with the workgroup. If the user tries to go online with
-     * the workgroup but is not allowed to be an agent, an XMPPError with error code 401 will
-     * be thrown.
-     *
-     * @param online true to set the agent as online with the workgroup.
-     * @throws XMPPException if an error occurs setting the online status.
-     */
-    public void setOnline(boolean online) throws XMPPException {
-        // If the online status hasn't changed, do nothing.
-        if (this.online == online) {
-            return;
-        }
-
-        Presence presence;
-
-        // If the user is going online...
-        if (online) {
-            presence = new Presence(Presence.Type.available);
-            presence.setTo(workgroupJID);
-            presence.addExtension(new DefaultPacketExtension(AgentStatus.ELEMENT_NAME,
-                    AgentStatus.NAMESPACE));
-
-            PacketCollector collector = this.connection.createPacketCollector(new AndFilter(new PacketTypeFilter(Presence.class), new FromContainsFilter(workgroupJID)));
-
-            connection.sendPacket(presence);
-
-            presence = (Presence)collector.nextResult(5000);
-            collector.cancel();
-            if (!presence.isAvailable()) {
-                throw new XMPPException("No response from server on status set.");
-            }
-
-            if (presence.getError() != null) {
-                throw new XMPPException(presence.getError());
-            }
-
-            // We can safely update this iv since we didn't get any error
-            this.online = online;
-        }
-        // Otherwise the user is going offline...
-        else {
-            // Update this iv now since we don't care at this point of any error
-            this.online = online;
-
-            presence = new Presence(Presence.Type.unavailable);
-            presence.setTo(workgroupJID);
-            presence.addExtension(new DefaultPacketExtension(AgentStatus.ELEMENT_NAME,
-                    AgentStatus.NAMESPACE));
-            connection.sendPacket(presence);
-        }
-    }
-
-    /**
-     * Sets the agent's current status with the workgroup. The presence mode affects
-     * how offers are routed to the agent. The possible presence modes with their
-     * meanings are as follows:<ul>
-     * <p/>
-     * <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats
-     * (equivalent to Presence.Mode.CHAT).
-     * <li>Presence.Mode.DO_NOT_DISTURB -- the agent is busy and should not be disturbed.
-     * However, special case, or extreme urgency chats may still be offered to the agent.
-     * <li>Presence.Mode.AWAY -- the agent is not available and should not
-     * have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul>
-     * <p/>
-     * The max chats value is the maximum number of chats the agent is willing to have
-     * routed to them at once. Some servers may be configured to only accept max chat
-     * values in a certain range; for example, between two and five. In that case, the
-     * maxChats value the agent sends may be adjusted by the server to a value within that
-     * range.
-     *
-     * @param presenceMode the presence mode of the agent.
-     * @param maxChats     the maximum number of chats the agent is willing to accept.
-     * @throws XMPPException         if an error occurs setting the agent status.
-     * @throws IllegalStateException if the agent is not online with the workgroup.
-     */
-    public void setStatus(Presence.Mode presenceMode, int maxChats) throws XMPPException {
-        setStatus(presenceMode, maxChats, null);
-    }
-
-    /**
-     * Sets the agent's current status with the workgroup. The presence mode affects how offers
-     * are routed to the agent. The possible presence modes with their meanings are as follows:<ul>
-     * <p/>
-     * <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats
-     * (equivalent to Presence.Mode.CHAT).
-     * <li>Presence.Mode.DO_NOT_DISTURB -- the agent is busy and should not be disturbed.
-     * However, special case, or extreme urgency chats may still be offered to the agent.
-     * <li>Presence.Mode.AWAY -- the agent is not available and should not
-     * have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul>
-     * <p/>
-     * The max chats value is the maximum number of chats the agent is willing to have routed to
-     * them at once. Some servers may be configured to only accept max chat values in a certain
-     * range; for example, between two and five. In that case, the maxChats value the agent sends
-     * may be adjusted by the server to a value within that range.
-     *
-     * @param presenceMode the presence mode of the agent.
-     * @param maxChats     the maximum number of chats the agent is willing to accept.
-     * @param status       sets the status message of the presence update.
-     * @throws XMPPException         if an error occurs setting the agent status.
-     * @throws IllegalStateException if the agent is not online with the workgroup.
-     */
-    public void setStatus(Presence.Mode presenceMode, int maxChats, String status)
-            throws XMPPException {
-        if (!online) {
-            throw new IllegalStateException("Cannot set status when the agent is not online.");
-        }
-
-        if (presenceMode == null) {
-            presenceMode = Presence.Mode.available;
-        }
-        this.presenceMode = presenceMode;
-        this.maxChats = maxChats;
-
-        Presence presence = new Presence(Presence.Type.available);
-        presence.setMode(presenceMode);
-        presence.setTo(this.getWorkgroupJID());
-
-        if (status != null) {
-            presence.setStatus(status);
-        }
-        // Send information about max chats and current chats as a packet extension.
-        DefaultPacketExtension agentStatus = new DefaultPacketExtension(AgentStatus.ELEMENT_NAME,
-                AgentStatus.NAMESPACE);
-        agentStatus.setValue("max-chats", "" + maxChats);
-        presence.addExtension(agentStatus);
-        presence.addExtension(new MetaData(this.metaData));
-
-        PacketCollector collector = this.connection.createPacketCollector(new AndFilter(new PacketTypeFilter(Presence.class), new FromContainsFilter(workgroupJID)));
-
-        this.connection.sendPacket(presence);
-
-        presence = (Presence)collector.nextResult(5000);
-        collector.cancel();
-        if (!presence.isAvailable()) {
-            throw new XMPPException("No response from server on status set.");
-        }
-
-        if (presence.getError() != null) {
-            throw new XMPPException(presence.getError());
-        }
-    }
-
-    /**
-     * Sets the agent's current status with the workgroup. The presence mode affects how offers
-     * are routed to the agent. The possible presence modes with their meanings are as follows:<ul>
-     * <p/>
-     * <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats
-     * (equivalent to Presence.Mode.CHAT).
-     * <li>Presence.Mode.DO_NOT_DISTURB -- the agent is busy and should not be disturbed.
-     * However, special case, or extreme urgency chats may still be offered to the agent.
-     * <li>Presence.Mode.AWAY -- the agent is not available and should not
-     * have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul>
-     *
-     * @param presenceMode the presence mode of the agent.
-     * @param status       sets the status message of the presence update.
-     * @throws XMPPException         if an error occurs setting the agent status.
-     * @throws IllegalStateException if the agent is not online with the workgroup.
-     */
-    public void setStatus(Presence.Mode presenceMode, String status) throws XMPPException {
-        if (!online) {
-            throw new IllegalStateException("Cannot set status when the agent is not online.");
-        }
-
-        if (presenceMode == null) {
-            presenceMode = Presence.Mode.available;
-        }
-        this.presenceMode = presenceMode;
-
-        Presence presence = new Presence(Presence.Type.available);
-        presence.setMode(presenceMode);
-        presence.setTo(this.getWorkgroupJID());
-
-        if (status != null) {
-            presence.setStatus(status);
-        }
-        presence.addExtension(new MetaData(this.metaData));
-
-        PacketCollector collector = this.connection.createPacketCollector(new AndFilter(new PacketTypeFilter(Presence.class),
-                new FromContainsFilter(workgroupJID)));
-
-        this.connection.sendPacket(presence);
-
-        presence = (Presence)collector.nextResult(5000);
-        collector.cancel();
-        if (!presence.isAvailable()) {
-            throw new XMPPException("No response from server on status set.");
-        }
-
-        if (presence.getError() != null) {
-            throw new XMPPException(presence.getError());
-        }
-    }
-
-    /**
-     * Removes a user from the workgroup queue. This is an administrative action that the
-     * <p/>
-     * The agent is not guaranteed of having privileges to perform this action; an exception
-     * denying the request may be thrown.
-     *
-     * @param userID the ID of the user to remove.
-     * @throws XMPPException if an exception occurs.
-     */
-    public void dequeueUser(String userID) throws XMPPException {
-        // todo: this method simply won't work right now.
-        DepartQueuePacket departPacket = new DepartQueuePacket(this.workgroupJID);
-
-        // PENDING
-        this.connection.sendPacket(departPacket);
-    }
-
-    /**
-     * Returns the transcripts of a given user. The answer will contain the complete history of
-     * conversations that a user had.
-     *
-     * @param userID the id of the user to get his conversations.
-     * @return the transcripts of a given user.
-     * @throws XMPPException if an error occurs while getting the information.
-     */
-    public Transcripts getTranscripts(String userID) throws XMPPException {
-        return transcriptManager.getTranscripts(workgroupJID, userID);
-    }
-
-    /**
-     * Returns the full conversation transcript of a given session.
-     *
-     * @param sessionID the id of the session to get the full transcript.
-     * @return the full conversation transcript of a given session.
-     * @throws XMPPException if an error occurs while getting the information.
-     */
-    public Transcript getTranscript(String sessionID) throws XMPPException {
-        return transcriptManager.getTranscript(workgroupJID, sessionID);
-    }
-
-    /**
-     * Returns the Form to use for searching transcripts. It is unlikely that the server
-     * will change the form (without a restart) so it is safe to keep the returned form
-     * for future submissions.
-     *
-     * @return the Form to use for searching transcripts.
-     * @throws XMPPException if an error occurs while sending the request to the server.
-     */
-    public Form getTranscriptSearchForm() throws XMPPException {
-        return transcriptSearchManager.getSearchForm(StringUtils.parseServer(workgroupJID));
-    }
-
-    /**
-     * Submits the completed form and returns the result of the transcript search. The result
-     * will include all the data returned from the server so be careful with the amount of
-     * data that the search may return.
-     *
-     * @param completedForm the filled out search form.
-     * @return the result of the transcript search.
-     * @throws XMPPException if an error occurs while submiting the search to the server.
-     */
-    public ReportedData searchTranscripts(Form completedForm) throws XMPPException {
-        return transcriptSearchManager.submitSearch(StringUtils.parseServer(workgroupJID),
-                completedForm);
-    }
-
-    /**
-     * Asks the workgroup for information about the occupants of the specified room. The returned
-     * information will include the real JID of the occupants, the nickname of the user in the
-     * room as well as the date when the user joined the room.
-     *
-     * @param roomID the room to get information about its occupants.
-     * @return information about the occupants of the specified room.
-     * @throws XMPPException if an error occurs while getting information from the server.
-     */
-    public OccupantsInfo getOccupantsInfo(String roomID) throws XMPPException {
-        OccupantsInfo request = new OccupantsInfo(roomID);
-        request.setType(IQ.Type.GET);
-        request.setTo(workgroupJID);
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
-        connection.sendPacket(request);
-
-        OccupantsInfo response = (OccupantsInfo)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response;
-    }
-
-    /**
-     * @return the fully-qualified name of the workgroup for which this session exists
-     */
-    public String getWorkgroupJID() {
-        return workgroupJID;
-    }
-
-    /**
-     * Returns the Agent associated to this session.
-     *
-     * @return the Agent associated to this session.
-     */
-    public Agent getAgent() {
-        return agent;
-    }
-
-    /**
-     * @param queueName the name of the queue
-     * @return an instance of WorkgroupQueue for the argument queue name, or null if none exists
-     */
-    public WorkgroupQueue getQueue(String queueName) {
-        return queues.get(queueName);
-    }
-
-    public Iterator<WorkgroupQueue> getQueues() {
-        return Collections.unmodifiableMap((new HashMap<String, WorkgroupQueue>(queues))).values().iterator();
-    }
-
-    public void addQueueUsersListener(QueueUsersListener listener) {
-        synchronized (queueUsersListeners) {
-            if (!queueUsersListeners.contains(listener)) {
-                queueUsersListeners.add(listener);
-            }
-        }
-    }
-
-    public void removeQueueUsersListener(QueueUsersListener listener) {
-        synchronized (queueUsersListeners) {
-            queueUsersListeners.remove(listener);
-        }
-    }
-
-    /**
-     * Adds an offer listener.
-     *
-     * @param offerListener the offer listener.
-     */
-    public void addOfferListener(OfferListener offerListener) {
-        synchronized (offerListeners) {
-            if (!offerListeners.contains(offerListener)) {
-                offerListeners.add(offerListener);
-            }
-        }
-    }
-
-    /**
-     * Removes an offer listener.
-     *
-     * @param offerListener the offer listener.
-     */
-    public void removeOfferListener(OfferListener offerListener) {
-        synchronized (offerListeners) {
-            offerListeners.remove(offerListener);
-        }
-    }
-
-    /**
-     * Adds an invitation listener.
-     *
-     * @param invitationListener the invitation listener.
-     */
-    public void addInvitationListener(WorkgroupInvitationListener invitationListener) {
-        synchronized (invitationListeners) {
-            if (!invitationListeners.contains(invitationListener)) {
-                invitationListeners.add(invitationListener);
-            }
-        }
-    }
-
-    /**
-     * Removes an invitation listener.
-     *
-     * @param invitationListener the invitation listener.
-     */
-    public void removeInvitationListener(WorkgroupInvitationListener invitationListener) {
-        synchronized (invitationListeners) {
-            invitationListeners.remove(invitationListener);
-        }
-    }
-
-    private void fireOfferRequestEvent(OfferRequestProvider.OfferRequestPacket requestPacket) {
-        Offer offer = new Offer(this.connection, this, requestPacket.getUserID(),
-                requestPacket.getUserJID(), this.getWorkgroupJID(),
-                new Date((new Date()).getTime() + (requestPacket.getTimeout() * 1000)),
-                requestPacket.getSessionID(), requestPacket.getMetaData(), requestPacket.getContent());
-
-        synchronized (offerListeners) {
-            for (OfferListener listener : offerListeners) {
-                listener.offerReceived(offer);
-            }
-        }
-    }
-
-    private void fireOfferRevokeEvent(OfferRevokeProvider.OfferRevokePacket orp) {
-        RevokedOffer revokedOffer = new RevokedOffer(orp.getUserJID(), orp.getUserID(),
-                this.getWorkgroupJID(), orp.getSessionID(), orp.getReason(), new Date());
-
-        synchronized (offerListeners) {
-            for (OfferListener listener : offerListeners) {
-                listener.offerRevoked(revokedOffer);
-            }
-        }
-    }
-
-    private void fireInvitationEvent(String groupChatJID, String sessionID, String body,
-                                     String from, Map<String, List<String>> metaData) {
-        WorkgroupInvitation invitation = new WorkgroupInvitation(connection.getUser(), groupChatJID,
-                workgroupJID, sessionID, body, from, metaData);
-
-        synchronized (invitationListeners) {
-            for (WorkgroupInvitationListener listener : invitationListeners) {
-                listener.invitationReceived(invitation);
-            }
-        }
-    }
-
-    private void fireQueueUsersEvent(WorkgroupQueue queue, WorkgroupQueue.Status status,
-                                     int averageWaitTime, Date oldestEntry, Set<QueueUser> users) {
-        synchronized (queueUsersListeners) {
-            for (QueueUsersListener listener : queueUsersListeners) {
-                if (status != null) {
-                    listener.statusUpdated(queue, status);
-                }
-                if (averageWaitTime != -1) {
-                    listener.averageWaitTimeUpdated(queue, averageWaitTime);
-                }
-                if (oldestEntry != null) {
-                    listener.oldestEntryUpdated(queue, oldestEntry);
-                }
-                if (users != null) {
-                    listener.usersUpdated(queue, users);
-                }
-            }
-        }
-    }
-
-    // PacketListener Implementation.
-
-    private void handlePacket(Packet packet) {
-        if (packet instanceof OfferRequestProvider.OfferRequestPacket) {
-            // Acknowledge the IQ set.
-            IQ reply = new IQ() {
-                public String getChildElementXML() {
-                    return null;
-                }
-            };
-            reply.setPacketID(packet.getPacketID());
-            reply.setTo(packet.getFrom());
-            reply.setType(IQ.Type.RESULT);
-            connection.sendPacket(reply);
-
-            fireOfferRequestEvent((OfferRequestProvider.OfferRequestPacket)packet);
-        }
-        else if (packet instanceof Presence) {
-            Presence presence = (Presence)packet;
-
-            // The workgroup can send us a number of different presence packets. We
-            // check for different packet extensions to see what type of presence
-            // packet it is.
-
-            String queueName = StringUtils.parseResource(presence.getFrom());
-            WorkgroupQueue queue = queues.get(queueName);
-            // If there isn't already an entry for the queue, create a new one.
-            if (queue == null) {
-                queue = new WorkgroupQueue(queueName);
-                queues.put(queueName, queue);
-            }
-
-            // QueueOverview packet extensions contain basic information about a queue.
-            QueueOverview queueOverview = (QueueOverview)presence.getExtension(QueueOverview.ELEMENT_NAME, QueueOverview.NAMESPACE);
-            if (queueOverview != null) {
-                if (queueOverview.getStatus() == null) {
-                    queue.setStatus(WorkgroupQueue.Status.CLOSED);
-                }
-                else {
-                    queue.setStatus(queueOverview.getStatus());
-                }
-                queue.setAverageWaitTime(queueOverview.getAverageWaitTime());
-                queue.setOldestEntry(queueOverview.getOldestEntry());
-                // Fire event.
-                fireQueueUsersEvent(queue, queueOverview.getStatus(),
-                        queueOverview.getAverageWaitTime(), queueOverview.getOldestEntry(),
-                        null);
-                return;
-            }
-
-            // QueueDetails packet extensions contain information about the users in
-            // a queue.
-            QueueDetails queueDetails = (QueueDetails)packet.getExtension(QueueDetails.ELEMENT_NAME, QueueDetails.NAMESPACE);
-            if (queueDetails != null) {
-                queue.setUsers(queueDetails.getUsers());
-                // Fire event.
-                fireQueueUsersEvent(queue, null, -1, null, queueDetails.getUsers());
-                return;
-            }
-
-            // Notify agent packets gives an overview of agent activity in a queue.
-            DefaultPacketExtension notifyAgents = (DefaultPacketExtension)presence.getExtension("notify-agents", "http://jabber.org/protocol/workgroup");
-            if (notifyAgents != null) {
-                int currentChats = Integer.parseInt(notifyAgents.getValue("current-chats"));
-                int maxChats = Integer.parseInt(notifyAgents.getValue("max-chats"));
-                queue.setCurrentChats(currentChats);
-                queue.setMaxChats(maxChats);
-                // Fire event.
-                // TODO: might need another event for current chats and max chats of queue
-                return;
-            }
-        }
-        else if (packet instanceof Message) {
-            Message message = (Message)packet;
-
-            // Check if a room invitation was sent and if the sender is the workgroup
-            MUCUser mucUser = (MUCUser)message.getExtension("x",
-                    "http://jabber.org/protocol/muc#user");
-            MUCUser.Invite invite = mucUser != null ? mucUser.getInvite() : null;
-            if (invite != null && workgroupJID.equals(invite.getFrom())) {
-                String sessionID = null;
-                Map<String, List<String>> metaData = null;
-
-                SessionID sessionIDExt = (SessionID)message.getExtension(SessionID.ELEMENT_NAME,
-                        SessionID.NAMESPACE);
-                if (sessionIDExt != null) {
-                    sessionID = sessionIDExt.getSessionID();
-                }
-
-                MetaData metaDataExt = (MetaData)message.getExtension(MetaData.ELEMENT_NAME,
-                        MetaData.NAMESPACE);
-                if (metaDataExt != null) {
-                    metaData = metaDataExt.getMetaData();
-                }
-
-                this.fireInvitationEvent(message.getFrom(), sessionID, message.getBody(),
-                        message.getFrom(), metaData);
-            }
-        }
-        else if (packet instanceof OfferRevokeProvider.OfferRevokePacket) {
-            // Acknowledge the IQ set.
-            IQ reply = new IQ() {
-                public String getChildElementXML() {
-                    return null;
-                }
-            };
-            reply.setPacketID(packet.getPacketID());
-            reply.setType(IQ.Type.RESULT);
-            connection.sendPacket(reply);
-
-            fireOfferRevokeEvent((OfferRevokeProvider.OfferRevokePacket)packet);
-        }
-    }
-
-    /**
-     * Creates a ChatNote that will be mapped to the given chat session.
-     *
-     * @param sessionID the session id of a Chat Session.
-     * @param note      the chat note to add.
-     * @throws XMPPException is thrown if an error occurs while adding the note.
-     */
-    public void setNote(String sessionID, String note) throws XMPPException {
-        note = ChatNotes.replace(note, "\n", "\\n");
-        note = StringUtils.escapeForXML(note);
-
-        ChatNotes notes = new ChatNotes();
-        notes.setType(IQ.Type.SET);
-        notes.setTo(workgroupJID);
-        notes.setSessionID(sessionID);
-        notes.setNotes(note);
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(notes.getPacketID()));
-        // Send the request
-        connection.sendPacket(notes);
-
-        IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server on status set.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-    }
-
-    /**
-     * Retrieves the ChatNote associated with a given chat session.
-     *
-     * @param sessionID the sessionID of the chat session.
-     * @return the <code>ChatNote</code> associated with a given chat session.
-     * @throws XMPPException if an error occurs while retrieving the ChatNote.
-     */
-    public ChatNotes getNote(String sessionID) throws XMPPException {
-        ChatNotes request = new ChatNotes();
-        request.setType(IQ.Type.GET);
-        request.setTo(workgroupJID);
-        request.setSessionID(sessionID);
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
-        connection.sendPacket(request);
-
-        ChatNotes response = (ChatNotes)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response;
-
-    }
-
-    /**
-     * Retrieves the AgentChatHistory associated with a particular agent jid.
-     *
-     * @param jid the jid of the agent.
-     * @param maxSessions the max number of sessions to retrieve.
-     * @param startDate the starting date of sessions to retrieve.
-     * @return the chat history associated with a given jid.
-     * @throws XMPPException if an error occurs while retrieving the AgentChatHistory.
-     */
-    public AgentChatHistory getAgentHistory(String jid, int maxSessions, Date startDate) throws XMPPException {
-        AgentChatHistory request;
-        if (startDate != null) {
-            request = new AgentChatHistory(jid, maxSessions, startDate);
-        }
-        else {
-            request = new AgentChatHistory(jid, maxSessions);
-        }
-
-        request.setType(IQ.Type.GET);
-        request.setTo(workgroupJID);
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
-        connection.sendPacket(request);
-
-        AgentChatHistory response = (AgentChatHistory)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response;
-    }
-
-    /**
-     * Asks the workgroup for it's Search Settings.
-     *
-     * @return SearchSettings the search settings for this workgroup.
-     * @throws XMPPException if an error occurs while getting information from the server.
-     */
-    public SearchSettings getSearchSettings() throws XMPPException {
-        SearchSettings request = new SearchSettings();
-        request.setType(IQ.Type.GET);
-        request.setTo(workgroupJID);
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
-        connection.sendPacket(request);
-
-
-        SearchSettings response = (SearchSettings)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response;
-    }
-
-    /**
-     * Asks the workgroup for it's Global Macros.
-     *
-     * @param global true to retrieve global macros, otherwise false for personal macros.
-     * @return MacroGroup the root macro group.
-     * @throws XMPPException if an error occurs while getting information from the server.
-     */
-    public MacroGroup getMacros(boolean global) throws XMPPException {
-        Macros request = new Macros();
-        request.setType(IQ.Type.GET);
-        request.setTo(workgroupJID);
-        request.setPersonal(!global);
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
-        connection.sendPacket(request);
-
-
-        Macros response = (Macros)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response.getRootGroup();
-    }
-
-    /**
-     * Persists the Personal Macro for an agent.
-     *
-     * @param group the macro group to save. 
-     * @throws XMPPException if an error occurs while getting information from the server.
-     */
-    public void saveMacros(MacroGroup group) throws XMPPException {
-        Macros request = new Macros();
-        request.setType(IQ.Type.SET);
-        request.setTo(workgroupJID);
-        request.setPersonal(true);
-        request.setPersonalMacroGroup(group);
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
-        connection.sendPacket(request);
-
-
-        IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server on status set.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-    }
-
-    /**
-     * Query for metadata associated with a session id.
-     *
-     * @param sessionID the sessionID to query for.
-     * @return Map a map of all metadata associated with the sessionID.
-     * @throws XMPPException if an error occurs while getting information from the server.
-     */
-    public Map<String, List<String>> getChatMetadata(String sessionID) throws XMPPException {
-        ChatMetadata request = new ChatMetadata();
-        request.setType(IQ.Type.GET);
-        request.setTo(workgroupJID);
-        request.setSessionID(sessionID);
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
-        connection.sendPacket(request);
-
-
-        ChatMetadata response = (ChatMetadata)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response.getMetadata();
-    }
-
-    /**
-     * Invites a user or agent to an existing session support. The provided invitee's JID can be of
-     * a user, an agent, a queue or a workgroup. In the case of a queue or a workgroup the workgroup service
-     * will decide the best agent to receive the invitation.<p>
-     *
-     * This method will return either when the service returned an ACK of the request or if an error occured
-     * while requesting the invitation. After sending the ACK the service will send the invitation to the target
-     * entity. When dealing with agents the common sequence of offer-response will be followed. However, when
-     * sending an invitation to a user a standard MUC invitation will be sent.<p>
-     *
-     * The agent or user that accepted the offer <b>MUST</b> join the room. Failing to do so will make
-     * the invitation to fail. The inviter will eventually receive a message error indicating that the invitee
-     * accepted the offer but failed to join the room.
-     *
-     * Different situations may lead to a failed invitation. Possible cases are: 1) all agents rejected the
-     * offer and ther are no agents available, 2) the agent that accepted the offer failed to join the room or
-     * 2) the user that received the MUC invitation never replied or joined the room. In any of these cases
-     * (or other failing cases) the inviter will get an error message with the failed notification.
-     *
-     * @param type type of entity that will get the invitation.
-     * @param invitee JID of entity that will get the invitation.
-     * @param sessionID ID of the support session that the invitee is being invited.
-     * @param reason the reason of the invitation.
-     * @throws XMPPException if the sender of the invitation is not an agent or the service failed to process
-     *         the request.
-     */
-    public void sendRoomInvitation(RoomInvitation.Type type, String invitee, String sessionID, String reason)
-            throws XMPPException {
-        final RoomInvitation invitation = new RoomInvitation(type, invitee, sessionID, reason);
-        IQ iq = new IQ() {
-
-            public String getChildElementXML() {
-                return invitation.toXML();
-            }
-        };
-        iq.setType(IQ.Type.SET);
-        iq.setTo(workgroupJID);
-        iq.setFrom(connection.getUser());
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(iq.getPacketID()));
-        connection.sendPacket(iq);
-
-        IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-    }
-
-    /**
-     * Transfer an existing session support to another user or agent. The provided invitee's JID can be of
-     * a user, an agent, a queue or a workgroup. In the case of a queue or a workgroup the workgroup service
-     * will decide the best agent to receive the invitation.<p>
-     *
-     * This method will return either when the service returned an ACK of the request or if an error occured
-     * while requesting the transfer. After sending the ACK the service will send the invitation to the target
-     * entity. When dealing with agents the common sequence of offer-response will be followed. However, when
-     * sending an invitation to a user a standard MUC invitation will be sent.<p>
-     *
-     * Once the invitee joins the support room the workgroup service will kick the inviter from the room.<p>
-     *
-     * Different situations may lead to a failed transfers. Possible cases are: 1) all agents rejected the
-     * offer and there are no agents available, 2) the agent that accepted the offer failed to join the room
-     * or 2) the user that received the MUC invitation never replied or joined the room. In any of these cases
-     * (or other failing cases) the inviter will get an error message with the failed notification.
-     *
-     * @param type type of entity that will get the invitation.
-     * @param invitee JID of entity that will get the invitation.
-     * @param sessionID ID of the support session that the invitee is being invited.
-     * @param reason the reason of the invitation.
-     * @throws XMPPException if the sender of the invitation is not an agent or the service failed to process
-     *         the request.
-     */
-    public void sendRoomTransfer(RoomTransfer.Type type, String invitee, String sessionID, String reason)
-            throws XMPPException {
-        final RoomTransfer transfer = new RoomTransfer(type, invitee, sessionID, reason);
-        IQ iq = new IQ() {
-
-            public String getChildElementXML() {
-                return transfer.toXML();
-            }
-        };
-        iq.setType(IQ.Type.SET);
-        iq.setTo(workgroupJID);
-        iq.setFrom(connection.getUser());
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(iq.getPacketID()));
-        connection.sendPacket(iq);
-
-        IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-    }
-
-    /**
-     * Returns the generic metadata of the workgroup the agent belongs to.
-     *
-     * @param con   the Connection to use.
-     * @param query an optional query object used to tell the server what metadata to retrieve. This can be null.
-     * @throws XMPPException if an error occurs while sending the request to the server.
-     * @return the settings for the workgroup.
-     */
-    public GenericSettings getGenericSettings(Connection con, String query) throws XMPPException {
-        GenericSettings setting = new GenericSettings();
-        setting.setType(IQ.Type.GET);
-        setting.setTo(workgroupJID);
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(setting.getPacketID()));
-        connection.sendPacket(setting);
-
-        GenericSettings response = (GenericSettings)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server on status set.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response;
-    }
-
-    public boolean hasMonitorPrivileges(Connection con) throws XMPPException {
-        MonitorPacket request = new MonitorPacket();
-        request.setType(IQ.Type.GET);
-        request.setTo(workgroupJID);
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
-        connection.sendPacket(request);
-
-        MonitorPacket response = (MonitorPacket)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server on status set.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response.isMonitor();
-
-    }
-
-    public void makeRoomOwner(Connection con, String sessionID) throws XMPPException {
-        MonitorPacket request = new MonitorPacket();
-        request.setType(IQ.Type.SET);
-        request.setTo(workgroupJID);
-        request.setSessionID(sessionID);
-
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
-        connection.sendPacket(request);
-
-        Packet response = collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server on status set.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-    }
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.agent;
+
+import org.jivesoftware.smackx.workgroup.MetaData;
+import org.jivesoftware.smackx.workgroup.QueueUser;
+import org.jivesoftware.smackx.workgroup.WorkgroupInvitation;
+import org.jivesoftware.smackx.workgroup.WorkgroupInvitationListener;
+import org.jivesoftware.smackx.workgroup.ext.history.AgentChatHistory;
+import org.jivesoftware.smackx.workgroup.ext.history.ChatMetadata;
+import org.jivesoftware.smackx.workgroup.ext.macros.MacroGroup;
+import org.jivesoftware.smackx.workgroup.ext.macros.Macros;
+import org.jivesoftware.smackx.workgroup.ext.notes.ChatNotes;
+import org.jivesoftware.smackx.workgroup.packet.*;
+import org.jivesoftware.smackx.workgroup.settings.GenericSettings;
+import org.jivesoftware.smackx.workgroup.settings.SearchSettings;
+import org.jivesoftware.smack.*;
+import org.jivesoftware.smack.filter.*;
+import org.jivesoftware.smack.packet.*;
+import org.jivesoftware.smack.util.StringUtils;
+import org.jivesoftware.smackx.Form;
+import org.jivesoftware.smackx.ReportedData;
+import org.jivesoftware.smackx.packet.MUCUser;
+
+import java.util.*;
+
+/**
+ * This class embodies the agent's active presence within a given workgroup. The application
+ * should have N instances of this class, where N is the number of workgroups to which the
+ * owning agent of the application belongs. This class provides all functionality that a
+ * session within a given workgroup is expected to have from an agent's perspective -- setting
+ * the status, tracking the status of queues to which the agent belongs within the workgroup, and
+ * dequeuing customers.
+ *
+ * @author Matt Tucker
+ * @author Derek DeMoro
+ */
+public class AgentSession {
+
+    private Connection connection;
+
+    private String workgroupJID;
+
+    private boolean online = false;
+    private Presence.Mode presenceMode;
+    private int maxChats;
+    private final Map<String, List<String>> metaData;
+
+    private Map<String, WorkgroupQueue> queues;
+
+    private final List<OfferListener> offerListeners;
+    private final List<WorkgroupInvitationListener> invitationListeners;
+    private final List<QueueUsersListener> queueUsersListeners;
+
+    private AgentRoster agentRoster = null;
+    private TranscriptManager transcriptManager;
+    private TranscriptSearchManager transcriptSearchManager;
+    private Agent agent;
+    private PacketListener packetListener;
+
+    /**
+     * Constructs a new agent session instance. Note, the {@link #setOnline(boolean)}
+     * method must be called with an argument of <tt>true</tt> to mark the agent
+     * as available to accept chat requests.
+     *
+     * @param connection   a connection instance which must have already gone through
+     *                     authentication.
+     * @param workgroupJID the fully qualified JID of the workgroup.
+     */
+    public AgentSession(String workgroupJID, Connection connection) {
+        // Login must have been done before passing in connection.
+        if (!connection.isAuthenticated()) {
+            throw new IllegalStateException("Must login to server before creating workgroup.");
+        }
+
+        this.workgroupJID = workgroupJID;
+        this.connection = connection;
+        this.transcriptManager = new TranscriptManager(connection);
+        this.transcriptSearchManager = new TranscriptSearchManager(connection);
+
+        this.maxChats = -1;
+
+        this.metaData = new HashMap<String, List<String>>();
+
+        this.queues = new HashMap<String, WorkgroupQueue>();
+
+        offerListeners = new ArrayList<OfferListener>();
+        invitationListeners = new ArrayList<WorkgroupInvitationListener>();
+        queueUsersListeners = new ArrayList<QueueUsersListener>();
+
+        // Create a filter to listen for packets we're interested in.
+        OrFilter filter = new OrFilter();
+        filter.addFilter(new PacketTypeFilter(OfferRequestProvider.OfferRequestPacket.class));
+        filter.addFilter(new PacketTypeFilter(OfferRevokeProvider.OfferRevokePacket.class));
+        filter.addFilter(new PacketTypeFilter(Presence.class));
+        filter.addFilter(new PacketTypeFilter(Message.class));
+
+        packetListener = new PacketListener() {
+            public void processPacket(Packet packet) {
+                try {
+                    handlePacket(packet);
+                }
+                catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        };
+        connection.addPacketListener(packetListener, filter);
+        // Create the agent associated to this session
+        agent = new Agent(connection, workgroupJID);
+    }
+
+    /**
+     * Close the agent session. The underlying connection will remain opened but the
+     * packet listeners that were added by this agent session will be removed.
+     */
+    public void close() {
+        connection.removePacketListener(packetListener);
+    }
+
+    /**
+     * Returns the agent roster for the workgroup, which contains
+     *
+     * @return the AgentRoster
+     */
+    public AgentRoster getAgentRoster() {
+        if (agentRoster == null) {
+            agentRoster = new AgentRoster(connection, workgroupJID);
+        }
+
+        // This might be the first time the user has asked for the roster. If so, we
+        // want to wait up to 2 seconds for the server to send back the list of agents.
+        // This behavior shields API users from having to worry about the fact that the
+        // operation is asynchronous, although they'll still have to listen for changes
+        // to the roster.
+        int elapsed = 0;
+        while (!agentRoster.rosterInitialized && elapsed <= 2000) {
+            try {
+                Thread.sleep(500);
+            }
+            catch (Exception e) {
+                // Ignore
+            }
+            elapsed += 500;
+        }
+        return agentRoster;
+    }
+
+    /**
+     * Returns the agent's current presence mode.
+     *
+     * @return the agent's current presence mode.
+     */
+    public Presence.Mode getPresenceMode() {
+        return presenceMode;
+    }
+
+    /**
+     * Returns the maximum number of chats the agent can participate in.
+     *
+     * @return the maximum number of chats the agent can participate in.
+     */
+    public int getMaxChats() {
+        return maxChats;
+    }
+
+    /**
+     * Returns true if the agent is online with the workgroup.
+     *
+     * @return true if the agent is online with the workgroup.
+     */
+    public boolean isOnline() {
+        return online;
+    }
+
+    /**
+     * Allows the addition of a new key-value pair to the agent's meta data, if the value is
+     * new data, the revised meta data will be rebroadcast in an agent's presence broadcast.
+     *
+     * @param key the meta data key
+     * @param val the non-null meta data value
+     * @throws XMPPException if an exception occurs.
+     */
+    public void setMetaData(String key, String val) throws XMPPException {
+        synchronized (this.metaData) {
+            List<String> oldVals = metaData.get(key);
+
+            if ((oldVals == null) || (!oldVals.get(0).equals(val))) {
+                oldVals.set(0, val);
+
+                setStatus(presenceMode, maxChats);
+            }
+        }
+    }
+
+    /**
+     * Allows the removal of data from the agent's meta data, if the key represents existing data,
+     * the revised meta data will be rebroadcast in an agent's presence broadcast.
+     *
+     * @param key the meta data key.
+     * @throws XMPPException if an exception occurs.
+     */
+    public void removeMetaData(String key) throws XMPPException {
+        synchronized (this.metaData) {
+            List<String> oldVal = metaData.remove(key);
+
+            if (oldVal != null) {
+                setStatus(presenceMode, maxChats);
+            }
+        }
+    }
+
+    /**
+     * Allows the retrieval of meta data for a specified key.
+     *
+     * @param key the meta data key
+     * @return the meta data value associated with the key or <tt>null</tt> if the meta-data
+     *         doesn't exist..
+     */
+    public List<String> getMetaData(String key) {
+        return metaData.get(key);
+    }
+
+    /**
+     * Sets whether the agent is online with the workgroup. If the user tries to go online with
+     * the workgroup but is not allowed to be an agent, an XMPPError with error code 401 will
+     * be thrown.
+     *
+     * @param online true to set the agent as online with the workgroup.
+     * @throws XMPPException if an error occurs setting the online status.
+     */
+    public void setOnline(boolean online) throws XMPPException {
+        // If the online status hasn't changed, do nothing.
+        if (this.online == online) {
+            return;
+        }
+
+        Presence presence;
+
+        // If the user is going online...
+        if (online) {
+            presence = new Presence(Presence.Type.available);
+            presence.setTo(workgroupJID);
+            presence.addExtension(new DefaultPacketExtension(AgentStatus.ELEMENT_NAME,
+                    AgentStatus.NAMESPACE));
+
+            PacketCollector collector = this.connection.createPacketCollector(new AndFilter(new PacketTypeFilter(Presence.class), new FromContainsFilter(workgroupJID)));
+
+            connection.sendPacket(presence);
+
+            presence = (Presence)collector.nextResult(5000);
+            collector.cancel();
+            if (!presence.isAvailable()) {
+                throw new XMPPException("No response from server on status set.");
+            }
+
+            if (presence.getError() != null) {
+                throw new XMPPException(presence.getError());
+            }
+
+            // We can safely update this iv since we didn't get any error
+            this.online = online;
+        }
+        // Otherwise the user is going offline...
+        else {
+            // Update this iv now since we don't care at this point of any error
+            this.online = online;
+
+            presence = new Presence(Presence.Type.unavailable);
+            presence.setTo(workgroupJID);
+            presence.addExtension(new DefaultPacketExtension(AgentStatus.ELEMENT_NAME,
+                    AgentStatus.NAMESPACE));
+            connection.sendPacket(presence);
+        }
+    }
+
+    /**
+     * Sets the agent's current status with the workgroup. The presence mode affects
+     * how offers are routed to the agent. The possible presence modes with their
+     * meanings are as follows:<ul>
+     * <p/>
+     * <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats
+     * (equivalent to Presence.Mode.CHAT).
+     * <li>Presence.Mode.DO_NOT_DISTURB -- the agent is busy and should not be disturbed.
+     * However, special case, or extreme urgency chats may still be offered to the agent.
+     * <li>Presence.Mode.AWAY -- the agent is not available and should not
+     * have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul>
+     * <p/>
+     * The max chats value is the maximum number of chats the agent is willing to have
+     * routed to them at once. Some servers may be configured to only accept max chat
+     * values in a certain range; for example, between two and five. In that case, the
+     * maxChats value the agent sends may be adjusted by the server to a value within that
+     * range.
+     *
+     * @param presenceMode the presence mode of the agent.
+     * @param maxChats     the maximum number of chats the agent is willing to accept.
+     * @throws XMPPException         if an error occurs setting the agent status.
+     * @throws IllegalStateException if the agent is not online with the workgroup.
+     */
+    public void setStatus(Presence.Mode presenceMode, int maxChats) throws XMPPException {
+        setStatus(presenceMode, maxChats, null);
+    }
+
+    /**
+     * Sets the agent's current status with the workgroup. The presence mode affects how offers
+     * are routed to the agent. The possible presence modes with their meanings are as follows:<ul>
+     * <p/>
+     * <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats
+     * (equivalent to Presence.Mode.CHAT).
+     * <li>Presence.Mode.DO_NOT_DISTURB -- the agent is busy and should not be disturbed.
+     * However, special case, or extreme urgency chats may still be offered to the agent.
+     * <li>Presence.Mode.AWAY -- the agent is not available and should not
+     * have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul>
+     * <p/>
+     * The max chats value is the maximum number of chats the agent is willing to have routed to
+     * them at once. Some servers may be configured to only accept max chat values in a certain
+     * range; for example, between two and five. In that case, the maxChats value the agent sends
+     * may be adjusted by the server to a value within that range.
+     *
+     * @param presenceMode the presence mode of the agent.
+     * @param maxChats     the maximum number of chats the agent is willing to accept.
+     * @param status       sets the status message of the presence update.
+     * @throws XMPPException         if an error occurs setting the agent status.
+     * @throws IllegalStateException if the agent is not online with the workgroup.
+     */
+    public void setStatus(Presence.Mode presenceMode, int maxChats, String status)
+            throws XMPPException {
+        if (!online) {
+            throw new IllegalStateException("Cannot set status when the agent is not online.");
+        }
+
+        if (presenceMode == null) {
+            presenceMode = Presence.Mode.available;
+        }
+        this.presenceMode = presenceMode;
+        this.maxChats = maxChats;
+
+        Presence presence = new Presence(Presence.Type.available);
+        presence.setMode(presenceMode);
+        presence.setTo(this.getWorkgroupJID());
+
+        if (status != null) {
+            presence.setStatus(status);
+        }
+        // Send information about max chats and current chats as a packet extension.
+        DefaultPacketExtension agentStatus = new DefaultPacketExtension(AgentStatus.ELEMENT_NAME,
+                AgentStatus.NAMESPACE);
+        agentStatus.setValue("max-chats", "" + maxChats);
+        presence.addExtension(agentStatus);
+        presence.addExtension(new MetaData(this.metaData));
+
+        PacketCollector collector = this.connection.createPacketCollector(new AndFilter(new PacketTypeFilter(Presence.class), new FromContainsFilter(workgroupJID)));
+
+        this.connection.sendPacket(presence);
+
+        presence = (Presence)collector.nextResult(5000);
+        collector.cancel();
+        if (!presence.isAvailable()) {
+            throw new XMPPException("No response from server on status set.");
+        }
+
+        if (presence.getError() != null) {
+            throw new XMPPException(presence.getError());
+        }
+    }
+
+    /**
+     * Sets the agent's current status with the workgroup. The presence mode affects how offers
+     * are routed to the agent. The possible presence modes with their meanings are as follows:<ul>
+     * <p/>
+     * <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats
+     * (equivalent to Presence.Mode.CHAT).
+     * <li>Presence.Mode.DO_NOT_DISTURB -- the agent is busy and should not be disturbed.
+     * However, special case, or extreme urgency chats may still be offered to the agent.
+     * <li>Presence.Mode.AWAY -- the agent is not available and should not
+     * have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul>
+     *
+     * @param presenceMode the presence mode of the agent.
+     * @param status       sets the status message of the presence update.
+     * @throws XMPPException         if an error occurs setting the agent status.
+     * @throws IllegalStateException if the agent is not online with the workgroup.
+     */
+    public void setStatus(Presence.Mode presenceMode, String status) throws XMPPException {
+        if (!online) {
+            throw new IllegalStateException("Cannot set status when the agent is not online.");
+        }
+
+        if (presenceMode == null) {
+            presenceMode = Presence.Mode.available;
+        }
+        this.presenceMode = presenceMode;
+
+        Presence presence = new Presence(Presence.Type.available);
+        presence.setMode(presenceMode);
+        presence.setTo(this.getWorkgroupJID());
+
+        if (status != null) {
+            presence.setStatus(status);
+        }
+        presence.addExtension(new MetaData(this.metaData));
+
+        PacketCollector collector = this.connection.createPacketCollector(new AndFilter(new PacketTypeFilter(Presence.class),
+                new FromContainsFilter(workgroupJID)));
+
+        this.connection.sendPacket(presence);
+
+        presence = (Presence)collector.nextResult(5000);
+        collector.cancel();
+        if (!presence.isAvailable()) {
+            throw new XMPPException("No response from server on status set.");
+        }
+
+        if (presence.getError() != null) {
+            throw new XMPPException(presence.getError());
+        }
+    }
+
+    /**
+     * Removes a user from the workgroup queue. This is an administrative action that the
+     * <p/>
+     * The agent is not guaranteed of having privileges to perform this action; an exception
+     * denying the request may be thrown.
+     *
+     * @param userID the ID of the user to remove.
+     * @throws XMPPException if an exception occurs.
+     */
+    public void dequeueUser(String userID) throws XMPPException {
+        // todo: this method simply won't work right now.
+        DepartQueuePacket departPacket = new DepartQueuePacket(this.workgroupJID);
+
+        // PENDING
+        this.connection.sendPacket(departPacket);
+    }
+
+    /**
+     * Returns the transcripts of a given user. The answer will contain the complete history of
+     * conversations that a user had.
+     *
+     * @param userID the id of the user to get his conversations.
+     * @return the transcripts of a given user.
+     * @throws XMPPException if an error occurs while getting the information.
+     */
+    public Transcripts getTranscripts(String userID) throws XMPPException {
+        return transcriptManager.getTranscripts(workgroupJID, userID);
+    }
+
+    /**
+     * Returns the full conversation transcript of a given session.
+     *
+     * @param sessionID the id of the session to get the full transcript.
+     * @return the full conversation transcript of a given session.
+     * @throws XMPPException if an error occurs while getting the information.
+     */
+    public Transcript getTranscript(String sessionID) throws XMPPException {
+        return transcriptManager.getTranscript(workgroupJID, sessionID);
+    }
+
+    /**
+     * Returns the Form to use for searching transcripts. It is unlikely that the server
+     * will change the form (without a restart) so it is safe to keep the returned form
+     * for future submissions.
+     *
+     * @return the Form to use for searching transcripts.
+     * @throws XMPPException if an error occurs while sending the request to the server.
+     */
+    public Form getTranscriptSearchForm() throws XMPPException {
+        return transcriptSearchManager.getSearchForm(StringUtils.parseServer(workgroupJID));
+    }
+
+    /**
+     * Submits the completed form and returns the result of the transcript search. The result
+     * will include all the data returned from the server so be careful with the amount of
+     * data that the search may return.
+     *
+     * @param completedForm the filled out search form.
+     * @return the result of the transcript search.
+     * @throws XMPPException if an error occurs while submiting the search to the server.
+     */
+    public ReportedData searchTranscripts(Form completedForm) throws XMPPException {
+        return transcriptSearchManager.submitSearch(StringUtils.parseServer(workgroupJID),
+                completedForm);
+    }
+
+    /**
+     * Asks the workgroup for information about the occupants of the specified room. The returned
+     * information will include the real JID of the occupants, the nickname of the user in the
+     * room as well as the date when the user joined the room.
+     *
+     * @param roomID the room to get information about its occupants.
+     * @return information about the occupants of the specified room.
+     * @throws XMPPException if an error occurs while getting information from the server.
+     */
+    public OccupantsInfo getOccupantsInfo(String roomID) throws XMPPException {
+        OccupantsInfo request = new OccupantsInfo(roomID);
+        request.setType(IQ.Type.GET);
+        request.setTo(workgroupJID);
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
+        connection.sendPacket(request);
+
+        OccupantsInfo response = (OccupantsInfo)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response;
+    }
+
+    /**
+     * @return the fully-qualified name of the workgroup for which this session exists
+     */
+    public String getWorkgroupJID() {
+        return workgroupJID;
+    }
+
+    /**
+     * Returns the Agent associated to this session.
+     *
+     * @return the Agent associated to this session.
+     */
+    public Agent getAgent() {
+        return agent;
+    }
+
+    /**
+     * @param queueName the name of the queue
+     * @return an instance of WorkgroupQueue for the argument queue name, or null if none exists
+     */
+    public WorkgroupQueue getQueue(String queueName) {
+        return queues.get(queueName);
+    }
+
+    public Iterator<WorkgroupQueue> getQueues() {
+        return Collections.unmodifiableMap((new HashMap<String, WorkgroupQueue>(queues))).values().iterator();
+    }
+
+    public void addQueueUsersListener(QueueUsersListener listener) {
+        synchronized (queueUsersListeners) {
+            if (!queueUsersListeners.contains(listener)) {
+                queueUsersListeners.add(listener);
+            }
+        }
+    }
+
+    public void removeQueueUsersListener(QueueUsersListener listener) {
+        synchronized (queueUsersListeners) {
+            queueUsersListeners.remove(listener);
+        }
+    }
+
+    /**
+     * Adds an offer listener.
+     *
+     * @param offerListener the offer listener.
+     */
+    public void addOfferListener(OfferListener offerListener) {
+        synchronized (offerListeners) {
+            if (!offerListeners.contains(offerListener)) {
+                offerListeners.add(offerListener);
+            }
+        }
+    }
+
+    /**
+     * Removes an offer listener.
+     *
+     * @param offerListener the offer listener.
+     */
+    public void removeOfferListener(OfferListener offerListener) {
+        synchronized (offerListeners) {
+            offerListeners.remove(offerListener);
+        }
+    }
+
+    /**
+     * Adds an invitation listener.
+     *
+     * @param invitationListener the invitation listener.
+     */
+    public void addInvitationListener(WorkgroupInvitationListener invitationListener) {
+        synchronized (invitationListeners) {
+            if (!invitationListeners.contains(invitationListener)) {
+                invitationListeners.add(invitationListener);
+            }
+        }
+    }
+
+    /**
+     * Removes an invitation listener.
+     *
+     * @param invitationListener the invitation listener.
+     */
+    public void removeInvitationListener(WorkgroupInvitationListener invitationListener) {
+        synchronized (invitationListeners) {
+            invitationListeners.remove(invitationListener);
+        }
+    }
+
+    private void fireOfferRequestEvent(OfferRequestProvider.OfferRequestPacket requestPacket) {
+        Offer offer = new Offer(this.connection, this, requestPacket.getUserID(),
+                requestPacket.getUserJID(), this.getWorkgroupJID(),
+                new Date((new Date()).getTime() + (requestPacket.getTimeout() * 1000)),
+                requestPacket.getSessionID(), requestPacket.getMetaData(), requestPacket.getContent());
+
+        synchronized (offerListeners) {
+            for (OfferListener listener : offerListeners) {
+                listener.offerReceived(offer);
+            }
+        }
+    }
+
+    private void fireOfferRevokeEvent(OfferRevokeProvider.OfferRevokePacket orp) {
+        RevokedOffer revokedOffer = new RevokedOffer(orp.getUserJID(), orp.getUserID(),
+                this.getWorkgroupJID(), orp.getSessionID(), orp.getReason(), new Date());
+
+        synchronized (offerListeners) {
+            for (OfferListener listener : offerListeners) {
+                listener.offerRevoked(revokedOffer);
+            }
+        }
+    }
+
+    private void fireInvitationEvent(String groupChatJID, String sessionID, String body,
+                                     String from, Map<String, List<String>> metaData) {
+        WorkgroupInvitation invitation = new WorkgroupInvitation(connection.getUser(), groupChatJID,
+                workgroupJID, sessionID, body, from, metaData);
+
+        synchronized (invitationListeners) {
+            for (WorkgroupInvitationListener listener : invitationListeners) {
+                listener.invitationReceived(invitation);
+            }
+        }
+    }
+
+    private void fireQueueUsersEvent(WorkgroupQueue queue, WorkgroupQueue.Status status,
+                                     int averageWaitTime, Date oldestEntry, Set<QueueUser> users) {
+        synchronized (queueUsersListeners) {
+            for (QueueUsersListener listener : queueUsersListeners) {
+                if (status != null) {
+                    listener.statusUpdated(queue, status);
+                }
+                if (averageWaitTime != -1) {
+                    listener.averageWaitTimeUpdated(queue, averageWaitTime);
+                }
+                if (oldestEntry != null) {
+                    listener.oldestEntryUpdated(queue, oldestEntry);
+                }
+                if (users != null) {
+                    listener.usersUpdated(queue, users);
+                }
+            }
+        }
+    }
+
+    // PacketListener Implementation.
+
+    private void handlePacket(Packet packet) {
+        if (packet instanceof OfferRequestProvider.OfferRequestPacket) {
+            // Acknowledge the IQ set.
+            IQ reply = new IQ() {
+                public String getChildElementXML() {
+                    return null;
+                }
+            };
+            reply.setPacketID(packet.getPacketID());
+            reply.setTo(packet.getFrom());
+            reply.setType(IQ.Type.RESULT);
+            connection.sendPacket(reply);
+
+            fireOfferRequestEvent((OfferRequestProvider.OfferRequestPacket)packet);
+        }
+        else if (packet instanceof Presence) {
+            Presence presence = (Presence)packet;
+
+            // The workgroup can send us a number of different presence packets. We
+            // check for different packet extensions to see what type of presence
+            // packet it is.
+
+            String queueName = StringUtils.parseResource(presence.getFrom());
+            WorkgroupQueue queue = queues.get(queueName);
+            // If there isn't already an entry for the queue, create a new one.
+            if (queue == null) {
+                queue = new WorkgroupQueue(queueName);
+                queues.put(queueName, queue);
+            }
+
+            // QueueOverview packet extensions contain basic information about a queue.
+            QueueOverview queueOverview = (QueueOverview)presence.getExtension(QueueOverview.ELEMENT_NAME, QueueOverview.NAMESPACE);
+            if (queueOverview != null) {
+                if (queueOverview.getStatus() == null) {
+                    queue.setStatus(WorkgroupQueue.Status.CLOSED);
+                }
+                else {
+                    queue.setStatus(queueOverview.getStatus());
+                }
+                queue.setAverageWaitTime(queueOverview.getAverageWaitTime());
+                queue.setOldestEntry(queueOverview.getOldestEntry());
+                // Fire event.
+                fireQueueUsersEvent(queue, queueOverview.getStatus(),
+                        queueOverview.getAverageWaitTime(), queueOverview.getOldestEntry(),
+                        null);
+                return;
+            }
+
+            // QueueDetails packet extensions contain information about the users in
+            // a queue.
+            QueueDetails queueDetails = (QueueDetails)packet.getExtension(QueueDetails.ELEMENT_NAME, QueueDetails.NAMESPACE);
+            if (queueDetails != null) {
+                queue.setUsers(queueDetails.getUsers());
+                // Fire event.
+                fireQueueUsersEvent(queue, null, -1, null, queueDetails.getUsers());
+                return;
+            }
+
+            // Notify agent packets gives an overview of agent activity in a queue.
+            DefaultPacketExtension notifyAgents = (DefaultPacketExtension)presence.getExtension("notify-agents", "http://jabber.org/protocol/workgroup");
+            if (notifyAgents != null) {
+                int currentChats = Integer.parseInt(notifyAgents.getValue("current-chats"));
+                int maxChats = Integer.parseInt(notifyAgents.getValue("max-chats"));
+                queue.setCurrentChats(currentChats);
+                queue.setMaxChats(maxChats);
+                // Fire event.
+                // TODO: might need another event for current chats and max chats of queue
+                return;
+            }
+        }
+        else if (packet instanceof Message) {
+            Message message = (Message)packet;
+
+            // Check if a room invitation was sent and if the sender is the workgroup
+            MUCUser mucUser = (MUCUser)message.getExtension("x",
+                    "http://jabber.org/protocol/muc#user");
+            MUCUser.Invite invite = mucUser != null ? mucUser.getInvite() : null;
+            if (invite != null && workgroupJID.equals(invite.getFrom())) {
+                String sessionID = null;
+                Map<String, List<String>> metaData = null;
+
+                SessionID sessionIDExt = (SessionID)message.getExtension(SessionID.ELEMENT_NAME,
+                        SessionID.NAMESPACE);
+                if (sessionIDExt != null) {
+                    sessionID = sessionIDExt.getSessionID();
+                }
+
+                MetaData metaDataExt = (MetaData)message.getExtension(MetaData.ELEMENT_NAME,
+                        MetaData.NAMESPACE);
+                if (metaDataExt != null) {
+                    metaData = metaDataExt.getMetaData();
+                }
+
+                this.fireInvitationEvent(message.getFrom(), sessionID, message.getBody(),
+                        message.getFrom(), metaData);
+            }
+        }
+        else if (packet instanceof OfferRevokeProvider.OfferRevokePacket) {
+            // Acknowledge the IQ set.
+            IQ reply = new IQ() {
+                public String getChildElementXML() {
+                    return null;
+                }
+            };
+            reply.setPacketID(packet.getPacketID());
+            reply.setType(IQ.Type.RESULT);
+            connection.sendPacket(reply);
+
+            fireOfferRevokeEvent((OfferRevokeProvider.OfferRevokePacket)packet);
+        }
+    }
+
+    /**
+     * Creates a ChatNote that will be mapped to the given chat session.
+     *
+     * @param sessionID the session id of a Chat Session.
+     * @param note      the chat note to add.
+     * @throws XMPPException is thrown if an error occurs while adding the note.
+     */
+    public void setNote(String sessionID, String note) throws XMPPException {
+        note = ChatNotes.replace(note, "\n", "\\n");
+        note = StringUtils.escapeForXML(note);
+
+        ChatNotes notes = new ChatNotes();
+        notes.setType(IQ.Type.SET);
+        notes.setTo(workgroupJID);
+        notes.setSessionID(sessionID);
+        notes.setNotes(note);
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(notes.getPacketID()));
+        // Send the request
+        connection.sendPacket(notes);
+
+        IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server on status set.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+    }
+
+    /**
+     * Retrieves the ChatNote associated with a given chat session.
+     *
+     * @param sessionID the sessionID of the chat session.
+     * @return the <code>ChatNote</code> associated with a given chat session.
+     * @throws XMPPException if an error occurs while retrieving the ChatNote.
+     */
+    public ChatNotes getNote(String sessionID) throws XMPPException {
+        ChatNotes request = new ChatNotes();
+        request.setType(IQ.Type.GET);
+        request.setTo(workgroupJID);
+        request.setSessionID(sessionID);
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
+        connection.sendPacket(request);
+
+        ChatNotes response = (ChatNotes)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response;
+
+    }
+
+    /**
+     * Retrieves the AgentChatHistory associated with a particular agent jid.
+     *
+     * @param jid the jid of the agent.
+     * @param maxSessions the max number of sessions to retrieve.
+     * @param startDate the starting date of sessions to retrieve.
+     * @return the chat history associated with a given jid.
+     * @throws XMPPException if an error occurs while retrieving the AgentChatHistory.
+     */
+    public AgentChatHistory getAgentHistory(String jid, int maxSessions, Date startDate) throws XMPPException {
+        AgentChatHistory request;
+        if (startDate != null) {
+            request = new AgentChatHistory(jid, maxSessions, startDate);
+        }
+        else {
+            request = new AgentChatHistory(jid, maxSessions);
+        }
+
+        request.setType(IQ.Type.GET);
+        request.setTo(workgroupJID);
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
+        connection.sendPacket(request);
+
+        AgentChatHistory response = (AgentChatHistory)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response;
+    }
+
+    /**
+     * Asks the workgroup for it's Search Settings.
+     *
+     * @return SearchSettings the search settings for this workgroup.
+     * @throws XMPPException if an error occurs while getting information from the server.
+     */
+    public SearchSettings getSearchSettings() throws XMPPException {
+        SearchSettings request = new SearchSettings();
+        request.setType(IQ.Type.GET);
+        request.setTo(workgroupJID);
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
+        connection.sendPacket(request);
+
+
+        SearchSettings response = (SearchSettings)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response;
+    }
+
+    /**
+     * Asks the workgroup for it's Global Macros.
+     *
+     * @param global true to retrieve global macros, otherwise false for personal macros.
+     * @return MacroGroup the root macro group.
+     * @throws XMPPException if an error occurs while getting information from the server.
+     */
+    public MacroGroup getMacros(boolean global) throws XMPPException {
+        Macros request = new Macros();
+        request.setType(IQ.Type.GET);
+        request.setTo(workgroupJID);
+        request.setPersonal(!global);
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
+        connection.sendPacket(request);
+
+
+        Macros response = (Macros)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response.getRootGroup();
+    }
+
+    /**
+     * Persists the Personal Macro for an agent.
+     *
+     * @param group the macro group to save. 
+     * @throws XMPPException if an error occurs while getting information from the server.
+     */
+    public void saveMacros(MacroGroup group) throws XMPPException {
+        Macros request = new Macros();
+        request.setType(IQ.Type.SET);
+        request.setTo(workgroupJID);
+        request.setPersonal(true);
+        request.setPersonalMacroGroup(group);
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
+        connection.sendPacket(request);
+
+
+        IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server on status set.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+    }
+
+    /**
+     * Query for metadata associated with a session id.
+     *
+     * @param sessionID the sessionID to query for.
+     * @return Map a map of all metadata associated with the sessionID.
+     * @throws XMPPException if an error occurs while getting information from the server.
+     */
+    public Map<String, List<String>> getChatMetadata(String sessionID) throws XMPPException {
+        ChatMetadata request = new ChatMetadata();
+        request.setType(IQ.Type.GET);
+        request.setTo(workgroupJID);
+        request.setSessionID(sessionID);
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
+        connection.sendPacket(request);
+
+
+        ChatMetadata response = (ChatMetadata)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response.getMetadata();
+    }
+
+    /**
+     * Invites a user or agent to an existing session support. The provided invitee's JID can be of
+     * a user, an agent, a queue or a workgroup. In the case of a queue or a workgroup the workgroup service
+     * will decide the best agent to receive the invitation.<p>
+     *
+     * This method will return either when the service returned an ACK of the request or if an error occured
+     * while requesting the invitation. After sending the ACK the service will send the invitation to the target
+     * entity. When dealing with agents the common sequence of offer-response will be followed. However, when
+     * sending an invitation to a user a standard MUC invitation will be sent.<p>
+     *
+     * The agent or user that accepted the offer <b>MUST</b> join the room. Failing to do so will make
+     * the invitation to fail. The inviter will eventually receive a message error indicating that the invitee
+     * accepted the offer but failed to join the room.
+     *
+     * Different situations may lead to a failed invitation. Possible cases are: 1) all agents rejected the
+     * offer and ther are no agents available, 2) the agent that accepted the offer failed to join the room or
+     * 2) the user that received the MUC invitation never replied or joined the room. In any of these cases
+     * (or other failing cases) the inviter will get an error message with the failed notification.
+     *
+     * @param type type of entity that will get the invitation.
+     * @param invitee JID of entity that will get the invitation.
+     * @param sessionID ID of the support session that the invitee is being invited.
+     * @param reason the reason of the invitation.
+     * @throws XMPPException if the sender of the invitation is not an agent or the service failed to process
+     *         the request.
+     */
+    public void sendRoomInvitation(RoomInvitation.Type type, String invitee, String sessionID, String reason)
+            throws XMPPException {
+        final RoomInvitation invitation = new RoomInvitation(type, invitee, sessionID, reason);
+        IQ iq = new IQ() {
+
+            public String getChildElementXML() {
+                return invitation.toXML();
+            }
+        };
+        iq.setType(IQ.Type.SET);
+        iq.setTo(workgroupJID);
+        iq.setFrom(connection.getUser());
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(iq.getPacketID()));
+        connection.sendPacket(iq);
+
+        IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+    }
+
+    /**
+     * Transfer an existing session support to another user or agent. The provided invitee's JID can be of
+     * a user, an agent, a queue or a workgroup. In the case of a queue or a workgroup the workgroup service
+     * will decide the best agent to receive the invitation.<p>
+     *
+     * This method will return either when the service returned an ACK of the request or if an error occured
+     * while requesting the transfer. After sending the ACK the service will send the invitation to the target
+     * entity. When dealing with agents the common sequence of offer-response will be followed. However, when
+     * sending an invitation to a user a standard MUC invitation will be sent.<p>
+     *
+     * Once the invitee joins the support room the workgroup service will kick the inviter from the room.<p>
+     *
+     * Different situations may lead to a failed transfers. Possible cases are: 1) all agents rejected the
+     * offer and there are no agents available, 2) the agent that accepted the offer failed to join the room
+     * or 2) the user that received the MUC invitation never replied or joined the room. In any of these cases
+     * (or other failing cases) the inviter will get an error message with the failed notification.
+     *
+     * @param type type of entity that will get the invitation.
+     * @param invitee JID of entity that will get the invitation.
+     * @param sessionID ID of the support session that the invitee is being invited.
+     * @param reason the reason of the invitation.
+     * @throws XMPPException if the sender of the invitation is not an agent or the service failed to process
+     *         the request.
+     */
+    public void sendRoomTransfer(RoomTransfer.Type type, String invitee, String sessionID, String reason)
+            throws XMPPException {
+        final RoomTransfer transfer = new RoomTransfer(type, invitee, sessionID, reason);
+        IQ iq = new IQ() {
+
+            public String getChildElementXML() {
+                return transfer.toXML();
+            }
+        };
+        iq.setType(IQ.Type.SET);
+        iq.setTo(workgroupJID);
+        iq.setFrom(connection.getUser());
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(iq.getPacketID()));
+        connection.sendPacket(iq);
+
+        IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+    }
+
+    /**
+     * Returns the generic metadata of the workgroup the agent belongs to.
+     *
+     * @param con   the Connection to use.
+     * @param query an optional query object used to tell the server what metadata to retrieve. This can be null.
+     * @throws XMPPException if an error occurs while sending the request to the server.
+     * @return the settings for the workgroup.
+     */
+    public GenericSettings getGenericSettings(Connection con, String query) throws XMPPException {
+        GenericSettings setting = new GenericSettings();
+        setting.setType(IQ.Type.GET);
+        setting.setTo(workgroupJID);
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(setting.getPacketID()));
+        connection.sendPacket(setting);
+
+        GenericSettings response = (GenericSettings)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server on status set.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response;
+    }
+
+    public boolean hasMonitorPrivileges(Connection con) throws XMPPException {
+        MonitorPacket request = new MonitorPacket();
+        request.setType(IQ.Type.GET);
+        request.setTo(workgroupJID);
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
+        connection.sendPacket(request);
+
+        MonitorPacket response = (MonitorPacket)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server on status set.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response.isMonitor();
+
+    }
+
+    public void makeRoomOwner(Connection con, String sessionID) throws XMPPException {
+        MonitorPacket request = new MonitorPacket();
+        request.setType(IQ.Type.SET);
+        request.setTo(workgroupJID);
+        request.setSessionID(sessionID);
+
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
+        connection.sendPacket(request);
+
+        Packet response = collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server on status set.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/InvitationRequest.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/InvitationRequest.java
index 16b324a..33629be 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/InvitationRequest.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/InvitationRequest.java
@@ -1,62 +1,62 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.agent;
-
-/**
- * Request sent by an agent to invite another agent or user.
- *
- * @author Gaston Dombiak
- */
-public class InvitationRequest extends OfferContent {
-
-    private String inviter;
-    private String room;
-    private String reason;
-
-    public InvitationRequest(String inviter, String room, String reason) {
-        this.inviter = inviter;
-        this.room = room;
-        this.reason = reason;
-    }
-
-    public String getInviter() {
-        return inviter;
-    }
-
-    public String getRoom() {
-        return room;
-    }
-
-    public String getReason() {
-        return reason;
-    }
-
-    boolean isUserRequest() {
-        return false;
-    }
-
-    boolean isInvitation() {
-        return true;
-    }
-
-    boolean isTransfer() {
-        return false;
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.agent;
+
+/**
+ * Request sent by an agent to invite another agent or user.
+ *
+ * @author Gaston Dombiak
+ */
+public class InvitationRequest extends OfferContent {
+
+    private String inviter;
+    private String room;
+    private String reason;
+
+    public InvitationRequest(String inviter, String room, String reason) {
+        this.inviter = inviter;
+        this.room = room;
+        this.reason = reason;
+    }
+
+    public String getInviter() {
+        return inviter;
+    }
+
+    public String getRoom() {
+        return room;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+
+    boolean isUserRequest() {
+        return false;
+    }
+
+    boolean isInvitation() {
+        return true;
+    }
+
+    boolean isTransfer() {
+        return false;
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/Offer.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/Offer.java
index ece8c6f..98070c6 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/Offer.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/Offer.java
@@ -1,223 +1,223 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.agent;
-
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Packet;
-
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A class embodying the semantic agent chat offer; specific instances allow the acceptance or
- * rejecting of the offer.<br>
- *
- * @author Matt Tucker
- * @author loki der quaeler
- * @author Derek DeMoro
- */
-public class Offer {
-
-    private Connection connection;
-    private AgentSession session;
-
-    private String sessionID;
-    private String userJID;
-    private String userID;
-    private String workgroupName;
-    private Date expiresDate;
-    private Map<String, List<String>> metaData;
-    private OfferContent content;
-
-    private boolean accepted = false;
-    private boolean rejected = false;
-
-    /**
-     * Creates a new offer.
-     *
-     * @param conn the XMPP connection with which the issuing session was created.
-     * @param agentSession the agent session instance through which this offer was issued.
-     * @param userID  the userID of the user from which the offer originates.
-     * @param userJID the XMPP address of the user from which the offer originates.
-     * @param workgroupName the fully qualified name of the workgroup.
-     * @param expiresDate the date at which this offer expires.
-     * @param sessionID the session id associated with the offer.
-     * @param metaData the metadata associated with the offer.
-     * @param content content of the offer. The content explains the reason for the offer
-     *        (e.g. user request, transfer)
-     */
-    Offer(Connection conn, AgentSession agentSession, String userID,
-            String userJID, String workgroupName, Date expiresDate,
-            String sessionID, Map<String, List<String>> metaData, OfferContent content)
-    {
-        this.connection = conn;
-        this.session = agentSession;
-        this.userID = userID;
-        this.userJID = userJID;
-        this.workgroupName = workgroupName;
-        this.expiresDate = expiresDate;
-        this.sessionID = sessionID;
-        this.metaData = metaData;
-        this.content = content;
-    }
-
-    /**
-     * Accepts the offer.
-     */
-    public void accept() {
-        Packet acceptPacket = new AcceptPacket(this.session.getWorkgroupJID());
-        connection.sendPacket(acceptPacket);
-        // TODO: listen for a reply.
-        accepted = true;
-    }
-
-    /**
-     * Rejects the offer.
-     */
-    public void reject() {
-        RejectPacket rejectPacket = new RejectPacket(this.session.getWorkgroupJID());
-        connection.sendPacket(rejectPacket);
-        // TODO: listen for a reply.
-        rejected = true;
-    }
-
-    /**
-     * Returns the userID that the offer originates from. In most cases, the
-     * userID will simply be the JID of the requesting user. However, users can
-     * also manually specify a userID for their request. In that case, that value will
-     * be returned.
-     *
-     * @return the userID of the user from which the offer originates.
-     */
-    public String getUserID() {
-        return userID;
-    }
-
-    /**
-     * Returns the JID of the user that made the offer request.
-     *
-     * @return the user's JID.
-     */
-    public String getUserJID() {
-        return userJID;
-    }
-
-    /**
-     * The fully qualified name of the workgroup (eg support@example.com).
-     *
-     * @return the name of the workgroup.
-     */
-    public String getWorkgroupName() {
-        return this.workgroupName;
-    }
-
-    /**
-     * The date when the offer will expire. The agent must {@link #accept()}
-     * the offer before the expiration date or the offer will lapse and be
-     * routed to another agent. Alternatively, the agent can {@link #reject()}
-     * the offer at any time if they don't wish to accept it..
-     *
-     * @return the date at which this offer expires.
-     */
-    public Date getExpiresDate() {
-        return this.expiresDate;
-    }
-
-    /**
-     * The session ID associated with the offer.
-     *
-     * @return the session id associated with the offer.
-     */
-    public String getSessionID() {
-        return this.sessionID;
-    }
-
-    /**
-     * The meta-data associated with the offer.
-     *
-     * @return the offer meta-data.
-     */
-    public Map<String, List<String>> getMetaData() {
-        return this.metaData;
-    }
-
-    /**
-     * Returns the content of the offer. The content explains the reason for the offer
-     * (e.g. user request, transfer)
-     *
-     * @return the content of the offer.
-     */
-    public OfferContent getContent() {
-        return content;
-    }
-
-    /**
-     * Returns true if the agent accepted this offer.
-     *
-     * @return true if the agent accepted this offer.
-     */
-    public boolean isAccepted() {
-        return accepted;
-    }
-
-    /**
-     * Return true if the agent rejected this offer.
-     *
-     * @return true if the agent rejected this offer.
-     */
-    public boolean isRejected() {
-        return rejected;
-    }
-
-    /**
-     * Packet for rejecting offers.
-     */
-    private class RejectPacket extends IQ {
-
-        RejectPacket(String workgroup) {
-            this.setTo(workgroup);
-            this.setType(IQ.Type.SET);
-        }
-
-        public String getChildElementXML() {
-            return "<offer-reject id=\"" + Offer.this.getSessionID() +
-                    "\" xmlns=\"http://jabber.org/protocol/workgroup" + "\"/>";
-        }
-    }
-
-    /**
-     * Packet for accepting an offer.
-     */
-    private class AcceptPacket extends IQ {
-
-        AcceptPacket(String workgroup) {
-            this.setTo(workgroup);
-            this.setType(IQ.Type.SET);
-        }
-
-        public String getChildElementXML() {
-            return "<offer-accept id=\"" + Offer.this.getSessionID() +
-                    "\" xmlns=\"http://jabber.org/protocol/workgroup" + "\"/>";
-        }
-    }
-
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.agent;
+
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Packet;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A class embodying the semantic agent chat offer; specific instances allow the acceptance or
+ * rejecting of the offer.<br>
+ *
+ * @author Matt Tucker
+ * @author loki der quaeler
+ * @author Derek DeMoro
+ */
+public class Offer {
+
+    private Connection connection;
+    private AgentSession session;
+
+    private String sessionID;
+    private String userJID;
+    private String userID;
+    private String workgroupName;
+    private Date expiresDate;
+    private Map<String, List<String>> metaData;
+    private OfferContent content;
+
+    private boolean accepted = false;
+    private boolean rejected = false;
+
+    /**
+     * Creates a new offer.
+     *
+     * @param conn the XMPP connection with which the issuing session was created.
+     * @param agentSession the agent session instance through which this offer was issued.
+     * @param userID  the userID of the user from which the offer originates.
+     * @param userJID the XMPP address of the user from which the offer originates.
+     * @param workgroupName the fully qualified name of the workgroup.
+     * @param expiresDate the date at which this offer expires.
+     * @param sessionID the session id associated with the offer.
+     * @param metaData the metadata associated with the offer.
+     * @param content content of the offer. The content explains the reason for the offer
+     *        (e.g. user request, transfer)
+     */
+    Offer(Connection conn, AgentSession agentSession, String userID,
+            String userJID, String workgroupName, Date expiresDate,
+            String sessionID, Map<String, List<String>> metaData, OfferContent content)
+    {
+        this.connection = conn;
+        this.session = agentSession;
+        this.userID = userID;
+        this.userJID = userJID;
+        this.workgroupName = workgroupName;
+        this.expiresDate = expiresDate;
+        this.sessionID = sessionID;
+        this.metaData = metaData;
+        this.content = content;
+    }
+
+    /**
+     * Accepts the offer.
+     */
+    public void accept() {
+        Packet acceptPacket = new AcceptPacket(this.session.getWorkgroupJID());
+        connection.sendPacket(acceptPacket);
+        // TODO: listen for a reply.
+        accepted = true;
+    }
+
+    /**
+     * Rejects the offer.
+     */
+    public void reject() {
+        RejectPacket rejectPacket = new RejectPacket(this.session.getWorkgroupJID());
+        connection.sendPacket(rejectPacket);
+        // TODO: listen for a reply.
+        rejected = true;
+    }
+
+    /**
+     * Returns the userID that the offer originates from. In most cases, the
+     * userID will simply be the JID of the requesting user. However, users can
+     * also manually specify a userID for their request. In that case, that value will
+     * be returned.
+     *
+     * @return the userID of the user from which the offer originates.
+     */
+    public String getUserID() {
+        return userID;
+    }
+
+    /**
+     * Returns the JID of the user that made the offer request.
+     *
+     * @return the user's JID.
+     */
+    public String getUserJID() {
+        return userJID;
+    }
+
+    /**
+     * The fully qualified name of the workgroup (eg support@example.com).
+     *
+     * @return the name of the workgroup.
+     */
+    public String getWorkgroupName() {
+        return this.workgroupName;
+    }
+
+    /**
+     * The date when the offer will expire. The agent must {@link #accept()}
+     * the offer before the expiration date or the offer will lapse and be
+     * routed to another agent. Alternatively, the agent can {@link #reject()}
+     * the offer at any time if they don't wish to accept it..
+     *
+     * @return the date at which this offer expires.
+     */
+    public Date getExpiresDate() {
+        return this.expiresDate;
+    }
+
+    /**
+     * The session ID associated with the offer.
+     *
+     * @return the session id associated with the offer.
+     */
+    public String getSessionID() {
+        return this.sessionID;
+    }
+
+    /**
+     * The meta-data associated with the offer.
+     *
+     * @return the offer meta-data.
+     */
+    public Map<String, List<String>> getMetaData() {
+        return this.metaData;
+    }
+
+    /**
+     * Returns the content of the offer. The content explains the reason for the offer
+     * (e.g. user request, transfer)
+     *
+     * @return the content of the offer.
+     */
+    public OfferContent getContent() {
+        return content;
+    }
+
+    /**
+     * Returns true if the agent accepted this offer.
+     *
+     * @return true if the agent accepted this offer.
+     */
+    public boolean isAccepted() {
+        return accepted;
+    }
+
+    /**
+     * Return true if the agent rejected this offer.
+     *
+     * @return true if the agent rejected this offer.
+     */
+    public boolean isRejected() {
+        return rejected;
+    }
+
+    /**
+     * Packet for rejecting offers.
+     */
+    private class RejectPacket extends IQ {
+
+        RejectPacket(String workgroup) {
+            this.setTo(workgroup);
+            this.setType(IQ.Type.SET);
+        }
+
+        public String getChildElementXML() {
+            return "<offer-reject id=\"" + Offer.this.getSessionID() +
+                    "\" xmlns=\"http://jabber.org/protocol/workgroup" + "\"/>";
+        }
+    }
+
+    /**
+     * Packet for accepting an offer.
+     */
+    private class AcceptPacket extends IQ {
+
+        AcceptPacket(String workgroup) {
+            this.setTo(workgroup);
+            this.setType(IQ.Type.SET);
+        }
+
+        public String getChildElementXML() {
+            return "<offer-accept id=\"" + Offer.this.getSessionID() +
+                    "\" xmlns=\"http://jabber.org/protocol/workgroup" + "\"/>";
+        }
+    }
+
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/OfferConfirmation.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/OfferConfirmation.java
index f55d588..ea1eba7 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/OfferConfirmation.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/OfferConfirmation.java
@@ -1,114 +1,114 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.agent;
-
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-
-public class OfferConfirmation extends IQ {
-    private String userJID;
-    private long sessionID;
-
-    public String getUserJID() {
-        return userJID;
-    }
-
-    public void setUserJID(String userJID) {
-        this.userJID = userJID;
-    }
-
-    public long getSessionID() {
-        return sessionID;
-    }
-
-    public void setSessionID(long sessionID) {
-        this.sessionID = sessionID;
-    }
-
-
-    public void notifyService(Connection con, String workgroup, String createdRoomName) {
-        NotifyServicePacket packet = new NotifyServicePacket(workgroup, createdRoomName);
-        con.sendPacket(packet);
-    }
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<offer-confirmation xmlns=\"http://jabber.org/protocol/workgroup\">");
-        buf.append("</offer-confirmation>");
-        return buf.toString();
-    }
-
-    public static class Provider implements IQProvider {
-
-        public IQ parseIQ(XmlPullParser parser) throws Exception {
-            final OfferConfirmation confirmation = new OfferConfirmation();
-
-            boolean done = false;
-            while (!done) {
-                parser.next();
-                String elementName = parser.getName();
-                if (parser.getEventType() == XmlPullParser.START_TAG && "user-jid".equals(elementName)) {
-                    try {
-                        confirmation.setUserJID(parser.nextText());
-                    }
-                    catch (NumberFormatException nfe) {
-                    }
-                }
-                else if (parser.getEventType() == XmlPullParser.START_TAG && "session-id".equals(elementName)) {
-                    try {
-                        confirmation.setSessionID(Long.valueOf(parser.nextText()));
-                    }
-                    catch (NumberFormatException nfe) {
-                    }
-                }
-                else if (parser.getEventType() == XmlPullParser.END_TAG && "offer-confirmation".equals(elementName)) {
-                    done = true;
-                }
-            }
-
-
-            return confirmation;
-        }
-    }
-
-
-    /**
-     * Packet for notifying server of RoomName
-     */
-    private class NotifyServicePacket extends IQ {
-        String roomName;
-
-        NotifyServicePacket(String workgroup, String roomName) {
-            this.setTo(workgroup);
-            this.setType(IQ.Type.RESULT);
-
-            this.roomName = roomName;
-        }
-
-        public String getChildElementXML() {
-            return "<offer-confirmation  roomname=\"" + roomName + "\" xmlns=\"http://jabber.org/protocol/workgroup" + "\"/>";
-        }
-    }
-
-
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.agent;
+
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+
+public class OfferConfirmation extends IQ {
+    private String userJID;
+    private long sessionID;
+
+    public String getUserJID() {
+        return userJID;
+    }
+
+    public void setUserJID(String userJID) {
+        this.userJID = userJID;
+    }
+
+    public long getSessionID() {
+        return sessionID;
+    }
+
+    public void setSessionID(long sessionID) {
+        this.sessionID = sessionID;
+    }
+
+
+    public void notifyService(Connection con, String workgroup, String createdRoomName) {
+        NotifyServicePacket packet = new NotifyServicePacket(workgroup, createdRoomName);
+        con.sendPacket(packet);
+    }
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("<offer-confirmation xmlns=\"http://jabber.org/protocol/workgroup\">");
+        buf.append("</offer-confirmation>");
+        return buf.toString();
+    }
+
+    public static class Provider implements IQProvider {
+
+        public IQ parseIQ(XmlPullParser parser) throws Exception {
+            final OfferConfirmation confirmation = new OfferConfirmation();
+
+            boolean done = false;
+            while (!done) {
+                parser.next();
+                String elementName = parser.getName();
+                if (parser.getEventType() == XmlPullParser.START_TAG && "user-jid".equals(elementName)) {
+                    try {
+                        confirmation.setUserJID(parser.nextText());
+                    }
+                    catch (NumberFormatException nfe) {
+                    }
+                }
+                else if (parser.getEventType() == XmlPullParser.START_TAG && "session-id".equals(elementName)) {
+                    try {
+                        confirmation.setSessionID(Long.valueOf(parser.nextText()));
+                    }
+                    catch (NumberFormatException nfe) {
+                    }
+                }
+                else if (parser.getEventType() == XmlPullParser.END_TAG && "offer-confirmation".equals(elementName)) {
+                    done = true;
+                }
+            }
+
+
+            return confirmation;
+        }
+    }
+
+
+    /**
+     * Packet for notifying server of RoomName
+     */
+    private class NotifyServicePacket extends IQ {
+        String roomName;
+
+        NotifyServicePacket(String workgroup, String roomName) {
+            this.setTo(workgroup);
+            this.setType(IQ.Type.RESULT);
+
+            this.roomName = roomName;
+        }
+
+        public String getChildElementXML() {
+            return "<offer-confirmation  roomname=\"" + roomName + "\" xmlns=\"http://jabber.org/protocol/workgroup" + "\"/>";
+        }
+    }
+
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/OfferConfirmationListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/OfferConfirmationListener.java
index fb10550..ec079e4 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/OfferConfirmationListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/OfferConfirmationListener.java
@@ -1,32 +1,32 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.workgroup.agent;
-
-public interface OfferConfirmationListener {
-
-
-    /**
-     * The implementing class instance will be notified via this when the AgentSession has confirmed
-     * the acceptance of the <code>Offer</code>. The instance will then have the ability to create the room and
-     * send the service the room name created for tracking.
-     *
-     * @param confirmedOffer the ConfirmedOffer
-     */
-    void offerConfirmed(OfferConfirmation confirmedOffer);
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.workgroup.agent;
+
+public interface OfferConfirmationListener {
+
+
+    /**
+     * The implementing class instance will be notified via this when the AgentSession has confirmed
+     * the acceptance of the <code>Offer</code>. The instance will then have the ability to create the room and
+     * send the service the room name created for tracking.
+     *
+     * @param confirmedOffer the ConfirmedOffer
+     */
+    void offerConfirmed(OfferConfirmation confirmedOffer);
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/OfferContent.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/OfferContent.java
index a11ddc3..f6d60ae 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/OfferContent.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/OfferContent.java
@@ -1,55 +1,55 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.agent;
-
-/**
- * Type of content being included in the offer. The content actually explains the reason
- * the agent is getting an offer.
- *
- * @author Gaston Dombiak
- */
-public abstract class OfferContent {
-
-    /**
-     * Returns true if the content of the offer is related to a user request. This is the
-     * most common type of offers an agent should receive.
-     *
-     * @return true if the content of the offer is related to a user request.
-     */
-    abstract boolean isUserRequest();
-
-    /**
-     * Returns true if the content of the offer is related to a room invitation made by another
-     * agent. This type of offer include the room to join, metadata sent by the user while joining
-     * the queue and the reason why the agent is being invited.
-     *
-     * @return true if the content of the offer is related to a room invitation made by another agent.
-     */
-    abstract boolean isInvitation();
-
-    /**
-     * Returns true if the content of the offer is related to a service transfer made by another
-     * agent. This type of offers include the room to join, metadata sent by the user while joining the
-     * queue and the reason why the agent is receiving the transfer offer.
-     *
-     * @return true if the content of the offer is related to a service transfer made by another agent.
-     */
-    abstract boolean isTransfer();
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.agent;
+
+/**
+ * Type of content being included in the offer. The content actually explains the reason
+ * the agent is getting an offer.
+ *
+ * @author Gaston Dombiak
+ */
+public abstract class OfferContent {
+
+    /**
+     * Returns true if the content of the offer is related to a user request. This is the
+     * most common type of offers an agent should receive.
+     *
+     * @return true if the content of the offer is related to a user request.
+     */
+    abstract boolean isUserRequest();
+
+    /**
+     * Returns true if the content of the offer is related to a room invitation made by another
+     * agent. This type of offer include the room to join, metadata sent by the user while joining
+     * the queue and the reason why the agent is being invited.
+     *
+     * @return true if the content of the offer is related to a room invitation made by another agent.
+     */
+    abstract boolean isInvitation();
+
+    /**
+     * Returns true if the content of the offer is related to a service transfer made by another
+     * agent. This type of offers include the room to join, metadata sent by the user while joining the
+     * queue and the reason why the agent is receiving the transfer offer.
+     *
+     * @return true if the content of the offer is related to a service transfer made by another agent.
+     */
+    abstract boolean isTransfer();
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/OfferListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/OfferListener.java
index 5efde99..72e50e3 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/OfferListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/OfferListener.java
@@ -1,49 +1,49 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.agent;
-
-/**
- * An interface which all classes interested in hearing about chat offers associated to a particular
- *  AgentSession instance should implement.<br>
- *
- * @author Matt Tucker
- * @author loki der quaeler
- * @see org.jivesoftware.smackx.workgroup.agent.AgentSession
- */
-public interface OfferListener {
-
-    /**
-     * The implementing class instance will be notified via this when the AgentSession has received
-     *  an offer for a chat. The instance will then have the ability to accept, reject, or ignore
-     *  the request (resulting in a revocation-by-timeout).
-     *
-     * @param request the Offer instance embodying the details of the offer
-     */
-    public void offerReceived (Offer request);
-
-    /**
-     * The implementing class instance will be notified via this when the AgentSessino has received
-     *  a revocation of a previously extended offer.
-     *
-     * @param revokedOffer the RevokedOffer instance embodying the details of the revoked offer
-     */
-    public void offerRevoked (RevokedOffer revokedOffer);
-
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.agent;
+
+/**
+ * An interface which all classes interested in hearing about chat offers associated to a particular
+ *  AgentSession instance should implement.<br>
+ *
+ * @author Matt Tucker
+ * @author loki der quaeler
+ * @see org.jivesoftware.smackx.workgroup.agent.AgentSession
+ */
+public interface OfferListener {
+
+    /**
+     * The implementing class instance will be notified via this when the AgentSession has received
+     *  an offer for a chat. The instance will then have the ability to accept, reject, or ignore
+     *  the request (resulting in a revocation-by-timeout).
+     *
+     * @param request the Offer instance embodying the details of the offer
+     */
+    public void offerReceived (Offer request);
+
+    /**
+     * The implementing class instance will be notified via this when the AgentSessino has received
+     *  a revocation of a previously extended offer.
+     *
+     * @param revokedOffer the RevokedOffer instance embodying the details of the revoked offer
+     */
+    public void offerRevoked (RevokedOffer revokedOffer);
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/QueueUsersListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/QueueUsersListener.java
index 9fcff9a..e7510d6 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/QueueUsersListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/QueueUsersListener.java
@@ -1,60 +1,60 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.agent;
-
-import java.util.Date;
-import java.util.Set;
-
-import org.jivesoftware.smackx.workgroup.QueueUser;
-
-public interface QueueUsersListener {
-
-    /**
-     * The status of the queue was updated.
-     *
-     * @param queue the workgroup queue.
-     * @param status the status of queue.
-     */
-    public void statusUpdated(WorkgroupQueue queue, WorkgroupQueue.Status status);
-
-    /**
-     * The average wait time of the queue was updated.
-     *
-     * @param queue the workgroup queue.
-     * @param averageWaitTime the average wait time of the queue.
-     */
-    public void averageWaitTimeUpdated(WorkgroupQueue queue, int averageWaitTime);
-
-    /**
-     * The date of oldest entry waiting in the queue was updated.
-     *
-     * @param queue the workgroup queue.
-     * @param oldestEntry the date of the oldest entry waiting in the queue.
-     */
-    public void oldestEntryUpdated(WorkgroupQueue queue, Date oldestEntry);
-
-    /**
-     * The list of users waiting in the queue was updated.
-     *
-     * @param queue the workgroup queue.
-     * @param users the list of users waiting in the queue.
-     */
-    public void usersUpdated(WorkgroupQueue queue, Set<QueueUser> users);
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.agent;
+
+import java.util.Date;
+import java.util.Set;
+
+import org.jivesoftware.smackx.workgroup.QueueUser;
+
+public interface QueueUsersListener {
+
+    /**
+     * The status of the queue was updated.
+     *
+     * @param queue the workgroup queue.
+     * @param status the status of queue.
+     */
+    public void statusUpdated(WorkgroupQueue queue, WorkgroupQueue.Status status);
+
+    /**
+     * The average wait time of the queue was updated.
+     *
+     * @param queue the workgroup queue.
+     * @param averageWaitTime the average wait time of the queue.
+     */
+    public void averageWaitTimeUpdated(WorkgroupQueue queue, int averageWaitTime);
+
+    /**
+     * The date of oldest entry waiting in the queue was updated.
+     *
+     * @param queue the workgroup queue.
+     * @param oldestEntry the date of the oldest entry waiting in the queue.
+     */
+    public void oldestEntryUpdated(WorkgroupQueue queue, Date oldestEntry);
+
+    /**
+     * The list of users waiting in the queue was updated.
+     *
+     * @param queue the workgroup queue.
+     * @param users the list of users waiting in the queue.
+     */
+    public void usersUpdated(WorkgroupQueue queue, Set<QueueUser> users);
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/RevokedOffer.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/RevokedOffer.java
index dab4d91..88250b2 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/RevokedOffer.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/RevokedOffer.java
@@ -1,98 +1,98 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.agent;
-
-import java.util.Date;
-
-/**
- * An immutable simple class to embody the information concerning a revoked offer, this is namely
- *  the reason, the workgroup, the userJID, and the timestamp which the message was received.<br>
- *
- * @author loki der quaeler
- */
-public class RevokedOffer {
-
-    private String userJID;
-    private String userID;
-    private String workgroupName;
-    private String sessionID;
-    private String reason;
-    private Date timestamp;
-
-    /**
-     *
-     * @param userJID the JID of the user for which this revocation was issued.
-     * @param userID the user ID of the user for which this revocation was issued.
-     * @param workgroupName the fully qualified name of the workgroup
-     * @param sessionID the session id attributed to this chain of packets
-     * @param reason the server issued message as to why this revocation was issued.
-     * @param timestamp the timestamp at which the revocation was issued
-     */
-    RevokedOffer(String userJID, String userID, String workgroupName, String sessionID,
-            String reason, Date timestamp) {
-        super();
-
-        this.userJID = userJID;
-        this.userID = userID;
-        this.workgroupName = workgroupName;
-        this.sessionID = sessionID;
-        this.reason = reason;
-        this.timestamp = timestamp;
-    }
-
-    public String getUserJID() {
-        return userJID;
-    }
-
-    /**
-     * @return the jid of the user for which this revocation was issued
-     */
-    public String getUserID() {
-        return this.userID;
-    }
-
-    /**
-     * @return the fully qualified name of the workgroup
-     */
-    public String getWorkgroupName() {
-        return this.workgroupName;
-    }
-
-    /**
-     * @return the session id which will associate all packets for the pending chat
-     */
-    public String getSessionID() {
-        return this.sessionID;
-    }
-
-    /**
-     * @return the server issued message as to why this revocation was issued
-     */
-    public String getReason() {
-        return this.reason;
-    }
-
-    /**
-     * @return the timestamp at which the revocation was issued
-     */
-    public Date getTimestamp() {
-        return this.timestamp;
-    }
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.agent;
+
+import java.util.Date;
+
+/**
+ * An immutable simple class to embody the information concerning a revoked offer, this is namely
+ *  the reason, the workgroup, the userJID, and the timestamp which the message was received.<br>
+ *
+ * @author loki der quaeler
+ */
+public class RevokedOffer {
+
+    private String userJID;
+    private String userID;
+    private String workgroupName;
+    private String sessionID;
+    private String reason;
+    private Date timestamp;
+
+    /**
+     *
+     * @param userJID the JID of the user for which this revocation was issued.
+     * @param userID the user ID of the user for which this revocation was issued.
+     * @param workgroupName the fully qualified name of the workgroup
+     * @param sessionID the session id attributed to this chain of packets
+     * @param reason the server issued message as to why this revocation was issued.
+     * @param timestamp the timestamp at which the revocation was issued
+     */
+    RevokedOffer(String userJID, String userID, String workgroupName, String sessionID,
+            String reason, Date timestamp) {
+        super();
+
+        this.userJID = userJID;
+        this.userID = userID;
+        this.workgroupName = workgroupName;
+        this.sessionID = sessionID;
+        this.reason = reason;
+        this.timestamp = timestamp;
+    }
+
+    public String getUserJID() {
+        return userJID;
+    }
+
+    /**
+     * @return the jid of the user for which this revocation was issued
+     */
+    public String getUserID() {
+        return this.userID;
+    }
+
+    /**
+     * @return the fully qualified name of the workgroup
+     */
+    public String getWorkgroupName() {
+        return this.workgroupName;
+    }
+
+    /**
+     * @return the session id which will associate all packets for the pending chat
+     */
+    public String getSessionID() {
+        return this.sessionID;
+    }
+
+    /**
+     * @return the server issued message as to why this revocation was issued
+     */
+    public String getReason() {
+        return this.reason;
+    }
+
+    /**
+     * @return the timestamp at which the revocation was issued
+     */
+    public Date getTimestamp() {
+        return this.timestamp;
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/TranscriptManager.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/TranscriptManager.java
index 8a3801f..2a17b47 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/TranscriptManager.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/TranscriptManager.java
@@ -1,100 +1,100 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.agent;
-
-import org.jivesoftware.smackx.workgroup.packet.Transcript;
-import org.jivesoftware.smackx.workgroup.packet.Transcripts;
-import org.jivesoftware.smack.PacketCollector;
-import org.jivesoftware.smack.SmackConfiguration;
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.filter.PacketIDFilter;
-
-/**
- * A TranscriptManager helps to retrieve the full conversation transcript of a given session
- * {@link #getTranscript(String, String)} or to retrieve a list with the summary of all the
- * conversations that a user had {@link #getTranscripts(String, String)}.
- *
- * @author Gaston Dombiak
- */
-public class TranscriptManager {
-    private Connection connection;
-
-    public TranscriptManager(Connection connection) {
-        this.connection = connection;
-    }
-
-    /**
-     * Returns the full conversation transcript of a given session.
-     *
-     * @param sessionID the id of the session to get the full transcript.
-     * @param workgroupJID the JID of the workgroup that will process the request.
-     * @return the full conversation transcript of a given session.
-     * @throws XMPPException if an error occurs while getting the information.
-     */
-    public Transcript getTranscript(String workgroupJID, String sessionID) throws XMPPException {
-        Transcript request = new Transcript(sessionID);
-        request.setTo(workgroupJID);
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
-        // Send the request
-        connection.sendPacket(request);
-
-        Transcript response = (Transcript) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server on status set.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response;
-    }
-
-    /**
-     * Returns the transcripts of a given user. The answer will contain the complete history of
-     * conversations that a user had.
-     *
-     * @param userID the id of the user to get his conversations.
-     * @param workgroupJID the JID of the workgroup that will process the request.
-     * @return the transcripts of a given user.
-     * @throws XMPPException if an error occurs while getting the information.
-     */
-    public Transcripts getTranscripts(String workgroupJID, String userID) throws XMPPException {
-        Transcripts request = new Transcripts(userID);
-        request.setTo(workgroupJID);
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
-        // Send the request
-        connection.sendPacket(request);
-
-        Transcripts response = (Transcripts) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server on status set.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response;
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.agent;
+
+import org.jivesoftware.smackx.workgroup.packet.Transcript;
+import org.jivesoftware.smackx.workgroup.packet.Transcripts;
+import org.jivesoftware.smack.PacketCollector;
+import org.jivesoftware.smack.SmackConfiguration;
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.filter.PacketIDFilter;
+
+/**
+ * A TranscriptManager helps to retrieve the full conversation transcript of a given session
+ * {@link #getTranscript(String, String)} or to retrieve a list with the summary of all the
+ * conversations that a user had {@link #getTranscripts(String, String)}.
+ *
+ * @author Gaston Dombiak
+ */
+public class TranscriptManager {
+    private Connection connection;
+
+    public TranscriptManager(Connection connection) {
+        this.connection = connection;
+    }
+
+    /**
+     * Returns the full conversation transcript of a given session.
+     *
+     * @param sessionID the id of the session to get the full transcript.
+     * @param workgroupJID the JID of the workgroup that will process the request.
+     * @return the full conversation transcript of a given session.
+     * @throws XMPPException if an error occurs while getting the information.
+     */
+    public Transcript getTranscript(String workgroupJID, String sessionID) throws XMPPException {
+        Transcript request = new Transcript(sessionID);
+        request.setTo(workgroupJID);
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
+        // Send the request
+        connection.sendPacket(request);
+
+        Transcript response = (Transcript) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server on status set.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response;
+    }
+
+    /**
+     * Returns the transcripts of a given user. The answer will contain the complete history of
+     * conversations that a user had.
+     *
+     * @param userID the id of the user to get his conversations.
+     * @param workgroupJID the JID of the workgroup that will process the request.
+     * @return the transcripts of a given user.
+     * @throws XMPPException if an error occurs while getting the information.
+     */
+    public Transcripts getTranscripts(String workgroupJID, String userID) throws XMPPException {
+        Transcripts request = new Transcripts(userID);
+        request.setTo(workgroupJID);
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
+        // Send the request
+        connection.sendPacket(request);
+
+        Transcripts response = (Transcripts) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server on status set.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response;
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/TranscriptSearchManager.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/TranscriptSearchManager.java
index 8260cd6..498cc8a 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/TranscriptSearchManager.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/TranscriptSearchManager.java
@@ -1,111 +1,111 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.agent;
-
-import org.jivesoftware.smackx.workgroup.packet.TranscriptSearch;
-import org.jivesoftware.smack.PacketCollector;
-import org.jivesoftware.smack.SmackConfiguration;
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.filter.PacketIDFilter;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smackx.Form;
-import org.jivesoftware.smackx.ReportedData;
-
-/**
- * A TranscriptSearchManager helps to retrieve the form to use for searching transcripts
- * {@link #getSearchForm(String)} or to submit a search form and return the results of
- * the search {@link #submitSearch(String, Form)}.
- *
- * @author Gaston Dombiak
- */
-public class TranscriptSearchManager {
-    private Connection connection;
-
-    public TranscriptSearchManager(Connection connection) {
-        this.connection = connection;
-    }
-
-    /**
-     * Returns the Form to use for searching transcripts. It is unlikely that the server
-     * will change the form (without a restart) so it is safe to keep the returned form
-     * for future submissions.
-     *
-     * @param serviceJID the address of the workgroup service.
-     * @return the Form to use for searching transcripts.
-     * @throws XMPPException if an error occurs while sending the request to the server.
-     */
-    public Form getSearchForm(String serviceJID) throws XMPPException {
-        TranscriptSearch search = new TranscriptSearch();
-        search.setType(IQ.Type.GET);
-        search.setTo(serviceJID);
-
-        PacketCollector collector = connection.createPacketCollector(
-                new PacketIDFilter(search.getPacketID()));
-        connection.sendPacket(search);
-
-        TranscriptSearch response = (TranscriptSearch) collector.nextResult(
-                SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server on status set.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return Form.getFormFrom(response);
-    }
-
-    /**
-     * Submits the completed form and returns the result of the transcript search. The result
-     * will include all the data returned from the server so be careful with the amount of
-     * data that the search may return.
-     *
-     * @param serviceJID    the address of the workgroup service.
-     * @param completedForm the filled out search form.
-     * @return the result of the transcript search.
-     * @throws XMPPException if an error occurs while submiting the search to the server.
-     */
-    public ReportedData submitSearch(String serviceJID, Form completedForm) throws XMPPException {
-        TranscriptSearch search = new TranscriptSearch();
-        search.setType(IQ.Type.GET);
-        search.setTo(serviceJID);
-        search.addExtension(completedForm.getDataFormToSend());
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(search.getPacketID()));
-        connection.sendPacket(search);
-
-        TranscriptSearch response = (TranscriptSearch) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server on status set.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return ReportedData.getReportedDataFrom(response);
-    }
-}
-
-
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.agent;
+
+import org.jivesoftware.smackx.workgroup.packet.TranscriptSearch;
+import org.jivesoftware.smack.PacketCollector;
+import org.jivesoftware.smack.SmackConfiguration;
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.filter.PacketIDFilter;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smackx.Form;
+import org.jivesoftware.smackx.ReportedData;
+
+/**
+ * A TranscriptSearchManager helps to retrieve the form to use for searching transcripts
+ * {@link #getSearchForm(String)} or to submit a search form and return the results of
+ * the search {@link #submitSearch(String, Form)}.
+ *
+ * @author Gaston Dombiak
+ */
+public class TranscriptSearchManager {
+    private Connection connection;
+
+    public TranscriptSearchManager(Connection connection) {
+        this.connection = connection;
+    }
+
+    /**
+     * Returns the Form to use for searching transcripts. It is unlikely that the server
+     * will change the form (without a restart) so it is safe to keep the returned form
+     * for future submissions.
+     *
+     * @param serviceJID the address of the workgroup service.
+     * @return the Form to use for searching transcripts.
+     * @throws XMPPException if an error occurs while sending the request to the server.
+     */
+    public Form getSearchForm(String serviceJID) throws XMPPException {
+        TranscriptSearch search = new TranscriptSearch();
+        search.setType(IQ.Type.GET);
+        search.setTo(serviceJID);
+
+        PacketCollector collector = connection.createPacketCollector(
+                new PacketIDFilter(search.getPacketID()));
+        connection.sendPacket(search);
+
+        TranscriptSearch response = (TranscriptSearch) collector.nextResult(
+                SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server on status set.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return Form.getFormFrom(response);
+    }
+
+    /**
+     * Submits the completed form and returns the result of the transcript search. The result
+     * will include all the data returned from the server so be careful with the amount of
+     * data that the search may return.
+     *
+     * @param serviceJID    the address of the workgroup service.
+     * @param completedForm the filled out search form.
+     * @return the result of the transcript search.
+     * @throws XMPPException if an error occurs while submiting the search to the server.
+     */
+    public ReportedData submitSearch(String serviceJID, Form completedForm) throws XMPPException {
+        TranscriptSearch search = new TranscriptSearch();
+        search.setType(IQ.Type.GET);
+        search.setTo(serviceJID);
+        search.addExtension(completedForm.getDataFormToSend());
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(search.getPacketID()));
+        connection.sendPacket(search);
+
+        TranscriptSearch response = (TranscriptSearch) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server on status set.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return ReportedData.getReportedDataFrom(response);
+    }
+}
+
+
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/TransferRequest.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/TransferRequest.java
index a3abbaa..0d0f87e 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/TransferRequest.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/TransferRequest.java
@@ -1,62 +1,62 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.agent;
-
-/**
- * Request sent by an agent to transfer a support session to another agent or user.
- *
- * @author Gaston Dombiak
- */
-public class TransferRequest extends OfferContent {
-
-    private String inviter;
-    private String room;
-    private String reason;
-
-    public TransferRequest(String inviter, String room, String reason) {
-        this.inviter = inviter;
-        this.room = room;
-        this.reason = reason;
-    }
-
-    public String getInviter() {
-        return inviter;
-    }
-
-    public String getRoom() {
-        return room;
-    }
-
-    public String getReason() {
-        return reason;
-    }
-
-    boolean isUserRequest() {
-        return false;
-    }
-
-    boolean isInvitation() {
-        return false;
-    }
-
-    boolean isTransfer() {
-        return true;
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.agent;
+
+/**
+ * Request sent by an agent to transfer a support session to another agent or user.
+ *
+ * @author Gaston Dombiak
+ */
+public class TransferRequest extends OfferContent {
+
+    private String inviter;
+    private String room;
+    private String reason;
+
+    public TransferRequest(String inviter, String room, String reason) {
+        this.inviter = inviter;
+        this.room = room;
+        this.reason = reason;
+    }
+
+    public String getInviter() {
+        return inviter;
+    }
+
+    public String getRoom() {
+        return room;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+
+    boolean isUserRequest() {
+        return false;
+    }
+
+    boolean isInvitation() {
+        return false;
+    }
+
+    boolean isTransfer() {
+        return true;
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/UserRequest.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/UserRequest.java
index ccaaaf3..f24208d 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/UserRequest.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/UserRequest.java
@@ -1,47 +1,47 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.agent;
-
-/**
- * Requests made by users to get support by some agent.
- *
- * @author Gaston Dombiak
- */
-public class UserRequest extends OfferContent {
-    // TODO Do we want to use a singleton? Should we store the userID here?
-    private static UserRequest instance = new UserRequest();
-
-    public static OfferContent getInstance() {
-        return instance;
-    }
-
-    boolean isUserRequest() {
-        return true;
-    }
-
-    boolean isInvitation() {
-        return false;
-    }
-
-    boolean isTransfer() {
-        return false;
-    }
-
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.agent;
+
+/**
+ * Requests made by users to get support by some agent.
+ *
+ * @author Gaston Dombiak
+ */
+public class UserRequest extends OfferContent {
+    // TODO Do we want to use a singleton? Should we store the userID here?
+    private static UserRequest instance = new UserRequest();
+
+    public static OfferContent getInstance() {
+        return instance;
+    }
+
+    boolean isUserRequest() {
+        return true;
+    }
+
+    boolean isInvitation() {
+        return false;
+    }
+
+    boolean isTransfer() {
+        return false;
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/WorkgroupQueue.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/WorkgroupQueue.java
index b43c826..b0d07a6 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/WorkgroupQueue.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/agent/WorkgroupQueue.java
@@ -1,224 +1,224 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.agent;
-
-import java.util.*;
-
-import org.jivesoftware.smackx.workgroup.QueueUser;
-
-/**
- * A queue in a workgroup, which is a pool of agents that are routed  a specific type of
- * chat request.
- */
-public class WorkgroupQueue {
-
-    private String name;
-    private Status status = Status.CLOSED;
-
-    private int averageWaitTime = -1;
-    private Date oldestEntry = null;
-    private Set<QueueUser> users = Collections.emptySet();
-
-    private int maxChats = 0;
-    private int currentChats = 0;
-
-    /**
-     * Creates a new workgroup queue instance.
-     *
-     * @param name the name of the queue.
-     */
-    WorkgroupQueue(String name) {
-        this.name = name;
-    }
-
-    /**
-     * Returns the name of the queue.
-     *
-     * @return the name of the queue.
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Returns the status of the queue.
-     *
-     * @return the status of the queue.
-     */
-    public Status getStatus() {
-        return status;
-    }
-
-    void setStatus(Status status) {
-        this.status = status;
-    }
-
-    /**
-     * Returns the number of users waiting in the queue waiting to be routed to
-     * an agent.
-     *
-     * @return the number of users waiting in the queue.
-     */
-    public int getUserCount() {
-        if (users == null) {
-            return 0;
-        }
-        return users.size();
-    }
-
-    /**
-     * Returns an Iterator for the users in the queue waiting to be routed to
-     * an agent (QueueUser instances).
-     *
-     * @return an Iterator for the users waiting in the queue.
-     */
-    public Iterator<QueueUser> getUsers() {
-        if (users == null) {
-            return new HashSet<QueueUser>().iterator();
-        }
-        return Collections.unmodifiableSet(users).iterator();
-    }
-
-    void setUsers(Set<QueueUser> users) {
-        this.users = users;
-    }
-
-    /**
-     * Returns the average amount of time users wait in the queue before being
-     * routed to an agent. If average wait time info isn't available, -1 will
-     * be returned.
-     *
-     * @return the average wait time
-     */
-    public int getAverageWaitTime() {
-        return averageWaitTime;
-    }
-
-    void setAverageWaitTime(int averageTime) {
-        this.averageWaitTime = averageTime;
-    }
-
-    /**
-     * Returns the date of the oldest request waiting in the queue. If there
-     * are no requests waiting to be routed, this method will return <tt>null</tt>.
-     *
-     * @return the date of the oldest request in the queue.
-     */
-    public Date getOldestEntry() {
-        return oldestEntry;
-    }
-
-    void setOldestEntry(Date oldestEntry) {
-        this.oldestEntry = oldestEntry;
-    }
-
-    /**
-     * Returns the maximum number of simultaneous chats the queue can handle.
-     *
-     * @return the max number of chats the queue can handle.
-     */
-    public int getMaxChats() {
-        return maxChats;
-    }
-
-    void setMaxChats(int maxChats) {
-        this.maxChats = maxChats;
-    }
-
-    /**
-     * Returns the current number of active chat sessions in the queue.
-     *
-     * @return the current number of active chat sessions in the queue.
-     */
-    public int getCurrentChats() {
-        return currentChats;
-    }
-
-    void setCurrentChats(int currentChats) {
-        this.currentChats = currentChats;
-    }
-
-    /**
-     * A class to represent the status of the workgroup. The possible values are:
-     *
-     * <ul>
-     *      <li>WorkgroupQueue.Status.OPEN -- the queue is active and accepting new chat requests.
-     *      <li>WorkgroupQueue.Status.ACTIVE -- the queue is active but NOT accepting new chat
-     *          requests.
-     *      <li>WorkgroupQueue.Status.CLOSED -- the queue is NOT active and NOT accepting new
-     *          chat requests.
-     * </ul>
-     */
-    public static class Status {
-
-        /**
-         * The queue is active and accepting new chat requests.
-         */
-        public static final Status OPEN = new Status("open");
-
-        /**
-         * The queue is active but NOT accepting new chat requests. This state might
-         * occur when the workgroup has closed because regular support hours have closed,
-         * but there are still several requests left in the queue.
-         */
-        public static final Status ACTIVE = new Status("active");
-
-        /**
-         * The queue is NOT active and NOT accepting new chat requests.
-         */
-        public static final Status CLOSED = new Status("closed");
-
-        /**
-         * Converts a String into the corresponding status. Valid String values
-         * that can be converted to a status are: "open", "active", and "closed".
-         *
-         * @param type the String value to covert.
-         * @return the corresponding Type.
-         */
-        public static Status fromString(String type) {
-            if (type == null) {
-                return null;
-            }
-            type = type.toLowerCase();
-            if (OPEN.toString().equals(type)) {
-                return OPEN;
-            }
-            else if (ACTIVE.toString().equals(type)) {
-                return ACTIVE;
-            }
-            else if (CLOSED.toString().equals(type)) {
-                return CLOSED;
-            }
-            else {
-                return null;
-            }
-        }
-
-        private String value;
-
-        private Status(String value) {
-            this.value = value;
-        }
-
-        public String toString() {
-            return value;
-        }
-    }
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.agent;
+
+import java.util.*;
+
+import org.jivesoftware.smackx.workgroup.QueueUser;
+
+/**
+ * A queue in a workgroup, which is a pool of agents that are routed  a specific type of
+ * chat request.
+ */
+public class WorkgroupQueue {
+
+    private String name;
+    private Status status = Status.CLOSED;
+
+    private int averageWaitTime = -1;
+    private Date oldestEntry = null;
+    private Set<QueueUser> users = Collections.emptySet();
+
+    private int maxChats = 0;
+    private int currentChats = 0;
+
+    /**
+     * Creates a new workgroup queue instance.
+     *
+     * @param name the name of the queue.
+     */
+    WorkgroupQueue(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Returns the name of the queue.
+     *
+     * @return the name of the queue.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the status of the queue.
+     *
+     * @return the status of the queue.
+     */
+    public Status getStatus() {
+        return status;
+    }
+
+    void setStatus(Status status) {
+        this.status = status;
+    }
+
+    /**
+     * Returns the number of users waiting in the queue waiting to be routed to
+     * an agent.
+     *
+     * @return the number of users waiting in the queue.
+     */
+    public int getUserCount() {
+        if (users == null) {
+            return 0;
+        }
+        return users.size();
+    }
+
+    /**
+     * Returns an Iterator for the users in the queue waiting to be routed to
+     * an agent (QueueUser instances).
+     *
+     * @return an Iterator for the users waiting in the queue.
+     */
+    public Iterator<QueueUser> getUsers() {
+        if (users == null) {
+            return new HashSet<QueueUser>().iterator();
+        }
+        return Collections.unmodifiableSet(users).iterator();
+    }
+
+    void setUsers(Set<QueueUser> users) {
+        this.users = users;
+    }
+
+    /**
+     * Returns the average amount of time users wait in the queue before being
+     * routed to an agent. If average wait time info isn't available, -1 will
+     * be returned.
+     *
+     * @return the average wait time
+     */
+    public int getAverageWaitTime() {
+        return averageWaitTime;
+    }
+
+    void setAverageWaitTime(int averageTime) {
+        this.averageWaitTime = averageTime;
+    }
+
+    /**
+     * Returns the date of the oldest request waiting in the queue. If there
+     * are no requests waiting to be routed, this method will return <tt>null</tt>.
+     *
+     * @return the date of the oldest request in the queue.
+     */
+    public Date getOldestEntry() {
+        return oldestEntry;
+    }
+
+    void setOldestEntry(Date oldestEntry) {
+        this.oldestEntry = oldestEntry;
+    }
+
+    /**
+     * Returns the maximum number of simultaneous chats the queue can handle.
+     *
+     * @return the max number of chats the queue can handle.
+     */
+    public int getMaxChats() {
+        return maxChats;
+    }
+
+    void setMaxChats(int maxChats) {
+        this.maxChats = maxChats;
+    }
+
+    /**
+     * Returns the current number of active chat sessions in the queue.
+     *
+     * @return the current number of active chat sessions in the queue.
+     */
+    public int getCurrentChats() {
+        return currentChats;
+    }
+
+    void setCurrentChats(int currentChats) {
+        this.currentChats = currentChats;
+    }
+
+    /**
+     * A class to represent the status of the workgroup. The possible values are:
+     *
+     * <ul>
+     *      <li>WorkgroupQueue.Status.OPEN -- the queue is active and accepting new chat requests.
+     *      <li>WorkgroupQueue.Status.ACTIVE -- the queue is active but NOT accepting new chat
+     *          requests.
+     *      <li>WorkgroupQueue.Status.CLOSED -- the queue is NOT active and NOT accepting new
+     *          chat requests.
+     * </ul>
+     */
+    public static class Status {
+
+        /**
+         * The queue is active and accepting new chat requests.
+         */
+        public static final Status OPEN = new Status("open");
+
+        /**
+         * The queue is active but NOT accepting new chat requests. This state might
+         * occur when the workgroup has closed because regular support hours have closed,
+         * but there are still several requests left in the queue.
+         */
+        public static final Status ACTIVE = new Status("active");
+
+        /**
+         * The queue is NOT active and NOT accepting new chat requests.
+         */
+        public static final Status CLOSED = new Status("closed");
+
+        /**
+         * Converts a String into the corresponding status. Valid String values
+         * that can be converted to a status are: "open", "active", and "closed".
+         *
+         * @param type the String value to covert.
+         * @return the corresponding Type.
+         */
+        public static Status fromString(String type) {
+            if (type == null) {
+                return null;
+            }
+            type = type.toLowerCase();
+            if (OPEN.toString().equals(type)) {
+                return OPEN;
+            }
+            else if (ACTIVE.toString().equals(type)) {
+                return ACTIVE;
+            }
+            else if (CLOSED.toString().equals(type)) {
+                return CLOSED;
+            }
+            else {
+                return null;
+            }
+        }
+
+        private String value;
+
+        private Status(String value) {
+            this.value = value;
+        }
+
+        public String toString() {
+            return value;
+        }
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/forms/WorkgroupForm.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/forms/WorkgroupForm.java
index f2dc08e..8348d97 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/forms/WorkgroupForm.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/forms/WorkgroupForm.java
@@ -1,82 +1,82 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.ext.forms;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.jivesoftware.smack.util.PacketParserUtils;
-import org.xmlpull.v1.XmlPullParser;
-
-public class WorkgroupForm extends IQ {
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "workgroup-form";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
-        // Add packet extensions, if any are defined.
-        buf.append(getExtensionsXML());
-        buf.append("</").append(ELEMENT_NAME).append("> ");
-
-        return buf.toString();
-    }
-
-    /**
-     * An IQProvider for WebForm packets.
-     *
-     * @author Derek DeMoro
-     */
-    public static class InternalProvider implements IQProvider {
-
-        public InternalProvider() {
-            super();
-        }
-
-        public IQ parseIQ(XmlPullParser parser) throws Exception {
-            WorkgroupForm answer = new WorkgroupForm();
-
-            boolean done = false;
-            while (!done) {
-                int eventType = parser.next();
-                if (eventType == XmlPullParser.START_TAG) {
-                    // Parse the packet extension
-                    answer.addExtension(PacketParserUtils.parsePacketExtension(parser.getName(),
-                            parser.getNamespace(), parser));
-                }
-                else if (eventType == XmlPullParser.END_TAG) {
-                    if (parser.getName().equals(ELEMENT_NAME)) {
-                        done = true;
-                    }
-                }
-            }
-
-            return answer;
-        }
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.ext.forms;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.jivesoftware.smack.util.PacketParserUtils;
+import org.xmlpull.v1.XmlPullParser;
+
+public class WorkgroupForm extends IQ {
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "workgroup-form";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
+        // Add packet extensions, if any are defined.
+        buf.append(getExtensionsXML());
+        buf.append("</").append(ELEMENT_NAME).append("> ");
+
+        return buf.toString();
+    }
+
+    /**
+     * An IQProvider for WebForm packets.
+     *
+     * @author Derek DeMoro
+     */
+    public static class InternalProvider implements IQProvider {
+
+        public InternalProvider() {
+            super();
+        }
+
+        public IQ parseIQ(XmlPullParser parser) throws Exception {
+            WorkgroupForm answer = new WorkgroupForm();
+
+            boolean done = false;
+            while (!done) {
+                int eventType = parser.next();
+                if (eventType == XmlPullParser.START_TAG) {
+                    // Parse the packet extension
+                    answer.addExtension(PacketParserUtils.parsePacketExtension(parser.getName(),
+                            parser.getNamespace(), parser));
+                }
+                else if (eventType == XmlPullParser.END_TAG) {
+                    if (parser.getName().equals(ELEMENT_NAME)) {
+                        done = true;
+                    }
+                }
+            }
+
+            return answer;
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/history/AgentChatHistory.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/history/AgentChatHistory.java
index 7b8d200..fcc9de0 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/history/AgentChatHistory.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/history/AgentChatHistory.java
@@ -1,155 +1,155 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.ext.history;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-
-/**
- * IQ provider used to retrieve individual agent information. Each chat session can be mapped
- * to one or more jids and therefore retrievable.
- */
-public class AgentChatHistory extends IQ {
-    private String agentJID;
-    private int maxSessions;
-    private long startDate;
-
-    private List<AgentChatSession> agentChatSessions = new ArrayList<AgentChatSession>();
-
-    public AgentChatHistory(String agentJID, int maxSessions, Date startDate) {
-        this.agentJID = agentJID;
-        this.maxSessions = maxSessions;
-        this.startDate = startDate.getTime();
-    }
-
-    public AgentChatHistory(String agentJID, int maxSessions) {
-        this.agentJID = agentJID;
-        this.maxSessions = maxSessions;
-        this.startDate = 0;
-    }
-
-    public AgentChatHistory() {
-    }
-
-    public void addChatSession(AgentChatSession chatSession) {
-        agentChatSessions.add(chatSession);
-    }
-
-    public Collection<AgentChatSession> getAgentChatSessions() {
-        return agentChatSessions;
-    }
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "chat-sessions";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=");
-        buf.append('"');
-        buf.append(NAMESPACE);
-        buf.append('"');
-        buf.append(" agentJID=\"" + agentJID + "\"");
-        buf.append(" maxSessions=\"" + maxSessions + "\"");
-        buf.append(" startDate=\"" + startDate + "\"");
-
-        buf.append("></").append(ELEMENT_NAME).append("> ");
-        return buf.toString();
-    }
-
-    /**
-     * Packet extension provider for AgentHistory packets.
-     */
-    public static class InternalProvider implements IQProvider {
-
-        public IQ parseIQ(XmlPullParser parser) throws Exception {
-            if (parser.getEventType() != XmlPullParser.START_TAG) {
-                throw new IllegalStateException("Parser not in proper position, or bad XML.");
-            }
-
-            AgentChatHistory agentChatHistory = new AgentChatHistory();
-
-            boolean done = false;
-            while (!done) {
-                int eventType = parser.next();
-                if ((eventType == XmlPullParser.START_TAG) && ("chat-session".equals(parser.getName()))) {
-                    agentChatHistory.addChatSession(parseChatSetting(parser));
-
-                }
-                else if (eventType == XmlPullParser.END_TAG && ELEMENT_NAME.equals(parser.getName())) {
-                    done = true;
-                }
-            }
-            return agentChatHistory;
-        }
-
-        private AgentChatSession parseChatSetting(XmlPullParser parser) throws Exception {
-
-            boolean done = false;
-            Date date = null;
-            long duration = 0;
-            String visitorsName = null;
-            String visitorsEmail = null;
-            String sessionID = null;
-            String question = null;
-
-            while (!done) {
-                int eventType = parser.next();
-                if ((eventType == XmlPullParser.START_TAG) && ("date".equals(parser.getName()))) {
-                    String dateStr = parser.nextText();
-                    long l = Long.valueOf(dateStr).longValue();
-                    date = new Date(l);
-                }
-                else if ((eventType == XmlPullParser.START_TAG) && ("duration".equals(parser.getName()))) {
-                    duration = Long.valueOf(parser.nextText()).longValue();
-                }
-                else if ((eventType == XmlPullParser.START_TAG) && ("visitorsName".equals(parser.getName()))) {
-                    visitorsName = parser.nextText();
-                }
-                else if ((eventType == XmlPullParser.START_TAG) && ("visitorsEmail".equals(parser.getName()))) {
-                    visitorsEmail = parser.nextText();
-                }
-                else if ((eventType == XmlPullParser.START_TAG) && ("sessionID".equals(parser.getName()))) {
-                    sessionID = parser.nextText();
-                }
-                else if ((eventType == XmlPullParser.START_TAG) && ("question".equals(parser.getName()))) {
-                    question = parser.nextText();
-                }
-                else if (eventType == XmlPullParser.END_TAG && "chat-session".equals(parser.getName())) {
-                    done = true;
-                }
-            }
-            return new AgentChatSession(date, duration, visitorsName, visitorsEmail, sessionID, question);
-        }
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.ext.history;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * IQ provider used to retrieve individual agent information. Each chat session can be mapped
+ * to one or more jids and therefore retrievable.
+ */
+public class AgentChatHistory extends IQ {
+    private String agentJID;
+    private int maxSessions;
+    private long startDate;
+
+    private List<AgentChatSession> agentChatSessions = new ArrayList<AgentChatSession>();
+
+    public AgentChatHistory(String agentJID, int maxSessions, Date startDate) {
+        this.agentJID = agentJID;
+        this.maxSessions = maxSessions;
+        this.startDate = startDate.getTime();
+    }
+
+    public AgentChatHistory(String agentJID, int maxSessions) {
+        this.agentJID = agentJID;
+        this.maxSessions = maxSessions;
+        this.startDate = 0;
+    }
+
+    public AgentChatHistory() {
+    }
+
+    public void addChatSession(AgentChatSession chatSession) {
+        agentChatSessions.add(chatSession);
+    }
+
+    public Collection<AgentChatSession> getAgentChatSessions() {
+        return agentChatSessions;
+    }
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "chat-sessions";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=");
+        buf.append('"');
+        buf.append(NAMESPACE);
+        buf.append('"');
+        buf.append(" agentJID=\"" + agentJID + "\"");
+        buf.append(" maxSessions=\"" + maxSessions + "\"");
+        buf.append(" startDate=\"" + startDate + "\"");
+
+        buf.append("></").append(ELEMENT_NAME).append("> ");
+        return buf.toString();
+    }
+
+    /**
+     * Packet extension provider for AgentHistory packets.
+     */
+    public static class InternalProvider implements IQProvider {
+
+        public IQ parseIQ(XmlPullParser parser) throws Exception {
+            if (parser.getEventType() != XmlPullParser.START_TAG) {
+                throw new IllegalStateException("Parser not in proper position, or bad XML.");
+            }
+
+            AgentChatHistory agentChatHistory = new AgentChatHistory();
+
+            boolean done = false;
+            while (!done) {
+                int eventType = parser.next();
+                if ((eventType == XmlPullParser.START_TAG) && ("chat-session".equals(parser.getName()))) {
+                    agentChatHistory.addChatSession(parseChatSetting(parser));
+
+                }
+                else if (eventType == XmlPullParser.END_TAG && ELEMENT_NAME.equals(parser.getName())) {
+                    done = true;
+                }
+            }
+            return agentChatHistory;
+        }
+
+        private AgentChatSession parseChatSetting(XmlPullParser parser) throws Exception {
+
+            boolean done = false;
+            Date date = null;
+            long duration = 0;
+            String visitorsName = null;
+            String visitorsEmail = null;
+            String sessionID = null;
+            String question = null;
+
+            while (!done) {
+                int eventType = parser.next();
+                if ((eventType == XmlPullParser.START_TAG) && ("date".equals(parser.getName()))) {
+                    String dateStr = parser.nextText();
+                    long l = Long.valueOf(dateStr).longValue();
+                    date = new Date(l);
+                }
+                else if ((eventType == XmlPullParser.START_TAG) && ("duration".equals(parser.getName()))) {
+                    duration = Long.valueOf(parser.nextText()).longValue();
+                }
+                else if ((eventType == XmlPullParser.START_TAG) && ("visitorsName".equals(parser.getName()))) {
+                    visitorsName = parser.nextText();
+                }
+                else if ((eventType == XmlPullParser.START_TAG) && ("visitorsEmail".equals(parser.getName()))) {
+                    visitorsEmail = parser.nextText();
+                }
+                else if ((eventType == XmlPullParser.START_TAG) && ("sessionID".equals(parser.getName()))) {
+                    sessionID = parser.nextText();
+                }
+                else if ((eventType == XmlPullParser.START_TAG) && ("question".equals(parser.getName()))) {
+                    question = parser.nextText();
+                }
+                else if (eventType == XmlPullParser.END_TAG && "chat-session".equals(parser.getName())) {
+                    done = true;
+                }
+            }
+            return new AgentChatSession(date, duration, visitorsName, visitorsEmail, sessionID, question);
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/history/AgentChatSession.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/history/AgentChatSession.java
index 5113cda..290a562 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/history/AgentChatSession.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/history/AgentChatSession.java
@@ -1,93 +1,93 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.ext.history;
-
-import java.util.Date;
-
-/**
- * Represents one chat session for an agent.
- */
-public class AgentChatSession {
-    public Date startDate;
-    public long duration;
-    public String visitorsName;
-    public String visitorsEmail;
-    public String sessionID;
-    public String question;
-
-    public AgentChatSession(Date date, long duration, String visitorsName, String visitorsEmail, String sessionID, String question) {
-        this.startDate = date;
-        this.duration = duration;
-        this.visitorsName = visitorsName;
-        this.visitorsEmail = visitorsEmail;
-        this.sessionID = sessionID;
-        this.question = question;
-    }
-
-    public Date getStartDate() {
-        return startDate;
-    }
-
-    public void setStartDate(Date startDate) {
-        this.startDate = startDate;
-    }
-
-    public long getDuration() {
-        return duration;
-    }
-
-    public void setDuration(long duration) {
-        this.duration = duration;
-    }
-
-    public String getVisitorsName() {
-        return visitorsName;
-    }
-
-    public void setVisitorsName(String visitorsName) {
-        this.visitorsName = visitorsName;
-    }
-
-    public String getVisitorsEmail() {
-        return visitorsEmail;
-    }
-
-    public void setVisitorsEmail(String visitorsEmail) {
-        this.visitorsEmail = visitorsEmail;
-    }
-
-    public String getSessionID() {
-        return sessionID;
-    }
-
-    public void setSessionID(String sessionID) {
-        this.sessionID = sessionID;
-    }
-
-    public void setQuestion(String question){
-        this.question = question;
-    }
-
-    public String getQuestion(){
-        return question;
-    }
-
-
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.ext.history;
+
+import java.util.Date;
+
+/**
+ * Represents one chat session for an agent.
+ */
+public class AgentChatSession {
+    public Date startDate;
+    public long duration;
+    public String visitorsName;
+    public String visitorsEmail;
+    public String sessionID;
+    public String question;
+
+    public AgentChatSession(Date date, long duration, String visitorsName, String visitorsEmail, String sessionID, String question) {
+        this.startDate = date;
+        this.duration = duration;
+        this.visitorsName = visitorsName;
+        this.visitorsEmail = visitorsEmail;
+        this.sessionID = sessionID;
+        this.question = question;
+    }
+
+    public Date getStartDate() {
+        return startDate;
+    }
+
+    public void setStartDate(Date startDate) {
+        this.startDate = startDate;
+    }
+
+    public long getDuration() {
+        return duration;
+    }
+
+    public void setDuration(long duration) {
+        this.duration = duration;
+    }
+
+    public String getVisitorsName() {
+        return visitorsName;
+    }
+
+    public void setVisitorsName(String visitorsName) {
+        this.visitorsName = visitorsName;
+    }
+
+    public String getVisitorsEmail() {
+        return visitorsEmail;
+    }
+
+    public void setVisitorsEmail(String visitorsEmail) {
+        this.visitorsEmail = visitorsEmail;
+    }
+
+    public String getSessionID() {
+        return sessionID;
+    }
+
+    public void setSessionID(String sessionID) {
+        this.sessionID = sessionID;
+    }
+
+    public void setQuestion(String question){
+        this.question = question;
+    }
+
+    public String getQuestion(){
+        return question;
+    }
+
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/history/ChatMetadata.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/history/ChatMetadata.java
index 301e1a5..1eaf30f 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/history/ChatMetadata.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/history/ChatMetadata.java
@@ -1,116 +1,116 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.ext.history;
-
-import org.jivesoftware.smackx.workgroup.util.MetaDataUtils;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class ChatMetadata extends IQ {
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "chat-metadata";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
-
-
-    private String sessionID;
-
-    public String getSessionID() {
-        return sessionID;
-    }
-
-    public void setSessionID(String sessionID) {
-        this.sessionID = sessionID;
-    }
-
-
-    private Map<String, List<String>> map = new HashMap<String, List<String>>();
-
-    public void setMetadata(Map<String, List<String>> metadata){
-        this.map = metadata;
-    }
-
-    public Map<String, List<String>> getMetadata(){
-        return map;
-    }
-
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
-        buf.append("<sessionID>").append(getSessionID()).append("</sessionID>");
-        buf.append("</").append(ELEMENT_NAME).append("> ");
-
-        return buf.toString();
-    }
-
-    /**
-     * An IQProvider for Metadata packets.
-     *
-     * @author Derek DeMoro
-     */
-    public static class Provider implements IQProvider {
-
-        public Provider() {
-            super();
-        }
-
-        public IQ parseIQ(XmlPullParser parser) throws Exception {
-            final ChatMetadata chatM = new ChatMetadata();
-
-            boolean done = false;
-            while (!done) {
-                int eventType = parser.next();
-                if (eventType == XmlPullParser.START_TAG) {
-                    if (parser.getName().equals("sessionID")) {
-                       chatM.setSessionID(parser.nextText());
-                    }
-                    else if (parser.getName().equals("metadata")) {
-                        Map<String, List<String>> map = MetaDataUtils.parseMetaData(parser);
-                        chatM.setMetadata(map);
-                    }
-                }
-                else if (eventType == XmlPullParser.END_TAG) {
-                    if (parser.getName().equals(ELEMENT_NAME)) {
-                        done = true;
-                    }
-                }
-            }
-
-            return chatM;
-        }
-    }
-}
-
-
-
-
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.ext.history;
+
+import org.jivesoftware.smackx.workgroup.util.MetaDataUtils;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ChatMetadata extends IQ {
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "chat-metadata";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
+
+
+    private String sessionID;
+
+    public String getSessionID() {
+        return sessionID;
+    }
+
+    public void setSessionID(String sessionID) {
+        this.sessionID = sessionID;
+    }
+
+
+    private Map<String, List<String>> map = new HashMap<String, List<String>>();
+
+    public void setMetadata(Map<String, List<String>> metadata){
+        this.map = metadata;
+    }
+
+    public Map<String, List<String>> getMetadata(){
+        return map;
+    }
+
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
+        buf.append("<sessionID>").append(getSessionID()).append("</sessionID>");
+        buf.append("</").append(ELEMENT_NAME).append("> ");
+
+        return buf.toString();
+    }
+
+    /**
+     * An IQProvider for Metadata packets.
+     *
+     * @author Derek DeMoro
+     */
+    public static class Provider implements IQProvider {
+
+        public Provider() {
+            super();
+        }
+
+        public IQ parseIQ(XmlPullParser parser) throws Exception {
+            final ChatMetadata chatM = new ChatMetadata();
+
+            boolean done = false;
+            while (!done) {
+                int eventType = parser.next();
+                if (eventType == XmlPullParser.START_TAG) {
+                    if (parser.getName().equals("sessionID")) {
+                       chatM.setSessionID(parser.nextText());
+                    }
+                    else if (parser.getName().equals("metadata")) {
+                        Map<String, List<String>> map = MetaDataUtils.parseMetaData(parser);
+                        chatM.setMetadata(map);
+                    }
+                }
+                else if (eventType == XmlPullParser.END_TAG) {
+                    if (parser.getName().equals(ELEMENT_NAME)) {
+                        done = true;
+                    }
+                }
+            }
+
+            return chatM;
+        }
+    }
+}
+
+
+
+
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/macros/Macro.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/macros/Macro.java
index acf6196..114902f 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/macros/Macro.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/macros/Macro.java
@@ -1,68 +1,68 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.ext.macros;
-
-/**
- * Macro datamodel.
- */
-public class Macro {
-    public static final int TEXT = 0;
-    public static final int URL = 1;
-    public static final int IMAGE = 2;
-
-
-    private String title;
-    private String description;
-    private String response;
-    private int type;
-
-    public String getTitle() {
-        return title;
-    }
-
-    public void setTitle(String title) {
-        this.title = title;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    public String getResponse() {
-        return response;
-    }
-
-    public void setResponse(String response) {
-        this.response = response;
-    }
-
-    public int getType() {
-        return type;
-    }
-
-    public void setType(int type) {
-        this.type = type;
-    }
-
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.ext.macros;
+
+/**
+ * Macro datamodel.
+ */
+public class Macro {
+    public static final int TEXT = 0;
+    public static final int URL = 1;
+    public static final int IMAGE = 2;
+
+
+    private String title;
+    private String description;
+    private String response;
+    private int type;
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getResponse() {
+        return response;
+    }
+
+    public void setResponse(String response) {
+        this.response = response;
+    }
+
+    public int getType() {
+        return type;
+    }
+
+    public void setType(int type) {
+        this.type = type;
+    }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/macros/MacroGroup.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/macros/MacroGroup.java
index 0742b3d..bb583ae 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/macros/MacroGroup.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/macros/MacroGroup.java
@@ -1,143 +1,143 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.ext.macros;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * MacroGroup datamodel.
- */
-public class MacroGroup {
-    private List<Macro> macros;
-    private List<MacroGroup> macroGroups;
-
-
-    // Define MacroGroup
-    private String title;
-
-    public MacroGroup() {
-        macros = new ArrayList<Macro>();
-        macroGroups = new ArrayList<MacroGroup>();
-    }
-
-    public void addMacro(Macro macro) {
-        macros.add(macro);
-    }
-
-    public void removeMacro(Macro macro) {
-        macros.remove(macro);
-    }
-
-    public Macro getMacroByTitle(String title) {
-        Collection<Macro> col = Collections.unmodifiableList(macros);
-        Iterator<Macro> iter = col.iterator();
-        while (iter.hasNext()) {
-            Macro macro = (Macro)iter.next();
-            if (macro.getTitle().equalsIgnoreCase(title)) {
-                return macro;
-            }
-        }
-        return null;
-    }
-
-    public void addMacroGroup(MacroGroup group) {
-        macroGroups.add(group);
-    }
-
-    public void removeMacroGroup(MacroGroup group) {
-        macroGroups.remove(group);
-    }
-
-    public Macro getMacro(int location) {
-        return (Macro)macros.get(location);
-    }
-
-    public MacroGroup getMacroGroupByTitle(String title) {
-        Collection<MacroGroup> col = Collections.unmodifiableList(macroGroups);
-        Iterator<MacroGroup> iter = col.iterator();
-        while (iter.hasNext()) {
-            MacroGroup group = (MacroGroup)iter.next();
-            if (group.getTitle().equalsIgnoreCase(title)) {
-                return group;
-            }
-        }
-        return null;
-    }
-
-    public MacroGroup getMacroGroup(int location) {
-        return (MacroGroup)macroGroups.get(location);
-    }
-
-
-    public List<Macro>  getMacros() {
-        return macros;
-    }
-
-    public void setMacros(List<Macro> macros) {
-        this.macros = macros;
-    }
-
-    public List<MacroGroup> getMacroGroups() {
-        return macroGroups;
-    }
-
-    public void setMacroGroups(List<MacroGroup> macroGroups) {
-        this.macroGroups = macroGroups;
-    }
-
-    public String getTitle() {
-        return title;
-    }
-
-    public void setTitle(String title) {
-        this.title = title;
-    }
-    
-    public String toXML() {
-    	StringBuilder buf = new StringBuilder();
-    	buf.append("<macrogroup>");
-    	buf.append("<title>" +  getTitle() + "</title>");
-    	buf.append("<macros>");
-    	for (Macro macro : getMacros())
-		{
-    		buf.append("<macro>");
-    		buf.append("<title>" + macro.getTitle() + "</title>");
-    		buf.append("<type>" + macro.getType() + "</type>");
-    		buf.append("<description>" + macro.getDescription() + "</description>");
-    		buf.append("<response>" + macro.getResponse() + "</response>");
-    		buf.append("</macro>");
-		}
-    	buf.append("</macros>");
-    	
-    	if (getMacroGroups().size() > 0) {
-    		buf.append("<macroGroups>");
-    		for (MacroGroup groups : getMacroGroups()) {
-    			buf.append(groups.toXML());
-    		}
-    		buf.append("</macroGroups>");
-    	}
-    	buf.append("</macrogroup>");
-    	return buf.toString(); 
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.ext.macros;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * MacroGroup datamodel.
+ */
+public class MacroGroup {
+    private List<Macro> macros;
+    private List<MacroGroup> macroGroups;
+
+
+    // Define MacroGroup
+    private String title;
+
+    public MacroGroup() {
+        macros = new ArrayList<Macro>();
+        macroGroups = new ArrayList<MacroGroup>();
+    }
+
+    public void addMacro(Macro macro) {
+        macros.add(macro);
+    }
+
+    public void removeMacro(Macro macro) {
+        macros.remove(macro);
+    }
+
+    public Macro getMacroByTitle(String title) {
+        Collection<Macro> col = Collections.unmodifiableList(macros);
+        Iterator<Macro> iter = col.iterator();
+        while (iter.hasNext()) {
+            Macro macro = (Macro)iter.next();
+            if (macro.getTitle().equalsIgnoreCase(title)) {
+                return macro;
+            }
+        }
+        return null;
+    }
+
+    public void addMacroGroup(MacroGroup group) {
+        macroGroups.add(group);
+    }
+
+    public void removeMacroGroup(MacroGroup group) {
+        macroGroups.remove(group);
+    }
+
+    public Macro getMacro(int location) {
+        return (Macro)macros.get(location);
+    }
+
+    public MacroGroup getMacroGroupByTitle(String title) {
+        Collection<MacroGroup> col = Collections.unmodifiableList(macroGroups);
+        Iterator<MacroGroup> iter = col.iterator();
+        while (iter.hasNext()) {
+            MacroGroup group = (MacroGroup)iter.next();
+            if (group.getTitle().equalsIgnoreCase(title)) {
+                return group;
+            }
+        }
+        return null;
+    }
+
+    public MacroGroup getMacroGroup(int location) {
+        return (MacroGroup)macroGroups.get(location);
+    }
+
+
+    public List<Macro>  getMacros() {
+        return macros;
+    }
+
+    public void setMacros(List<Macro> macros) {
+        this.macros = macros;
+    }
+
+    public List<MacroGroup> getMacroGroups() {
+        return macroGroups;
+    }
+
+    public void setMacroGroups(List<MacroGroup> macroGroups) {
+        this.macroGroups = macroGroups;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+    
+    public String toXML() {
+    	StringBuilder buf = new StringBuilder();
+    	buf.append("<macrogroup>");
+    	buf.append("<title>" +  getTitle() + "</title>");
+    	buf.append("<macros>");
+    	for (Macro macro : getMacros())
+		{
+    		buf.append("<macro>");
+    		buf.append("<title>" + macro.getTitle() + "</title>");
+    		buf.append("<type>" + macro.getType() + "</type>");
+    		buf.append("<description>" + macro.getDescription() + "</description>");
+    		buf.append("<response>" + macro.getResponse() + "</response>");
+    		buf.append("</macro>");
+		}
+    	buf.append("</macros>");
+    	
+    	if (getMacroGroups().size() > 0) {
+    		buf.append("<macroGroups>");
+    		for (MacroGroup groups : getMacroGroups()) {
+    			buf.append(groups.toXML());
+    		}
+    		buf.append("</macroGroups>");
+    	}
+    	buf.append("</macrogroup>");
+    	return buf.toString(); 
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/macros/Macros.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/macros/Macros.java
index b658bf9..c0718c2 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/macros/Macros.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/macros/Macros.java
@@ -1,198 +1,198 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.ext.macros;
-
-import java.io.StringReader;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.jivesoftware.smack.util.StringUtils;
-import org.xmlpull.mxp1.MXParser;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * Macros iq is responsible for handling global and personal macros in the a Live Assistant
- * Workgroup.
- */
-public class Macros extends IQ {
-
-    private MacroGroup rootGroup;
-    private boolean personal;
-    private MacroGroup personalMacroGroup;
-
-    public MacroGroup getRootGroup() {
-        return rootGroup;
-    }
-
-    public void setRootGroup(MacroGroup rootGroup) {
-        this.rootGroup = rootGroup;
-    }
-
-    public boolean isPersonal() {
-        return personal;
-    }
-
-    public void setPersonal(boolean personal) {
-        this.personal = personal;
-    }
-
-    public MacroGroup getPersonalMacroGroup() {
-        return personalMacroGroup;
-    }
-
-    public void setPersonalMacroGroup(MacroGroup personalMacroGroup) {
-        this.personalMacroGroup = personalMacroGroup;
-    }
-
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "macros";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
-        if (isPersonal()) {
-            buf.append("<personal>true</personal>");
-        }
-        if (getPersonalMacroGroup() != null) {        	
-        	buf.append("<personalMacro>");
-        	buf.append(StringUtils.escapeForXML(getPersonalMacroGroup().toXML()));
-        	buf.append("</personalMacro>");
-        }
-        buf.append("</").append(ELEMENT_NAME).append("> ");
-
-        return buf.toString();
-    }
-
-    /**
-     * An IQProvider for Macro packets.
-     *
-     * @author Derek DeMoro
-     */
-    public static class InternalProvider implements IQProvider {
-
-        public InternalProvider() {
-            super();
-        }
-
-        public IQ parseIQ(XmlPullParser parser) throws Exception {
-            Macros macroGroup = new Macros();
-
-            boolean done = false;
-            while (!done) {
-                int eventType = parser.next();
-                if (eventType == XmlPullParser.START_TAG) {
-                    if (parser.getName().equals("model")) {
-                        String macros = parser.nextText();
-                        MacroGroup group = parseMacroGroups(macros);
-                        macroGroup.setRootGroup(group);
-                    }
-                }
-                else if (eventType == XmlPullParser.END_TAG) {
-                    if (parser.getName().equals(ELEMENT_NAME)) {
-                        done = true;
-                    }
-                }
-            }
-
-            return macroGroup;
-        }
-        
-        public Macro parseMacro(XmlPullParser parser) throws Exception {
-        	Macro macro = new Macro();
-        	 boolean done = false;
-            while (!done) {
-	        	int eventType = parser.next();
-	        	if (eventType == XmlPullParser.START_TAG) {
-	        		if (parser.getName().equals("title")) {
-	        			parser.next();
-	        			macro.setTitle(parser.getText());
-	        		}
-	        		else if (parser.getName().equals("description")) {
-	        			macro.setDescription(parser.nextText());
-	        		}
-	        		else if (parser.getName().equals("response")) {
-	        			macro.setResponse(parser.nextText());
-	        		}
-	        		else if (parser.getName().equals("type")) {
-	        			macro.setType(Integer.valueOf(parser.nextText()).intValue());
-	        		}
-	        	}
-	            else if (eventType == XmlPullParser.END_TAG) {
-	                if (parser.getName().equals("macro")) {
-	                    done = true;
-	                }
-	            }
-            }
-        	return macro;
-        }
-        
-        public MacroGroup parseMacroGroup(XmlPullParser parser) throws Exception {
-        	MacroGroup group = new MacroGroup();
-        	
-            boolean done = false;
-            while (!done) {
-	        	int eventType = parser.next();
-	        	if (eventType == XmlPullParser.START_TAG) {
-	        		if (parser.getName().equals("macrogroup")) {
-	        			group.addMacroGroup(parseMacroGroup(parser));
-	        		}
-	        		if (parser.getName().equals("title")) {
-	        			group.setTitle(parser.nextText());
-	        		}
-	        		if (parser.getName().equals("macro")) {
-	        			group.addMacro(parseMacro(parser));
-	        		}
-	        	}
-	            else if (eventType == XmlPullParser.END_TAG) {
-	                if (parser.getName().equals("macrogroup")) {
-	                    done = true;
-	                }
-	            }
-            }
-        	return group; 
-        }
-        
-        public MacroGroup parseMacroGroups(String macros) throws Exception {
-
-        	MacroGroup group = null;
-        	XmlPullParser parser = new MXParser();
-        	parser.setInput(new StringReader(macros));
-			int eventType = parser.getEventType();
-			while (eventType != XmlPullParser.END_DOCUMENT) {		
-				eventType = parser.next();
-				 if (eventType == XmlPullParser.START_TAG) {
-	                    if (parser.getName().equals("macrogroup")) {
-	                    	group = parseMacroGroup(parser);
-	                    }
-				 }
-			}
-			return group;
-        }
-    }
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.ext.macros;
+
+import java.io.StringReader;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.jivesoftware.smack.util.StringUtils;
+import org.xmlpull.mxp1.MXParser;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * Macros iq is responsible for handling global and personal macros in the a Live Assistant
+ * Workgroup.
+ */
+public class Macros extends IQ {
+
+    private MacroGroup rootGroup;
+    private boolean personal;
+    private MacroGroup personalMacroGroup;
+
+    public MacroGroup getRootGroup() {
+        return rootGroup;
+    }
+
+    public void setRootGroup(MacroGroup rootGroup) {
+        this.rootGroup = rootGroup;
+    }
+
+    public boolean isPersonal() {
+        return personal;
+    }
+
+    public void setPersonal(boolean personal) {
+        this.personal = personal;
+    }
+
+    public MacroGroup getPersonalMacroGroup() {
+        return personalMacroGroup;
+    }
+
+    public void setPersonalMacroGroup(MacroGroup personalMacroGroup) {
+        this.personalMacroGroup = personalMacroGroup;
+    }
+
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "macros";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
+        if (isPersonal()) {
+            buf.append("<personal>true</personal>");
+        }
+        if (getPersonalMacroGroup() != null) {        	
+        	buf.append("<personalMacro>");
+        	buf.append(StringUtils.escapeForXML(getPersonalMacroGroup().toXML()));
+        	buf.append("</personalMacro>");
+        }
+        buf.append("</").append(ELEMENT_NAME).append("> ");
+
+        return buf.toString();
+    }
+
+    /**
+     * An IQProvider for Macro packets.
+     *
+     * @author Derek DeMoro
+     */
+    public static class InternalProvider implements IQProvider {
+
+        public InternalProvider() {
+            super();
+        }
+
+        public IQ parseIQ(XmlPullParser parser) throws Exception {
+            Macros macroGroup = new Macros();
+
+            boolean done = false;
+            while (!done) {
+                int eventType = parser.next();
+                if (eventType == XmlPullParser.START_TAG) {
+                    if (parser.getName().equals("model")) {
+                        String macros = parser.nextText();
+                        MacroGroup group = parseMacroGroups(macros);
+                        macroGroup.setRootGroup(group);
+                    }
+                }
+                else if (eventType == XmlPullParser.END_TAG) {
+                    if (parser.getName().equals(ELEMENT_NAME)) {
+                        done = true;
+                    }
+                }
+            }
+
+            return macroGroup;
+        }
+        
+        public Macro parseMacro(XmlPullParser parser) throws Exception {
+        	Macro macro = new Macro();
+        	 boolean done = false;
+            while (!done) {
+	        	int eventType = parser.next();
+	        	if (eventType == XmlPullParser.START_TAG) {
+	        		if (parser.getName().equals("title")) {
+	        			parser.next();
+	        			macro.setTitle(parser.getText());
+	        		}
+	        		else if (parser.getName().equals("description")) {
+	        			macro.setDescription(parser.nextText());
+	        		}
+	        		else if (parser.getName().equals("response")) {
+	        			macro.setResponse(parser.nextText());
+	        		}
+	        		else if (parser.getName().equals("type")) {
+	        			macro.setType(Integer.valueOf(parser.nextText()).intValue());
+	        		}
+	        	}
+	            else if (eventType == XmlPullParser.END_TAG) {
+	                if (parser.getName().equals("macro")) {
+	                    done = true;
+	                }
+	            }
+            }
+        	return macro;
+        }
+        
+        public MacroGroup parseMacroGroup(XmlPullParser parser) throws Exception {
+        	MacroGroup group = new MacroGroup();
+        	
+            boolean done = false;
+            while (!done) {
+	        	int eventType = parser.next();
+	        	if (eventType == XmlPullParser.START_TAG) {
+	        		if (parser.getName().equals("macrogroup")) {
+	        			group.addMacroGroup(parseMacroGroup(parser));
+	        		}
+	        		if (parser.getName().equals("title")) {
+	        			group.setTitle(parser.nextText());
+	        		}
+	        		if (parser.getName().equals("macro")) {
+	        			group.addMacro(parseMacro(parser));
+	        		}
+	        	}
+	            else if (eventType == XmlPullParser.END_TAG) {
+	                if (parser.getName().equals("macrogroup")) {
+	                    done = true;
+	                }
+	            }
+            }
+        	return group; 
+        }
+        
+        public MacroGroup parseMacroGroups(String macros) throws Exception {
+
+        	MacroGroup group = null;
+        	XmlPullParser parser = new MXParser();
+        	parser.setInput(new StringReader(macros));
+			int eventType = parser.getEventType();
+			while (eventType != XmlPullParser.END_DOCUMENT) {		
+				eventType = parser.next();
+				 if (eventType == XmlPullParser.START_TAG) {
+	                    if (parser.getName().equals("macrogroup")) {
+	                    	group = parseMacroGroup(parser);
+	                    }
+				 }
+			}
+			return group;
+        }
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/notes/ChatNotes.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/notes/ChatNotes.java
index eff3c6c..3540006 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/notes/ChatNotes.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/ext/notes/ChatNotes.java
@@ -1,155 +1,155 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.ext.notes;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * IQ packet for retrieving and adding Chat Notes.
- */
-public class ChatNotes extends IQ {
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "chat-notes";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
-
-
-    private String sessionID;
-    private String notes;
-
-    public String getSessionID() {
-        return sessionID;
-    }
-
-    public void setSessionID(String sessionID) {
-        this.sessionID = sessionID;
-    }
-
-    public String getNotes() {
-        return notes;
-    }
-
-    public void setNotes(String notes) {
-        this.notes = notes;
-    }
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
-        buf.append("<sessionID>").append(getSessionID()).append("</sessionID>");
-
-        if (getNotes() != null) {
-            buf.append("<notes>").append(getNotes()).append("</notes>");
-        }
-        buf.append("</").append(ELEMENT_NAME).append("> ");
-
-        return buf.toString();
-    }
-
-    /**
-     * An IQProvider for ChatNotes packets.
-     *
-     * @author Derek DeMoro
-     */
-    public static class Provider implements IQProvider {
-
-        public Provider() {
-            super();
-        }
-
-        public IQ parseIQ(XmlPullParser parser) throws Exception {
-            ChatNotes chatNotes = new ChatNotes();
-
-            boolean done = false;
-            while (!done) {
-                int eventType = parser.next();
-                if (eventType == XmlPullParser.START_TAG) {
-                    if (parser.getName().equals("sessionID")) {
-                        chatNotes.setSessionID(parser.nextText());
-                    }
-                    else if (parser.getName().equals("text")) {
-                        String note = parser.nextText();
-                        note = note.replaceAll("\\\\n", "\n");
-                        chatNotes.setNotes(note);
-                    }
-                }
-                else if (eventType == XmlPullParser.END_TAG) {
-                    if (parser.getName().equals(ELEMENT_NAME)) {
-                        done = true;
-                    }
-                }
-            }
-
-            return chatNotes;
-        }
-    }
-
-    /**
-     * Replaces all instances of oldString with newString in string.
-     *
-     * @param string    the String to search to perform replacements on
-     * @param oldString the String that should be replaced by newString
-     * @param newString the String that will replace all instances of oldString
-     * @return a String will all instances of oldString replaced by newString
-     */
-    public static final String replace(String string, String oldString, String newString) {
-        if (string == null) {
-            return null;
-        }
-        // If the newString is null or zero length, just return the string since there's nothing
-        // to replace.
-        if (newString == null) {
-            return string;
-        }
-        int i = 0;
-        // Make sure that oldString appears at least once before doing any processing.
-        if ((i = string.indexOf(oldString, i)) >= 0) {
-            // Use char []'s, as they are more efficient to deal with.
-            char[] string2 = string.toCharArray();
-            char[] newString2 = newString.toCharArray();
-            int oLength = oldString.length();
-            StringBuilder buf = new StringBuilder(string2.length);
-            buf.append(string2, 0, i).append(newString2);
-            i += oLength;
-            int j = i;
-            // Replace all remaining instances of oldString with newString.
-            while ((i = string.indexOf(oldString, i)) > 0) {
-                buf.append(string2, j, i - j).append(newString2);
-                i += oLength;
-                j = i;
-            }
-            buf.append(string2, j, string2.length - j);
-            return buf.toString();
-        }
-        return string;
-    }
-}
-
-
-
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.ext.notes;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * IQ packet for retrieving and adding Chat Notes.
+ */
+public class ChatNotes extends IQ {
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "chat-notes";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
+
+
+    private String sessionID;
+    private String notes;
+
+    public String getSessionID() {
+        return sessionID;
+    }
+
+    public void setSessionID(String sessionID) {
+        this.sessionID = sessionID;
+    }
+
+    public String getNotes() {
+        return notes;
+    }
+
+    public void setNotes(String notes) {
+        this.notes = notes;
+    }
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
+        buf.append("<sessionID>").append(getSessionID()).append("</sessionID>");
+
+        if (getNotes() != null) {
+            buf.append("<notes>").append(getNotes()).append("</notes>");
+        }
+        buf.append("</").append(ELEMENT_NAME).append("> ");
+
+        return buf.toString();
+    }
+
+    /**
+     * An IQProvider for ChatNotes packets.
+     *
+     * @author Derek DeMoro
+     */
+    public static class Provider implements IQProvider {
+
+        public Provider() {
+            super();
+        }
+
+        public IQ parseIQ(XmlPullParser parser) throws Exception {
+            ChatNotes chatNotes = new ChatNotes();
+
+            boolean done = false;
+            while (!done) {
+                int eventType = parser.next();
+                if (eventType == XmlPullParser.START_TAG) {
+                    if (parser.getName().equals("sessionID")) {
+                        chatNotes.setSessionID(parser.nextText());
+                    }
+                    else if (parser.getName().equals("text")) {
+                        String note = parser.nextText();
+                        note = note.replaceAll("\\\\n", "\n");
+                        chatNotes.setNotes(note);
+                    }
+                }
+                else if (eventType == XmlPullParser.END_TAG) {
+                    if (parser.getName().equals(ELEMENT_NAME)) {
+                        done = true;
+                    }
+                }
+            }
+
+            return chatNotes;
+        }
+    }
+
+    /**
+     * Replaces all instances of oldString with newString in string.
+     *
+     * @param string    the String to search to perform replacements on
+     * @param oldString the String that should be replaced by newString
+     * @param newString the String that will replace all instances of oldString
+     * @return a String will all instances of oldString replaced by newString
+     */
+    public static final String replace(String string, String oldString, String newString) {
+        if (string == null) {
+            return null;
+        }
+        // If the newString is null or zero length, just return the string since there's nothing
+        // to replace.
+        if (newString == null) {
+            return string;
+        }
+        int i = 0;
+        // Make sure that oldString appears at least once before doing any processing.
+        if ((i = string.indexOf(oldString, i)) >= 0) {
+            // Use char []'s, as they are more efficient to deal with.
+            char[] string2 = string.toCharArray();
+            char[] newString2 = newString.toCharArray();
+            int oLength = oldString.length();
+            StringBuilder buf = new StringBuilder(string2.length);
+            buf.append(string2, 0, i).append(newString2);
+            i += oLength;
+            int j = i;
+            // Replace all remaining instances of oldString with newString.
+            while ((i = string.indexOf(oldString, i)) > 0) {
+                buf.append(string2, j, i - j).append(newString2);
+                i += oLength;
+                j = i;
+            }
+            buf.append(string2, j, string2.length - j);
+            return buf.toString();
+        }
+        return string;
+    }
+}
+
+
+
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/AgentInfo.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/AgentInfo.java
index 8b9d230..6502b88 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/AgentInfo.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/AgentInfo.java
@@ -1,132 +1,132 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * IQ packet for retrieving and changing the Agent personal information.
- */
-public class AgentInfo extends IQ {
-
-    /**
-    * Element name of the packet extension.
-    */
-   public static final String ELEMENT_NAME = "agent-info";
-
-   /**
-    * Namespace of the packet extension.
-    */
-   public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
-
-    private String jid;
-    private String name;
-
-    /**
-     * Returns the Agent's jid.
-     *
-     * @return the Agent's jid.
-     */
-    public String getJid() {
-        return jid;
-    }
-
-    /**
-     * Sets the Agent's jid.
-     *
-     * @param jid the jid of the agent.
-     */
-    public void setJid(String jid) {
-        this.jid = jid;
-    }
-
-    /**
-     * Returns the Agent's name. The name of the agent may be different than the user's name.
-     * This property may be shown in the webchat client.
-     *
-     * @return the Agent's name.
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Sets the Agent's name. The name of the agent may be different than the user's name.
-     * This property may be shown in the webchat client.
-     *
-     * @param name the new name of the agent.
-     */
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
-        if (jid != null) {
-            buf.append("<jid>").append(getJid()).append("</jid>");
-        }
-        if (name != null) {
-            buf.append("<name>").append(getName()).append("</name>");
-        }
-        buf.append("</").append(ELEMENT_NAME).append("> ");
-
-        return buf.toString();
-    }
-
-    /**
-     * An IQProvider for AgentInfo packets.
-     *
-     * @author Gaston Dombiak
-     */
-    public static class Provider implements IQProvider {
-
-        public Provider() {
-            super();
-        }
-
-        public IQ parseIQ(XmlPullParser parser) throws Exception {
-            AgentInfo answer = new AgentInfo();
-
-            boolean done = false;
-            while (!done) {
-                int eventType = parser.next();
-                if (eventType == XmlPullParser.START_TAG) {
-                    if (parser.getName().equals("jid")) {
-                        answer.setJid(parser.nextText());
-                    }
-                    else if (parser.getName().equals("name")) {
-                        answer.setName(parser.nextText());
-                    }
-                }
-                else if (eventType == XmlPullParser.END_TAG) {
-                    if (parser.getName().equals(ELEMENT_NAME)) {
-                        done = true;
-                    }
-                }
-            }
-
-            return answer;
-        }
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * IQ packet for retrieving and changing the Agent personal information.
+ */
+public class AgentInfo extends IQ {
+
+    /**
+    * Element name of the packet extension.
+    */
+   public static final String ELEMENT_NAME = "agent-info";
+
+   /**
+    * Namespace of the packet extension.
+    */
+   public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
+
+    private String jid;
+    private String name;
+
+    /**
+     * Returns the Agent's jid.
+     *
+     * @return the Agent's jid.
+     */
+    public String getJid() {
+        return jid;
+    }
+
+    /**
+     * Sets the Agent's jid.
+     *
+     * @param jid the jid of the agent.
+     */
+    public void setJid(String jid) {
+        this.jid = jid;
+    }
+
+    /**
+     * Returns the Agent's name. The name of the agent may be different than the user's name.
+     * This property may be shown in the webchat client.
+     *
+     * @return the Agent's name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Sets the Agent's name. The name of the agent may be different than the user's name.
+     * This property may be shown in the webchat client.
+     *
+     * @param name the new name of the agent.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
+        if (jid != null) {
+            buf.append("<jid>").append(getJid()).append("</jid>");
+        }
+        if (name != null) {
+            buf.append("<name>").append(getName()).append("</name>");
+        }
+        buf.append("</").append(ELEMENT_NAME).append("> ");
+
+        return buf.toString();
+    }
+
+    /**
+     * An IQProvider for AgentInfo packets.
+     *
+     * @author Gaston Dombiak
+     */
+    public static class Provider implements IQProvider {
+
+        public Provider() {
+            super();
+        }
+
+        public IQ parseIQ(XmlPullParser parser) throws Exception {
+            AgentInfo answer = new AgentInfo();
+
+            boolean done = false;
+            while (!done) {
+                int eventType = parser.next();
+                if (eventType == XmlPullParser.START_TAG) {
+                    if (parser.getName().equals("jid")) {
+                        answer.setJid(parser.nextText());
+                    }
+                    else if (parser.getName().equals("name")) {
+                        answer.setName(parser.nextText());
+                    }
+                }
+                else if (eventType == XmlPullParser.END_TAG) {
+                    if (parser.getName().equals(ELEMENT_NAME)) {
+                        done = true;
+                    }
+                }
+            }
+
+            return answer;
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/AgentStatus.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/AgentStatus.java
index 9f49033..f84fe5c 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/AgentStatus.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/AgentStatus.java
@@ -1,266 +1,266 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.*;
-
-/**
- * Agent status packet.
- *
- * @author Matt Tucker
- */
-public class AgentStatus implements PacketExtension {
-
-    private static final SimpleDateFormat UTC_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
-
-    static {
-        UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+0"));
-    }
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "agent-status";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
-
-    private String workgroupJID;
-    private List<ChatInfo> currentChats = new ArrayList<ChatInfo>();
-    private int maxChats = -1;
-
-    AgentStatus() {
-    }
-
-    public String getWorkgroupJID() {
-        return workgroupJID;
-    }
-
-    /**
-     * Returns a collection of ChatInfo where each ChatInfo represents a Chat where this agent
-     * is participating.
-     *
-     * @return a collection of ChatInfo where each ChatInfo represents a Chat where this agent
-     *         is participating.
-     */
-    public List<ChatInfo> getCurrentChats() {
-        return Collections.unmodifiableList(currentChats);
-    }
-
-    public int getMaxChats() {
-        return maxChats;
-    }
-
-    public String getElementName() {
-        return ELEMENT_NAME;
-    }
-
-    public String getNamespace() {
-        return NAMESPACE;
-    }
-
-    public String toXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\"");
-        if (workgroupJID != null) {
-            buf.append(" jid=\"").append(workgroupJID).append("\"");
-        }
-        buf.append(">");
-        if (maxChats != -1) {
-            buf.append("<max-chats>").append(maxChats).append("</max-chats>");
-        }
-        if (!currentChats.isEmpty()) {
-            buf.append("<current-chats xmlns= \"http://jivesoftware.com/protocol/workgroup\">");
-            for (Iterator<ChatInfo> it = currentChats.iterator(); it.hasNext();) {
-                buf.append(((ChatInfo)it.next()).toXML());
-            }
-            buf.append("</current-chats>");
-        }
-        buf.append("</").append(this.getElementName()).append("> ");
-
-        return buf.toString();
-    }
-
-    /**
-     * Represents information about a Chat where this Agent is participating.
-     *
-     * @author Gaston Dombiak
-     */
-    public static class ChatInfo {
-
-        private String sessionID;
-        private String userID;
-        private Date date;
-        private String email;
-        private String username;
-        private String question;
-
-        public ChatInfo(String sessionID, String userID, Date date, String email, String username, String question) {
-            this.sessionID = sessionID;
-            this.userID = userID;
-            this.date = date;
-            this.email = email;
-            this.username = username;
-            this.question = question;
-        }
-
-        /**
-         * Returns the sessionID associated to this chat. Each chat will have a unique sessionID
-         * that could be used for retrieving the whole transcript of the conversation.
-         *
-         * @return the sessionID associated to this chat.
-         */
-        public String getSessionID() {
-            return sessionID;
-        }
-
-        /**
-         * Returns the user unique identification of the user that made the initial request and
-         * for which this chat was generated. If the user joined using an anonymous connection
-         * then the userID will be the value of the ID attribute of the USER element. Otherwise,
-         * the userID will be the bare JID of the user that made the request.
-         *
-         * @return the user unique identification of the user that made the initial request.
-         */
-        public String getUserID() {
-            return userID;
-        }
-
-        /**
-         * Returns the date when this agent joined the chat.
-         *
-         * @return the date when this agent joined the chat.
-         */
-        public Date getDate() {
-            return date;
-        }
-
-        /**
-         * Returns the email address associated with the user.
-         *
-         * @return the email address associated with the user.
-         */
-        public String getEmail() {
-            return email;
-        }
-
-        /**
-         * Returns the username(nickname) associated with the user.
-         *
-         * @return the username associated with the user.
-         */
-        public String getUsername() {
-            return username;
-        }
-
-        /**
-         * Returns the question the user asked.
-         *
-         * @return the question the user asked, if any.
-         */
-        public String getQuestion() {
-            return question;
-        }
-
-        public String toXML() {
-            StringBuilder buf = new StringBuilder();
-
-            buf.append("<chat ");
-            if (sessionID != null) {
-                buf.append(" sessionID=\"").append(sessionID).append("\"");
-            }
-            if (userID != null) {
-                buf.append(" userID=\"").append(userID).append("\"");
-            }
-            if (date != null) {
-                buf.append(" startTime=\"").append(UTC_FORMAT.format(date)).append("\"");
-            }
-            if (email != null) {
-                buf.append(" email=\"").append(email).append("\"");
-            }
-            if (username != null) {
-                buf.append(" username=\"").append(username).append("\"");
-            }
-            if (question != null) {
-                buf.append(" question=\"").append(question).append("\"");
-            }
-            buf.append("/>");
-
-            return buf.toString();
-        }
-    }
-
-    /**
-     * Packet extension provider for AgentStatus packets.
-     */
-    public static class Provider implements PacketExtensionProvider {
-
-        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
-            AgentStatus agentStatus = new AgentStatus();
-
-            agentStatus.workgroupJID = parser.getAttributeValue("", "jid");
-
-            boolean done = false;
-            while (!done) {
-                int eventType = parser.next();
-
-                if (eventType == XmlPullParser.START_TAG) {
-                    if ("chat".equals(parser.getName())) {
-                        agentStatus.currentChats.add(parseChatInfo(parser));
-                    }
-                    else if ("max-chats".equals(parser.getName())) {
-                        agentStatus.maxChats = Integer.parseInt(parser.nextText());
-                    }
-                }
-                else if (eventType == XmlPullParser.END_TAG &&
-                    ELEMENT_NAME.equals(parser.getName())) {
-                    done = true;
-                }
-            }
-            return agentStatus;
-        }
-
-        private ChatInfo parseChatInfo(XmlPullParser parser) {
-
-            String sessionID = parser.getAttributeValue("", "sessionID");
-            String userID = parser.getAttributeValue("", "userID");
-            Date date = null;
-            try {
-                date = UTC_FORMAT.parse(parser.getAttributeValue("", "startTime"));
-            }
-            catch (ParseException e) {
-            }
-
-            String email = parser.getAttributeValue("", "email");
-            String username = parser.getAttributeValue("", "username");
-            String question = parser.getAttributeValue("", "question");
-
-            return new ChatInfo(sessionID, userID, date, email, username, question);
-        }
-    }
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * Agent status packet.
+ *
+ * @author Matt Tucker
+ */
+public class AgentStatus implements PacketExtension {
+
+    private static final SimpleDateFormat UTC_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
+
+    static {
+        UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+0"));
+    }
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "agent-status";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
+
+    private String workgroupJID;
+    private List<ChatInfo> currentChats = new ArrayList<ChatInfo>();
+    private int maxChats = -1;
+
+    AgentStatus() {
+    }
+
+    public String getWorkgroupJID() {
+        return workgroupJID;
+    }
+
+    /**
+     * Returns a collection of ChatInfo where each ChatInfo represents a Chat where this agent
+     * is participating.
+     *
+     * @return a collection of ChatInfo where each ChatInfo represents a Chat where this agent
+     *         is participating.
+     */
+    public List<ChatInfo> getCurrentChats() {
+        return Collections.unmodifiableList(currentChats);
+    }
+
+    public int getMaxChats() {
+        return maxChats;
+    }
+
+    public String getElementName() {
+        return ELEMENT_NAME;
+    }
+
+    public String getNamespace() {
+        return NAMESPACE;
+    }
+
+    public String toXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\"");
+        if (workgroupJID != null) {
+            buf.append(" jid=\"").append(workgroupJID).append("\"");
+        }
+        buf.append(">");
+        if (maxChats != -1) {
+            buf.append("<max-chats>").append(maxChats).append("</max-chats>");
+        }
+        if (!currentChats.isEmpty()) {
+            buf.append("<current-chats xmlns= \"http://jivesoftware.com/protocol/workgroup\">");
+            for (Iterator<ChatInfo> it = currentChats.iterator(); it.hasNext();) {
+                buf.append(((ChatInfo)it.next()).toXML());
+            }
+            buf.append("</current-chats>");
+        }
+        buf.append("</").append(this.getElementName()).append("> ");
+
+        return buf.toString();
+    }
+
+    /**
+     * Represents information about a Chat where this Agent is participating.
+     *
+     * @author Gaston Dombiak
+     */
+    public static class ChatInfo {
+
+        private String sessionID;
+        private String userID;
+        private Date date;
+        private String email;
+        private String username;
+        private String question;
+
+        public ChatInfo(String sessionID, String userID, Date date, String email, String username, String question) {
+            this.sessionID = sessionID;
+            this.userID = userID;
+            this.date = date;
+            this.email = email;
+            this.username = username;
+            this.question = question;
+        }
+
+        /**
+         * Returns the sessionID associated to this chat. Each chat will have a unique sessionID
+         * that could be used for retrieving the whole transcript of the conversation.
+         *
+         * @return the sessionID associated to this chat.
+         */
+        public String getSessionID() {
+            return sessionID;
+        }
+
+        /**
+         * Returns the user unique identification of the user that made the initial request and
+         * for which this chat was generated. If the user joined using an anonymous connection
+         * then the userID will be the value of the ID attribute of the USER element. Otherwise,
+         * the userID will be the bare JID of the user that made the request.
+         *
+         * @return the user unique identification of the user that made the initial request.
+         */
+        public String getUserID() {
+            return userID;
+        }
+
+        /**
+         * Returns the date when this agent joined the chat.
+         *
+         * @return the date when this agent joined the chat.
+         */
+        public Date getDate() {
+            return date;
+        }
+
+        /**
+         * Returns the email address associated with the user.
+         *
+         * @return the email address associated with the user.
+         */
+        public String getEmail() {
+            return email;
+        }
+
+        /**
+         * Returns the username(nickname) associated with the user.
+         *
+         * @return the username associated with the user.
+         */
+        public String getUsername() {
+            return username;
+        }
+
+        /**
+         * Returns the question the user asked.
+         *
+         * @return the question the user asked, if any.
+         */
+        public String getQuestion() {
+            return question;
+        }
+
+        public String toXML() {
+            StringBuilder buf = new StringBuilder();
+
+            buf.append("<chat ");
+            if (sessionID != null) {
+                buf.append(" sessionID=\"").append(sessionID).append("\"");
+            }
+            if (userID != null) {
+                buf.append(" userID=\"").append(userID).append("\"");
+            }
+            if (date != null) {
+                buf.append(" startTime=\"").append(UTC_FORMAT.format(date)).append("\"");
+            }
+            if (email != null) {
+                buf.append(" email=\"").append(email).append("\"");
+            }
+            if (username != null) {
+                buf.append(" username=\"").append(username).append("\"");
+            }
+            if (question != null) {
+                buf.append(" question=\"").append(question).append("\"");
+            }
+            buf.append("/>");
+
+            return buf.toString();
+        }
+    }
+
+    /**
+     * Packet extension provider for AgentStatus packets.
+     */
+    public static class Provider implements PacketExtensionProvider {
+
+        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
+            AgentStatus agentStatus = new AgentStatus();
+
+            agentStatus.workgroupJID = parser.getAttributeValue("", "jid");
+
+            boolean done = false;
+            while (!done) {
+                int eventType = parser.next();
+
+                if (eventType == XmlPullParser.START_TAG) {
+                    if ("chat".equals(parser.getName())) {
+                        agentStatus.currentChats.add(parseChatInfo(parser));
+                    }
+                    else if ("max-chats".equals(parser.getName())) {
+                        agentStatus.maxChats = Integer.parseInt(parser.nextText());
+                    }
+                }
+                else if (eventType == XmlPullParser.END_TAG &&
+                    ELEMENT_NAME.equals(parser.getName())) {
+                    done = true;
+                }
+            }
+            return agentStatus;
+        }
+
+        private ChatInfo parseChatInfo(XmlPullParser parser) {
+
+            String sessionID = parser.getAttributeValue("", "sessionID");
+            String userID = parser.getAttributeValue("", "userID");
+            Date date = null;
+            try {
+                date = UTC_FORMAT.parse(parser.getAttributeValue("", "startTime"));
+            }
+            catch (ParseException e) {
+            }
+
+            String email = parser.getAttributeValue("", "email");
+            String username = parser.getAttributeValue("", "username");
+            String question = parser.getAttributeValue("", "question");
+
+            return new ChatInfo(sessionID, userID, date, email, username, question);
+        }
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/AgentStatusRequest.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/AgentStatusRequest.java
index 48549d2..db6626c 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/AgentStatusRequest.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/AgentStatusRequest.java
@@ -1,163 +1,163 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * Agent status request packet. This packet is used by agents to request the list of
- * agents in a workgroup. The response packet contains a list of packets. Presence
- * packets from individual agents follow.
- *
- * @author Matt Tucker
- */
-public class AgentStatusRequest extends IQ {
-
-     /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "agent-status-request";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
-
-    private Set<Item> agents;
-
-    public AgentStatusRequest() {
-        agents = new HashSet<Item>();
-    }
-
-    public int getAgentCount() {
-        return agents.size();
-    }
-
-    public Set<Item> getAgents() {
-        return Collections.unmodifiableSet(agents);
-    }
-
-    public String getElementName() {
-        return ELEMENT_NAME;
-    }
-
-    public String getNamespace() {
-        return NAMESPACE;
-    }
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
-        synchronized (agents) {
-            for (Iterator<Item> i=agents.iterator(); i.hasNext(); ) {
-                Item item = (Item) i.next();
-                buf.append("<agent jid=\"").append(item.getJID()).append("\">");
-                if (item.getName() != null) {
-                    buf.append("<name xmlns=\""+ AgentInfo.NAMESPACE + "\">");
-                    buf.append(item.getName());
-                    buf.append("</name>");
-                }
-                buf.append("</agent>");
-            }
-        }
-        buf.append("</").append(this.getElementName()).append("> ");
-        return buf.toString();
-    }
-
-    public static class Item {
-
-        private String jid;
-        private String type;
-        private String name;
-
-        public Item(String jid, String type, String name) {
-            this.jid = jid;
-            this.type = type;
-            this.name = name;
-        }
-
-        public String getJID() {
-            return jid;
-        }
-
-        public String getType() {
-            return type;
-        }
-
-        public String getName() {
-            return name;
-        }
-    }
-
-    /**
-     * Packet extension provider for AgentStatusRequest packets.
-     */
-    public static class Provider implements IQProvider {
-
-        public IQ parseIQ(XmlPullParser parser) throws Exception {
-            AgentStatusRequest statusRequest = new AgentStatusRequest();
-
-            if (parser.getEventType() != XmlPullParser.START_TAG) {
-                throw new IllegalStateException("Parser not in proper position, or bad XML.");
-            }
-
-            boolean done = false;
-            while (!done) {
-                int eventType = parser.next();
-                if ((eventType == XmlPullParser.START_TAG) && ("agent".equals(parser.getName()))) {
-                    statusRequest.agents.add(parseAgent(parser));
-                }
-                else if (eventType == XmlPullParser.END_TAG &&
-                        "agent-status-request".equals(parser.getName()))
-                {
-                    done = true;
-                }
-            }
-            return statusRequest;
-        }
-
-        private Item parseAgent(XmlPullParser parser) throws Exception {
-
-            boolean done = false;
-            String jid = parser.getAttributeValue("", "jid");
-            String type = parser.getAttributeValue("", "type");
-            String name = null;
-            while (!done) {
-                int eventType = parser.next();
-                if ((eventType == XmlPullParser.START_TAG) && ("name".equals(parser.getName()))) {
-                    name = parser.nextText();
-                }
-                else if (eventType == XmlPullParser.END_TAG &&
-                        "agent".equals(parser.getName()))
-                {
-                    done = true;
-                }
-            }
-            return new Item(jid, type, name);
-        }
-    }
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * Agent status request packet. This packet is used by agents to request the list of
+ * agents in a workgroup. The response packet contains a list of packets. Presence
+ * packets from individual agents follow.
+ *
+ * @author Matt Tucker
+ */
+public class AgentStatusRequest extends IQ {
+
+     /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "agent-status-request";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
+
+    private Set<Item> agents;
+
+    public AgentStatusRequest() {
+        agents = new HashSet<Item>();
+    }
+
+    public int getAgentCount() {
+        return agents.size();
+    }
+
+    public Set<Item> getAgents() {
+        return Collections.unmodifiableSet(agents);
+    }
+
+    public String getElementName() {
+        return ELEMENT_NAME;
+    }
+
+    public String getNamespace() {
+        return NAMESPACE;
+    }
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
+        synchronized (agents) {
+            for (Iterator<Item> i=agents.iterator(); i.hasNext(); ) {
+                Item item = (Item) i.next();
+                buf.append("<agent jid=\"").append(item.getJID()).append("\">");
+                if (item.getName() != null) {
+                    buf.append("<name xmlns=\""+ AgentInfo.NAMESPACE + "\">");
+                    buf.append(item.getName());
+                    buf.append("</name>");
+                }
+                buf.append("</agent>");
+            }
+        }
+        buf.append("</").append(this.getElementName()).append("> ");
+        return buf.toString();
+    }
+
+    public static class Item {
+
+        private String jid;
+        private String type;
+        private String name;
+
+        public Item(String jid, String type, String name) {
+            this.jid = jid;
+            this.type = type;
+            this.name = name;
+        }
+
+        public String getJID() {
+            return jid;
+        }
+
+        public String getType() {
+            return type;
+        }
+
+        public String getName() {
+            return name;
+        }
+    }
+
+    /**
+     * Packet extension provider for AgentStatusRequest packets.
+     */
+    public static class Provider implements IQProvider {
+
+        public IQ parseIQ(XmlPullParser parser) throws Exception {
+            AgentStatusRequest statusRequest = new AgentStatusRequest();
+
+            if (parser.getEventType() != XmlPullParser.START_TAG) {
+                throw new IllegalStateException("Parser not in proper position, or bad XML.");
+            }
+
+            boolean done = false;
+            while (!done) {
+                int eventType = parser.next();
+                if ((eventType == XmlPullParser.START_TAG) && ("agent".equals(parser.getName()))) {
+                    statusRequest.agents.add(parseAgent(parser));
+                }
+                else if (eventType == XmlPullParser.END_TAG &&
+                        "agent-status-request".equals(parser.getName()))
+                {
+                    done = true;
+                }
+            }
+            return statusRequest;
+        }
+
+        private Item parseAgent(XmlPullParser parser) throws Exception {
+
+            boolean done = false;
+            String jid = parser.getAttributeValue("", "jid");
+            String type = parser.getAttributeValue("", "type");
+            String name = null;
+            while (!done) {
+                int eventType = parser.next();
+                if ((eventType == XmlPullParser.START_TAG) && ("name".equals(parser.getName()))) {
+                    name = parser.nextText();
+                }
+                else if (eventType == XmlPullParser.END_TAG &&
+                        "agent".equals(parser.getName()))
+                {
+                    done = true;
+                }
+            }
+            return new Item(jid, type, name);
+        }
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/AgentWorkgroups.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/AgentWorkgroups.java
index 292a640..29fa09a 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/AgentWorkgroups.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/AgentWorkgroups.java
@@ -1,129 +1,129 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Represents a request for getting the jid of the workgroups where an agent can work or could
- * represent the result of such request which will contain the list of workgroups JIDs where the
- * agent can work.
- *
- * @author Gaston Dombiak
- */
-public class AgentWorkgroups extends IQ {
-
-    private String agentJID;
-    private List<String> workgroups;
-
-    /**
-     * Creates an AgentWorkgroups request for the given agent. This IQ will be sent and an answer
-     * will be received with the jid of the workgroups where the agent can work.
-     *
-     * @param agentJID the id of the agent to get his workgroups.
-     */
-    public AgentWorkgroups(String agentJID) {
-        this.agentJID = agentJID;
-        this.workgroups = new ArrayList<String>();
-    }
-
-    /**
-     * Creates an AgentWorkgroups which will contain the JIDs of the workgroups where an agent can
-     * work.
-     *
-     * @param agentJID the id of the agent that can work in the list of workgroups.
-     * @param workgroups the list of workgroup JIDs where the agent can work.
-     */
-    public AgentWorkgroups(String agentJID, List<String> workgroups) {
-        this.agentJID = agentJID;
-        this.workgroups = workgroups;
-    }
-
-    public String getAgentJID() {
-        return agentJID;
-    }
-
-    /**
-     * Returns a list of workgroup JIDs where the agent can work.
-     *
-     * @return a list of workgroup JIDs where the agent can work.
-     */
-    public List<String> getWorkgroups() {
-        return Collections.unmodifiableList(workgroups);
-    }
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<workgroups xmlns=\"http://jabber.org/protocol/workgroup\" jid=\"")
-                .append(agentJID)
-                .append("\">");
-
-        for (Iterator<String> it=workgroups.iterator(); it.hasNext();) {
-            String workgroupJID = it.next();
-            buf.append("<workgroup jid=\"" + workgroupJID + "\"/>");
-        }
-
-        buf.append("</workgroups>");
-
-        return buf.toString();
-    }
-
-    /**
-     * An IQProvider for AgentWorkgroups packets.
-     *
-     * @author Gaston Dombiak
-     */
-    public static class Provider implements IQProvider {
-
-        public Provider() {
-            super();
-        }
-
-        public IQ parseIQ(XmlPullParser parser) throws Exception {
-            String agentJID = parser.getAttributeValue("", "jid");
-            List<String> workgroups = new ArrayList<String>();
-
-            boolean done = false;
-            while (!done) {
-                int eventType = parser.next();
-                if (eventType == XmlPullParser.START_TAG) {
-                    if (parser.getName().equals("workgroup")) {
-                        workgroups.add(parser.getAttributeValue("", "jid"));
-                    }
-                }
-                else if (eventType == XmlPullParser.END_TAG) {
-                    if (parser.getName().equals("workgroups")) {
-                        done = true;
-                    }
-                }
-            }
-
-            return new AgentWorkgroups(agentJID, workgroups);
-        }
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Represents a request for getting the jid of the workgroups where an agent can work or could
+ * represent the result of such request which will contain the list of workgroups JIDs where the
+ * agent can work.
+ *
+ * @author Gaston Dombiak
+ */
+public class AgentWorkgroups extends IQ {
+
+    private String agentJID;
+    private List<String> workgroups;
+
+    /**
+     * Creates an AgentWorkgroups request for the given agent. This IQ will be sent and an answer
+     * will be received with the jid of the workgroups where the agent can work.
+     *
+     * @param agentJID the id of the agent to get his workgroups.
+     */
+    public AgentWorkgroups(String agentJID) {
+        this.agentJID = agentJID;
+        this.workgroups = new ArrayList<String>();
+    }
+
+    /**
+     * Creates an AgentWorkgroups which will contain the JIDs of the workgroups where an agent can
+     * work.
+     *
+     * @param agentJID the id of the agent that can work in the list of workgroups.
+     * @param workgroups the list of workgroup JIDs where the agent can work.
+     */
+    public AgentWorkgroups(String agentJID, List<String> workgroups) {
+        this.agentJID = agentJID;
+        this.workgroups = workgroups;
+    }
+
+    public String getAgentJID() {
+        return agentJID;
+    }
+
+    /**
+     * Returns a list of workgroup JIDs where the agent can work.
+     *
+     * @return a list of workgroup JIDs where the agent can work.
+     */
+    public List<String> getWorkgroups() {
+        return Collections.unmodifiableList(workgroups);
+    }
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<workgroups xmlns=\"http://jabber.org/protocol/workgroup\" jid=\"")
+                .append(agentJID)
+                .append("\">");
+
+        for (Iterator<String> it=workgroups.iterator(); it.hasNext();) {
+            String workgroupJID = it.next();
+            buf.append("<workgroup jid=\"" + workgroupJID + "\"/>");
+        }
+
+        buf.append("</workgroups>");
+
+        return buf.toString();
+    }
+
+    /**
+     * An IQProvider for AgentWorkgroups packets.
+     *
+     * @author Gaston Dombiak
+     */
+    public static class Provider implements IQProvider {
+
+        public Provider() {
+            super();
+        }
+
+        public IQ parseIQ(XmlPullParser parser) throws Exception {
+            String agentJID = parser.getAttributeValue("", "jid");
+            List<String> workgroups = new ArrayList<String>();
+
+            boolean done = false;
+            while (!done) {
+                int eventType = parser.next();
+                if (eventType == XmlPullParser.START_TAG) {
+                    if (parser.getName().equals("workgroup")) {
+                        workgroups.add(parser.getAttributeValue("", "jid"));
+                    }
+                }
+                else if (eventType == XmlPullParser.END_TAG) {
+                    if (parser.getName().equals("workgroups")) {
+                        done = true;
+                    }
+                }
+            }
+
+            return new AgentWorkgroups(agentJID, workgroups);
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/DepartQueuePacket.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/DepartQueuePacket.java
index 620291c..d9db5e1 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/DepartQueuePacket.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/DepartQueuePacket.java
@@ -1,75 +1,75 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.packet.IQ;
-
-/**
- * A IQ packet used to depart a workgroup queue. There are two cases for issuing a depart
- * queue request:<ul>
- *     <li>The user wants to leave the queue. In this case, an instance of this class
- *         should be created without passing in a user address.
- *     <li>An administrator or the server removes wants to remove a user from the queue.
- *         In that case, the address of the user to remove from the queue should be
- *         used to create an instance of this class.</ul>
- *
- * @author loki der quaeler
- */
-public class DepartQueuePacket extends IQ {
-
-    private String user;
-
-    /**
-     * Creates a depart queue request packet to the specified workgroup.
-     *
-     * @param workgroup the workgroup to depart.
-     */
-    public DepartQueuePacket(String workgroup) {
-        this(workgroup, null);
-    }
-
-    /**
-     * Creates a depart queue request to the specified workgroup and for the
-     * specified user.
-     *
-     * @param workgroup the workgroup to depart.
-     * @param user the user to make depart from the queue.
-     */
-    public DepartQueuePacket(String workgroup, String user) {
-        this.user = user;
-
-        setTo(workgroup);
-        setType(IQ.Type.SET);
-        setFrom(user);
-    }
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder("<depart-queue xmlns=\"http://jabber.org/protocol/workgroup\"");
-
-        if (this.user != null) {
-            buf.append("><jid>").append(this.user).append("</jid></depart-queue>");
-        }
-        else {
-            buf.append("/>");
-        }
-
-        return buf.toString();
-    }
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.packet.IQ;
+
+/**
+ * A IQ packet used to depart a workgroup queue. There are two cases for issuing a depart
+ * queue request:<ul>
+ *     <li>The user wants to leave the queue. In this case, an instance of this class
+ *         should be created without passing in a user address.
+ *     <li>An administrator or the server removes wants to remove a user from the queue.
+ *         In that case, the address of the user to remove from the queue should be
+ *         used to create an instance of this class.</ul>
+ *
+ * @author loki der quaeler
+ */
+public class DepartQueuePacket extends IQ {
+
+    private String user;
+
+    /**
+     * Creates a depart queue request packet to the specified workgroup.
+     *
+     * @param workgroup the workgroup to depart.
+     */
+    public DepartQueuePacket(String workgroup) {
+        this(workgroup, null);
+    }
+
+    /**
+     * Creates a depart queue request to the specified workgroup and for the
+     * specified user.
+     *
+     * @param workgroup the workgroup to depart.
+     * @param user the user to make depart from the queue.
+     */
+    public DepartQueuePacket(String workgroup, String user) {
+        this.user = user;
+
+        setTo(workgroup);
+        setType(IQ.Type.SET);
+        setFrom(user);
+    }
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder("<depart-queue xmlns=\"http://jabber.org/protocol/workgroup\"");
+
+        if (this.user != null) {
+            buf.append("><jid>").append(this.user).append("</jid></depart-queue>");
+        }
+        else {
+            buf.append("/>");
+        }
+
+        return buf.toString();
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/MetaDataProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/MetaDataProvider.java
index af76986..a326212 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/MetaDataProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/MetaDataProvider.java
@@ -1,49 +1,49 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import java.util.List;
-import java.util.Map;
-
-import org.jivesoftware.smackx.workgroup.MetaData;
-import org.jivesoftware.smackx.workgroup.util.MetaDataUtils;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * This provider parses meta data if it's not contained already in a larger extension provider.
- *
- * @author loki der quaeler
- */
-public class MetaDataProvider implements PacketExtensionProvider {
-
-    /**
-     * PacketExtensionProvider implementation
-     */
-    public PacketExtension parseExtension (XmlPullParser parser)
-        throws Exception {
-        Map<String, List<String>> metaData = MetaDataUtils.parseMetaData(parser);
-
-        return new MetaData(metaData);
-    }
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import java.util.List;
+import java.util.Map;
+
+import org.jivesoftware.smackx.workgroup.MetaData;
+import org.jivesoftware.smackx.workgroup.util.MetaDataUtils;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * This provider parses meta data if it's not contained already in a larger extension provider.
+ *
+ * @author loki der quaeler
+ */
+public class MetaDataProvider implements PacketExtensionProvider {
+
+    /**
+     * PacketExtensionProvider implementation
+     */
+    public PacketExtension parseExtension (XmlPullParser parser)
+        throws Exception {
+        Map<String, List<String>> metaData = MetaDataUtils.parseMetaData(parser);
+
+        return new MetaData(metaData);
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/OccupantsInfo.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/OccupantsInfo.java
index 0f80866..b577bab 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/OccupantsInfo.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/OccupantsInfo.java
@@ -1,173 +1,173 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-import java.text.SimpleDateFormat;
-import java.util.*;
-
-/**
- * Packet used for requesting information about occupants of a room or for retrieving information
- * such information.
- *
- * @author Gaston Dombiak
- */
-public class OccupantsInfo extends IQ {
-
-    private static final SimpleDateFormat UTC_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
-
-    static {
-        UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+0"));
-    }
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "occupants-info";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
-
-    private String roomID;
-    private final Set<OccupantInfo> occupants;
-
-    public OccupantsInfo(String roomID) {
-        this.roomID = roomID;
-        this.occupants = new HashSet<OccupantInfo>();
-    }
-
-    public String getRoomID() {
-        return roomID;
-    }
-
-    public int getOccupantsCount() {
-        return occupants.size();
-    }
-
-    public Set<OccupantInfo> getOccupants() {
-        return Collections.unmodifiableSet(occupants);
-    }
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE);
-        buf.append("\" roomID=\"").append(roomID).append("\">");
-        synchronized (occupants) {
-            for (OccupantInfo occupant : occupants) {
-                buf.append("<occupant>");
-                // Add the occupant jid
-                buf.append("<jid>");
-                buf.append(occupant.getJID());
-                buf.append("</jid>");
-                // Add the occupant nickname
-                buf.append("<name>");
-                buf.append(occupant.getNickname());
-                buf.append("</name>");
-                // Add the date when the occupant joined the room
-                buf.append("<joined>");
-                buf.append(UTC_FORMAT.format(occupant.getJoined()));
-                buf.append("</joined>");
-                buf.append("</occupant>");
-            }
-        }
-        buf.append("</").append(ELEMENT_NAME).append("> ");
-        return buf.toString();
-    }
-
-    public static class OccupantInfo {
-
-        private String jid;
-        private String nickname;
-        private Date joined;
-
-        public OccupantInfo(String jid, String nickname, Date joined) {
-            this.jid = jid;
-            this.nickname = nickname;
-            this.joined = joined;
-        }
-
-        public String getJID() {
-            return jid;
-        }
-
-        public String getNickname() {
-            return nickname;
-        }
-
-        public Date getJoined() {
-            return joined;
-        }
-    }
-
-    /**
-     * Packet extension provider for AgentStatusRequest packets.
-     */
-    public static class Provider implements IQProvider {
-
-        public IQ parseIQ(XmlPullParser parser) throws Exception {
-            if (parser.getEventType() != XmlPullParser.START_TAG) {
-                throw new IllegalStateException("Parser not in proper position, or bad XML.");
-            }
-            OccupantsInfo occupantsInfo = new OccupantsInfo(parser.getAttributeValue("", "roomID"));
-
-            boolean done = false;
-            while (!done) {
-                int eventType = parser.next();
-                if ((eventType == XmlPullParser.START_TAG) &&
-                        ("occupant".equals(parser.getName()))) {
-                    occupantsInfo.occupants.add(parseOccupantInfo(parser));
-                } else if (eventType == XmlPullParser.END_TAG &&
-                        ELEMENT_NAME.equals(parser.getName())) {
-                    done = true;
-                }
-            }
-            return occupantsInfo;
-        }
-
-        private OccupantInfo parseOccupantInfo(XmlPullParser parser) throws Exception {
-
-            boolean done = false;
-            String jid = null;
-            String nickname = null;
-            Date joined = null;
-            while (!done) {
-                int eventType = parser.next();
-                if ((eventType == XmlPullParser.START_TAG) && ("jid".equals(parser.getName()))) {
-                    jid = parser.nextText();
-                } else if ((eventType == XmlPullParser.START_TAG) &&
-                        ("nickname".equals(parser.getName()))) {
-                    nickname = parser.nextText();
-                } else if ((eventType == XmlPullParser.START_TAG) &&
-                        ("joined".equals(parser.getName()))) {
-                    joined = UTC_FORMAT.parse(parser.nextText());
-                } else if (eventType == XmlPullParser.END_TAG &&
-                        "occupant".equals(parser.getName())) {
-                    done = true;
-                }
-            }
-            return new OccupantInfo(jid, nickname, joined);
-        }
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * Packet used for requesting information about occupants of a room or for retrieving information
+ * such information.
+ *
+ * @author Gaston Dombiak
+ */
+public class OccupantsInfo extends IQ {
+
+    private static final SimpleDateFormat UTC_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
+
+    static {
+        UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+0"));
+    }
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "occupants-info";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
+
+    private String roomID;
+    private final Set<OccupantInfo> occupants;
+
+    public OccupantsInfo(String roomID) {
+        this.roomID = roomID;
+        this.occupants = new HashSet<OccupantInfo>();
+    }
+
+    public String getRoomID() {
+        return roomID;
+    }
+
+    public int getOccupantsCount() {
+        return occupants.size();
+    }
+
+    public Set<OccupantInfo> getOccupants() {
+        return Collections.unmodifiableSet(occupants);
+    }
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE);
+        buf.append("\" roomID=\"").append(roomID).append("\">");
+        synchronized (occupants) {
+            for (OccupantInfo occupant : occupants) {
+                buf.append("<occupant>");
+                // Add the occupant jid
+                buf.append("<jid>");
+                buf.append(occupant.getJID());
+                buf.append("</jid>");
+                // Add the occupant nickname
+                buf.append("<name>");
+                buf.append(occupant.getNickname());
+                buf.append("</name>");
+                // Add the date when the occupant joined the room
+                buf.append("<joined>");
+                buf.append(UTC_FORMAT.format(occupant.getJoined()));
+                buf.append("</joined>");
+                buf.append("</occupant>");
+            }
+        }
+        buf.append("</").append(ELEMENT_NAME).append("> ");
+        return buf.toString();
+    }
+
+    public static class OccupantInfo {
+
+        private String jid;
+        private String nickname;
+        private Date joined;
+
+        public OccupantInfo(String jid, String nickname, Date joined) {
+            this.jid = jid;
+            this.nickname = nickname;
+            this.joined = joined;
+        }
+
+        public String getJID() {
+            return jid;
+        }
+
+        public String getNickname() {
+            return nickname;
+        }
+
+        public Date getJoined() {
+            return joined;
+        }
+    }
+
+    /**
+     * Packet extension provider for AgentStatusRequest packets.
+     */
+    public static class Provider implements IQProvider {
+
+        public IQ parseIQ(XmlPullParser parser) throws Exception {
+            if (parser.getEventType() != XmlPullParser.START_TAG) {
+                throw new IllegalStateException("Parser not in proper position, or bad XML.");
+            }
+            OccupantsInfo occupantsInfo = new OccupantsInfo(parser.getAttributeValue("", "roomID"));
+
+            boolean done = false;
+            while (!done) {
+                int eventType = parser.next();
+                if ((eventType == XmlPullParser.START_TAG) &&
+                        ("occupant".equals(parser.getName()))) {
+                    occupantsInfo.occupants.add(parseOccupantInfo(parser));
+                } else if (eventType == XmlPullParser.END_TAG &&
+                        ELEMENT_NAME.equals(parser.getName())) {
+                    done = true;
+                }
+            }
+            return occupantsInfo;
+        }
+
+        private OccupantInfo parseOccupantInfo(XmlPullParser parser) throws Exception {
+
+            boolean done = false;
+            String jid = null;
+            String nickname = null;
+            Date joined = null;
+            while (!done) {
+                int eventType = parser.next();
+                if ((eventType == XmlPullParser.START_TAG) && ("jid".equals(parser.getName()))) {
+                    jid = parser.nextText();
+                } else if ((eventType == XmlPullParser.START_TAG) &&
+                        ("nickname".equals(parser.getName()))) {
+                    nickname = parser.nextText();
+                } else if ((eventType == XmlPullParser.START_TAG) &&
+                        ("joined".equals(parser.getName()))) {
+                    joined = UTC_FORMAT.parse(parser.nextText());
+                } else if (eventType == XmlPullParser.END_TAG &&
+                        "occupant".equals(parser.getName())) {
+                    done = true;
+                }
+            }
+            return new OccupantInfo(jid, nickname, joined);
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/OfferRequestProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/OfferRequestProvider.java
index 8f56b78..c7d245a 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/OfferRequestProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/OfferRequestProvider.java
@@ -1,211 +1,211 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smackx.workgroup.MetaData;
-import org.jivesoftware.smackx.workgroup.agent.InvitationRequest;
-import org.jivesoftware.smackx.workgroup.agent.OfferContent;
-import org.jivesoftware.smackx.workgroup.agent.TransferRequest;
-import org.jivesoftware.smackx.workgroup.agent.UserRequest;
-import org.jivesoftware.smackx.workgroup.util.MetaDataUtils;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.jivesoftware.smack.util.PacketParserUtils;
-import org.xmlpull.v1.XmlPullParser;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * An IQProvider for agent offer requests.
- *
- * @author loki der quaeler
- */
-public class OfferRequestProvider implements IQProvider {
-
-    public OfferRequestProvider() {
-    }
-
-    public IQ parseIQ(XmlPullParser parser) throws Exception {
-        int eventType = parser.getEventType();
-        String sessionID = null;
-        int timeout = -1;
-        OfferContent content = null;
-        boolean done = false;
-        Map<String, List<String>> metaData = new HashMap<String, List<String>>();
-
-        if (eventType != XmlPullParser.START_TAG) {
-            // throw exception
-        }
-
-        String userJID = parser.getAttributeValue("", "jid");
-        // Default userID to the JID.
-        String userID = userJID;
-
-        while (!done) {
-            eventType = parser.next();
-
-            if (eventType == XmlPullParser.START_TAG) {
-                String elemName = parser.getName();
-
-                if ("timeout".equals(elemName)) {
-                    timeout = Integer.parseInt(parser.nextText());
-                }
-                else if (MetaData.ELEMENT_NAME.equals(elemName)) {
-                    metaData = MetaDataUtils.parseMetaData(parser);
-                }
-                else if (SessionID.ELEMENT_NAME.equals(elemName)) {
-                   sessionID = parser.getAttributeValue("", "id");
-                }
-                else if (UserID.ELEMENT_NAME.equals(elemName)) {
-                    userID = parser.getAttributeValue("", "id");
-                }
-                else if ("user-request".equals(elemName)) {
-                    content = UserRequest.getInstance();
-                }
-                else if (RoomInvitation.ELEMENT_NAME.equals(elemName)) {
-                    RoomInvitation invitation = (RoomInvitation) PacketParserUtils
-                            .parsePacketExtension(RoomInvitation.ELEMENT_NAME, RoomInvitation.NAMESPACE, parser);
-                    content = new InvitationRequest(invitation.getInviter(), invitation.getRoom(),
-                            invitation.getReason());
-                }
-                else if (RoomTransfer.ELEMENT_NAME.equals(elemName)) {
-                    RoomTransfer transfer = (RoomTransfer) PacketParserUtils
-                            .parsePacketExtension(RoomTransfer.ELEMENT_NAME, RoomTransfer.NAMESPACE, parser);
-                    content = new TransferRequest(transfer.getInviter(), transfer.getRoom(), transfer.getReason());
-                }
-            }
-            else if (eventType == XmlPullParser.END_TAG) {
-                if ("offer".equals(parser.getName())) {
-                    done = true;
-                }
-            }
-        }
-
-        OfferRequestPacket offerRequest =
-                new OfferRequestPacket(userJID, userID, timeout, metaData, sessionID, content);
-        offerRequest.setType(IQ.Type.SET);
-
-        return offerRequest;
-    }
-
-    public static class OfferRequestPacket extends IQ {
-
-        private int timeout;
-        private String userID;
-        private String userJID;
-        private Map<String, List<String>> metaData;
-        private String sessionID;
-        private OfferContent content;
-
-        public OfferRequestPacket(String userJID, String userID, int timeout, Map<String, List<String>> metaData,
-                String sessionID, OfferContent content)
-        {
-            this.userJID = userJID;
-            this.userID = userID;
-            this.timeout = timeout;
-            this.metaData = metaData;
-            this.sessionID = sessionID;
-            this.content = content;
-        }
-
-        /**
-         * Returns the userID, which is either the same as the userJID or a special
-         * value that the user provided as part of their "join queue" request.
-         *
-         * @return the user ID.
-         */
-        public String getUserID() {
-            return userID;
-        }
-
-        /**
-         * The JID of the user that made the "join queue" request.
-         *
-         * @return the user JID.
-         */
-        public String getUserJID() {
-            return userJID;
-        }
-
-        /**
-         * Returns the session ID associated with the request and ensuing chat. If the offer
-         * does not contain a session ID, <tt>null</tt> will be returned.
-         *
-         * @return the session id associated with the request.
-         */
-        public String getSessionID() {
-            return sessionID;
-        }
-
-        /**
-         * Returns the number of seconds the agent has to accept the offer before
-         * it times out.
-         *
-         * @return the offer timeout (in seconds).
-         */
-        public int getTimeout() {
-            return this.timeout;
-        }
-
-        public OfferContent getContent() {
-            return content;
-        }
-
-        /**
-         * Returns any meta-data associated with the offer.
-         *
-         * @return meta-data associated with the offer.
-         */
-        public Map<String, List<String>> getMetaData() {
-            return this.metaData;
-        }
-
-        public String getChildElementXML () {
-            StringBuilder buf = new StringBuilder();
-
-            buf.append("<offer xmlns=\"http://jabber.org/protocol/workgroup\" jid=\"").append(userJID).append("\">");
-            buf.append("<timeout>").append(timeout).append("</timeout>");
-
-            if (sessionID != null) {
-                buf.append('<').append(SessionID.ELEMENT_NAME);
-                buf.append(" session=\"");
-                buf.append(getSessionID()).append("\" xmlns=\"");
-                buf.append(SessionID.NAMESPACE).append("\"/>");
-            }
-
-            if (metaData != null) {
-                buf.append(MetaDataUtils.serializeMetaData(metaData));
-            }
-
-            if (userID != null) {
-                buf.append('<').append(UserID.ELEMENT_NAME);
-                buf.append(" id=\"");
-                buf.append(userID).append("\" xmlns=\"");
-                buf.append(UserID.NAMESPACE).append("\"/>");
-            }
-
-            buf.append("</offer>");
-
-            return buf.toString();
-        }
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smackx.workgroup.MetaData;
+import org.jivesoftware.smackx.workgroup.agent.InvitationRequest;
+import org.jivesoftware.smackx.workgroup.agent.OfferContent;
+import org.jivesoftware.smackx.workgroup.agent.TransferRequest;
+import org.jivesoftware.smackx.workgroup.agent.UserRequest;
+import org.jivesoftware.smackx.workgroup.util.MetaDataUtils;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.jivesoftware.smack.util.PacketParserUtils;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An IQProvider for agent offer requests.
+ *
+ * @author loki der quaeler
+ */
+public class OfferRequestProvider implements IQProvider {
+
+    public OfferRequestProvider() {
+    }
+
+    public IQ parseIQ(XmlPullParser parser) throws Exception {
+        int eventType = parser.getEventType();
+        String sessionID = null;
+        int timeout = -1;
+        OfferContent content = null;
+        boolean done = false;
+        Map<String, List<String>> metaData = new HashMap<String, List<String>>();
+
+        if (eventType != XmlPullParser.START_TAG) {
+            // throw exception
+        }
+
+        String userJID = parser.getAttributeValue("", "jid");
+        // Default userID to the JID.
+        String userID = userJID;
+
+        while (!done) {
+            eventType = parser.next();
+
+            if (eventType == XmlPullParser.START_TAG) {
+                String elemName = parser.getName();
+
+                if ("timeout".equals(elemName)) {
+                    timeout = Integer.parseInt(parser.nextText());
+                }
+                else if (MetaData.ELEMENT_NAME.equals(elemName)) {
+                    metaData = MetaDataUtils.parseMetaData(parser);
+                }
+                else if (SessionID.ELEMENT_NAME.equals(elemName)) {
+                   sessionID = parser.getAttributeValue("", "id");
+                }
+                else if (UserID.ELEMENT_NAME.equals(elemName)) {
+                    userID = parser.getAttributeValue("", "id");
+                }
+                else if ("user-request".equals(elemName)) {
+                    content = UserRequest.getInstance();
+                }
+                else if (RoomInvitation.ELEMENT_NAME.equals(elemName)) {
+                    RoomInvitation invitation = (RoomInvitation) PacketParserUtils
+                            .parsePacketExtension(RoomInvitation.ELEMENT_NAME, RoomInvitation.NAMESPACE, parser);
+                    content = new InvitationRequest(invitation.getInviter(), invitation.getRoom(),
+                            invitation.getReason());
+                }
+                else if (RoomTransfer.ELEMENT_NAME.equals(elemName)) {
+                    RoomTransfer transfer = (RoomTransfer) PacketParserUtils
+                            .parsePacketExtension(RoomTransfer.ELEMENT_NAME, RoomTransfer.NAMESPACE, parser);
+                    content = new TransferRequest(transfer.getInviter(), transfer.getRoom(), transfer.getReason());
+                }
+            }
+            else if (eventType == XmlPullParser.END_TAG) {
+                if ("offer".equals(parser.getName())) {
+                    done = true;
+                }
+            }
+        }
+
+        OfferRequestPacket offerRequest =
+                new OfferRequestPacket(userJID, userID, timeout, metaData, sessionID, content);
+        offerRequest.setType(IQ.Type.SET);
+
+        return offerRequest;
+    }
+
+    public static class OfferRequestPacket extends IQ {
+
+        private int timeout;
+        private String userID;
+        private String userJID;
+        private Map<String, List<String>> metaData;
+        private String sessionID;
+        private OfferContent content;
+
+        public OfferRequestPacket(String userJID, String userID, int timeout, Map<String, List<String>> metaData,
+                String sessionID, OfferContent content)
+        {
+            this.userJID = userJID;
+            this.userID = userID;
+            this.timeout = timeout;
+            this.metaData = metaData;
+            this.sessionID = sessionID;
+            this.content = content;
+        }
+
+        /**
+         * Returns the userID, which is either the same as the userJID or a special
+         * value that the user provided as part of their "join queue" request.
+         *
+         * @return the user ID.
+         */
+        public String getUserID() {
+            return userID;
+        }
+
+        /**
+         * The JID of the user that made the "join queue" request.
+         *
+         * @return the user JID.
+         */
+        public String getUserJID() {
+            return userJID;
+        }
+
+        /**
+         * Returns the session ID associated with the request and ensuing chat. If the offer
+         * does not contain a session ID, <tt>null</tt> will be returned.
+         *
+         * @return the session id associated with the request.
+         */
+        public String getSessionID() {
+            return sessionID;
+        }
+
+        /**
+         * Returns the number of seconds the agent has to accept the offer before
+         * it times out.
+         *
+         * @return the offer timeout (in seconds).
+         */
+        public int getTimeout() {
+            return this.timeout;
+        }
+
+        public OfferContent getContent() {
+            return content;
+        }
+
+        /**
+         * Returns any meta-data associated with the offer.
+         *
+         * @return meta-data associated with the offer.
+         */
+        public Map<String, List<String>> getMetaData() {
+            return this.metaData;
+        }
+
+        public String getChildElementXML () {
+            StringBuilder buf = new StringBuilder();
+
+            buf.append("<offer xmlns=\"http://jabber.org/protocol/workgroup\" jid=\"").append(userJID).append("\">");
+            buf.append("<timeout>").append(timeout).append("</timeout>");
+
+            if (sessionID != null) {
+                buf.append('<').append(SessionID.ELEMENT_NAME);
+                buf.append(" session=\"");
+                buf.append(getSessionID()).append("\" xmlns=\"");
+                buf.append(SessionID.NAMESPACE).append("\"/>");
+            }
+
+            if (metaData != null) {
+                buf.append(MetaDataUtils.serializeMetaData(metaData));
+            }
+
+            if (userID != null) {
+                buf.append('<').append(UserID.ELEMENT_NAME);
+                buf.append(" id=\"");
+                buf.append(userID).append("\" xmlns=\"");
+                buf.append(UserID.NAMESPACE).append("\"/>");
+            }
+
+            buf.append("</offer>");
+
+            return buf.toString();
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/OfferRevokeProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/OfferRevokeProvider.java
index 202824c..b3974b4 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/OfferRevokeProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/OfferRevokeProvider.java
@@ -1,112 +1,112 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * An IQProvider class which has savvy about the offer-revoke tag.<br>
- *
- * @author loki der quaeler
- */
-public class OfferRevokeProvider implements IQProvider {
-
-    public IQ parseIQ (XmlPullParser parser) throws Exception {
-        // The parser will be positioned on the opening IQ tag, so get the JID attribute.
-        String userJID = parser.getAttributeValue("", "jid");
-        // Default the userID to the JID.
-        String userID = userJID;
-        String reason = null;
-        String sessionID = null;
-        boolean done = false;
-
-        while (!done) {
-            int eventType = parser.next();
-
-            if ((eventType == XmlPullParser.START_TAG) && parser.getName().equals("reason")) {
-                reason = parser.nextText();
-            }
-            else if ((eventType == XmlPullParser.START_TAG)
-                         && parser.getName().equals(SessionID.ELEMENT_NAME)) {
-                sessionID = parser.getAttributeValue("", "id");
-            }
-            else if ((eventType == XmlPullParser.START_TAG)
-                         && parser.getName().equals(UserID.ELEMENT_NAME)) {
-                userID = parser.getAttributeValue("", "id");
-            }
-            else if ((eventType == XmlPullParser.END_TAG) && parser.getName().equals(
-                    "offer-revoke"))
-            {
-                done = true;
-            }
-        }
-
-        return new OfferRevokePacket(userJID, userID, reason, sessionID);
-    }
-
-    public class OfferRevokePacket extends IQ {
-
-        private String userJID;
-        private String userID;
-        private String sessionID;
-        private String reason;
-
-        public OfferRevokePacket (String userJID, String userID, String cause, String sessionID) {
-            this.userJID = userJID;
-            this.userID = userID;
-            this.reason = cause;
-            this.sessionID = sessionID;
-        }
-
-        public String getUserJID() {
-            return userJID;
-        }
-
-        public String getUserID() {
-            return this.userID;
-        }
-
-        public String getReason() {
-            return this.reason;
-        }
-
-        public String getSessionID() {
-            return this.sessionID;
-        }
-
-        public String getChildElementXML () {
-            StringBuilder buf = new StringBuilder();
-            buf.append("<offer-revoke xmlns=\"http://jabber.org/protocol/workgroup\" jid=\"").append(userID).append("\">");
-            if (reason != null) {
-                buf.append("<reason>").append(reason).append("</reason>");
-            }
-            if (sessionID != null) {
-                buf.append(new SessionID(sessionID).toXML());
-            }
-            if (userID != null) {
-                buf.append(new UserID(userID).toXML());
-            }
-            buf.append("</offer-revoke>");
-            return buf.toString();
-        }
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * An IQProvider class which has savvy about the offer-revoke tag.<br>
+ *
+ * @author loki der quaeler
+ */
+public class OfferRevokeProvider implements IQProvider {
+
+    public IQ parseIQ (XmlPullParser parser) throws Exception {
+        // The parser will be positioned on the opening IQ tag, so get the JID attribute.
+        String userJID = parser.getAttributeValue("", "jid");
+        // Default the userID to the JID.
+        String userID = userJID;
+        String reason = null;
+        String sessionID = null;
+        boolean done = false;
+
+        while (!done) {
+            int eventType = parser.next();
+
+            if ((eventType == XmlPullParser.START_TAG) && parser.getName().equals("reason")) {
+                reason = parser.nextText();
+            }
+            else if ((eventType == XmlPullParser.START_TAG)
+                         && parser.getName().equals(SessionID.ELEMENT_NAME)) {
+                sessionID = parser.getAttributeValue("", "id");
+            }
+            else if ((eventType == XmlPullParser.START_TAG)
+                         && parser.getName().equals(UserID.ELEMENT_NAME)) {
+                userID = parser.getAttributeValue("", "id");
+            }
+            else if ((eventType == XmlPullParser.END_TAG) && parser.getName().equals(
+                    "offer-revoke"))
+            {
+                done = true;
+            }
+        }
+
+        return new OfferRevokePacket(userJID, userID, reason, sessionID);
+    }
+
+    public class OfferRevokePacket extends IQ {
+
+        private String userJID;
+        private String userID;
+        private String sessionID;
+        private String reason;
+
+        public OfferRevokePacket (String userJID, String userID, String cause, String sessionID) {
+            this.userJID = userJID;
+            this.userID = userID;
+            this.reason = cause;
+            this.sessionID = sessionID;
+        }
+
+        public String getUserJID() {
+            return userJID;
+        }
+
+        public String getUserID() {
+            return this.userID;
+        }
+
+        public String getReason() {
+            return this.reason;
+        }
+
+        public String getSessionID() {
+            return this.sessionID;
+        }
+
+        public String getChildElementXML () {
+            StringBuilder buf = new StringBuilder();
+            buf.append("<offer-revoke xmlns=\"http://jabber.org/protocol/workgroup\" jid=\"").append(userID).append("\">");
+            if (reason != null) {
+                buf.append("<reason>").append(reason).append("</reason>");
+            }
+            if (sessionID != null) {
+                buf.append(new SessionID(sessionID).toXML());
+            }
+            if (userID != null) {
+                buf.append(new UserID(userID).toXML());
+            }
+            buf.append("</offer-revoke>");
+            return buf.toString();
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/QueueDetails.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/QueueDetails.java
index 86b3673..2a7fe3b 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/QueueDetails.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/QueueDetails.java
@@ -1,199 +1,199 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smackx.workgroup.QueueUser;
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * Queue details packet extension, which contains details about the users
- * currently in a queue.
- */
-public class QueueDetails implements PacketExtension {
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "notify-queue-details";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
-
-    private static final String DATE_FORMAT = "yyyyMMdd'T'HH:mm:ss";
-
-    private SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
-    /**
-     * The list of users in the queue.
-     */
-    private Set<QueueUser> users;
-
-    /**
-     * Creates a new QueueDetails packet
-     */
-    private QueueDetails() {
-        users = new HashSet<QueueUser>();
-    }
-
-    /**
-     * Returns the number of users currently in the queue that are waiting to
-     * be routed to an agent.
-     *
-     * @return the number of users in the queue.
-     */
-    public int getUserCount() {
-        return users.size();
-    }
-
-    /**
-     * Returns the set of users in the queue that are waiting to
-     * be routed to an agent (as QueueUser objects).
-     *
-     * @return a Set for the users waiting in a queue.
-     */
-    public Set<QueueUser> getUsers() {
-        synchronized (users) {
-            return users;
-        }
-    }
-
-    /**
-     * Adds a user to the packet.
-     *
-     * @param user the user.
-     */
-    private void addUser(QueueUser user) {
-        synchronized (users) {
-            users.add(user);
-        }
-    }
-
-    public String getElementName() {
-        return ELEMENT_NAME;
-    }
-
-    public String getNamespace() {
-        return NAMESPACE;
-    }
-
-    public String toXML() {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
-
-        synchronized (users) {
-            for (Iterator<QueueUser> i=users.iterator(); i.hasNext(); ) {
-                QueueUser user = (QueueUser)i.next();
-                int position = user.getQueuePosition();
-                int timeRemaining = user.getEstimatedRemainingTime();
-                Date timestamp = user.getQueueJoinTimestamp();
-
-                buf.append("<user jid=\"").append(user.getUserID()).append("\">");
-
-                if (position != -1) {
-                    buf.append("<position>").append(position).append("</position>");
-                }
-
-                if (timeRemaining != -1) {
-                    buf.append("<time>").append(timeRemaining).append("</time>");
-                }
-
-                if (timestamp != null) {
-                    buf.append("<join-time>");
-                    buf.append(dateFormat.format(timestamp));
-                    buf.append("</join-time>");
-                }
-
-                buf.append("</user>");
-            }
-        }
-        buf.append("</").append(ELEMENT_NAME).append(">");
-        return buf.toString();
-    }
-
-    /**
-     * Provider class for QueueDetails packet extensions.
-     */
-    public static class Provider implements PacketExtensionProvider {
-        
-        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
-            
-            SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
-            QueueDetails queueDetails = new QueueDetails();
-
-            int eventType = parser.getEventType();
-            while (eventType != XmlPullParser.END_TAG &&
-                    "notify-queue-details".equals(parser.getName()))
-            {
-                eventType = parser.next();
-                while ((eventType == XmlPullParser.START_TAG) && "user".equals(parser.getName())) {
-                    String uid = null;
-                    int position = -1;
-                    int time = -1;
-                    Date joinTime = null;
-
-                    uid = parser.getAttributeValue("", "jid");
-               
-                    if (uid == null) {
-                        // throw exception
-                    }
-
-                    eventType = parser.next();
-                    while ((eventType != XmlPullParser.END_TAG)
-                                || (! "user".equals(parser.getName())))
-                    {                        
-                        if ("position".equals(parser.getName())) {
-                            position = Integer.parseInt(parser.nextText());
-                        }
-                        else if ("time".equals(parser.getName())) {
-                            time = Integer.parseInt(parser.nextText());
-                        }
-                        else if ("join-time".equals(parser.getName())) {
-                            joinTime = dateFormat.parse(parser.nextText());                            
-                        }
-                        else if( parser.getName().equals( "waitTime" ) ) {
-                            Date wait = dateFormat.parse(parser.nextText());
-                            System.out.println( wait );
-                        }
-
-                        eventType = parser.next();
-
-                        if (eventType != XmlPullParser.END_TAG) {
-                            // throw exception
-                        }
-                    }
-
-                    queueDetails.addUser(new QueueUser(uid, position, time, joinTime));
-
-                    eventType = parser.next();
-                }
-            }
-            return queueDetails;
-        }
-    }
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smackx.workgroup.QueueUser;
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * Queue details packet extension, which contains details about the users
+ * currently in a queue.
+ */
+public class QueueDetails implements PacketExtension {
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "notify-queue-details";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
+
+    private static final String DATE_FORMAT = "yyyyMMdd'T'HH:mm:ss";
+
+    private SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
+    /**
+     * The list of users in the queue.
+     */
+    private Set<QueueUser> users;
+
+    /**
+     * Creates a new QueueDetails packet
+     */
+    private QueueDetails() {
+        users = new HashSet<QueueUser>();
+    }
+
+    /**
+     * Returns the number of users currently in the queue that are waiting to
+     * be routed to an agent.
+     *
+     * @return the number of users in the queue.
+     */
+    public int getUserCount() {
+        return users.size();
+    }
+
+    /**
+     * Returns the set of users in the queue that are waiting to
+     * be routed to an agent (as QueueUser objects).
+     *
+     * @return a Set for the users waiting in a queue.
+     */
+    public Set<QueueUser> getUsers() {
+        synchronized (users) {
+            return users;
+        }
+    }
+
+    /**
+     * Adds a user to the packet.
+     *
+     * @param user the user.
+     */
+    private void addUser(QueueUser user) {
+        synchronized (users) {
+            users.add(user);
+        }
+    }
+
+    public String getElementName() {
+        return ELEMENT_NAME;
+    }
+
+    public String getNamespace() {
+        return NAMESPACE;
+    }
+
+    public String toXML() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
+
+        synchronized (users) {
+            for (Iterator<QueueUser> i=users.iterator(); i.hasNext(); ) {
+                QueueUser user = (QueueUser)i.next();
+                int position = user.getQueuePosition();
+                int timeRemaining = user.getEstimatedRemainingTime();
+                Date timestamp = user.getQueueJoinTimestamp();
+
+                buf.append("<user jid=\"").append(user.getUserID()).append("\">");
+
+                if (position != -1) {
+                    buf.append("<position>").append(position).append("</position>");
+                }
+
+                if (timeRemaining != -1) {
+                    buf.append("<time>").append(timeRemaining).append("</time>");
+                }
+
+                if (timestamp != null) {
+                    buf.append("<join-time>");
+                    buf.append(dateFormat.format(timestamp));
+                    buf.append("</join-time>");
+                }
+
+                buf.append("</user>");
+            }
+        }
+        buf.append("</").append(ELEMENT_NAME).append(">");
+        return buf.toString();
+    }
+
+    /**
+     * Provider class for QueueDetails packet extensions.
+     */
+    public static class Provider implements PacketExtensionProvider {
+        
+        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
+            
+            SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
+            QueueDetails queueDetails = new QueueDetails();
+
+            int eventType = parser.getEventType();
+            while (eventType != XmlPullParser.END_TAG &&
+                    "notify-queue-details".equals(parser.getName()))
+            {
+                eventType = parser.next();
+                while ((eventType == XmlPullParser.START_TAG) && "user".equals(parser.getName())) {
+                    String uid = null;
+                    int position = -1;
+                    int time = -1;
+                    Date joinTime = null;
+
+                    uid = parser.getAttributeValue("", "jid");
+               
+                    if (uid == null) {
+                        // throw exception
+                    }
+
+                    eventType = parser.next();
+                    while ((eventType != XmlPullParser.END_TAG)
+                                || (! "user".equals(parser.getName())))
+                    {                        
+                        if ("position".equals(parser.getName())) {
+                            position = Integer.parseInt(parser.nextText());
+                        }
+                        else if ("time".equals(parser.getName())) {
+                            time = Integer.parseInt(parser.nextText());
+                        }
+                        else if ("join-time".equals(parser.getName())) {
+                            joinTime = dateFormat.parse(parser.nextText());                            
+                        }
+                        else if( parser.getName().equals( "waitTime" ) ) {
+                            Date wait = dateFormat.parse(parser.nextText());
+                            System.out.println( wait );
+                        }
+
+                        eventType = parser.next();
+
+                        if (eventType != XmlPullParser.END_TAG) {
+                            // throw exception
+                        }
+                    }
+
+                    queueDetails.addUser(new QueueUser(uid, position, time, joinTime));
+
+                    eventType = parser.next();
+                }
+            }
+            return queueDetails;
+        }
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/QueueOverview.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/QueueOverview.java
index a559579..c97473c 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/QueueOverview.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/QueueOverview.java
@@ -1,160 +1,160 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smackx.workgroup.agent.WorkgroupQueue;
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-public class QueueOverview implements PacketExtension {
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static String ELEMENT_NAME = "notify-queue";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static String NAMESPACE = "http://jabber.org/protocol/workgroup";
-
-    private static final String DATE_FORMAT = "yyyyMMdd'T'HH:mm:ss";
-    private SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
-
-    private int averageWaitTime;
-    private Date oldestEntry;
-    private int userCount;
-    private WorkgroupQueue.Status status;
-
-    QueueOverview() {
-        this.averageWaitTime = -1;
-        this.oldestEntry = null;
-        this.userCount = -1;
-        this.status = null;
-    }
-
-    void setAverageWaitTime(int averageWaitTime) {
-        this.averageWaitTime = averageWaitTime;
-    }
-
-    public int getAverageWaitTime () {
-        return averageWaitTime;
-    }
-
-    void setOldestEntry(Date oldestEntry) {
-        this.oldestEntry = oldestEntry;
-    }
-
-    public Date getOldestEntry() {
-        return oldestEntry;
-    }
-
-    void setUserCount(int userCount) {
-        this.userCount = userCount;
-    }
-
-    public int getUserCount() {
-        return userCount;
-    }
-
-    public WorkgroupQueue.Status getStatus() {
-        return status;
-    }
-
-    void setStatus(WorkgroupQueue.Status status) {
-        this.status = status;
-    }
-
-    public String getElementName () {
-        return ELEMENT_NAME;
-    }
-
-    public String getNamespace () {
-        return NAMESPACE;
-    }
-
-    public String toXML () {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
-
-        if (userCount != -1) {
-            buf.append("<count>").append(userCount).append("</count>");
-        }
-        if (oldestEntry != null) {
-            buf.append("<oldest>").append(dateFormat.format(oldestEntry)).append("</oldest>");
-        }
-        if (averageWaitTime != -1) {
-            buf.append("<time>").append(averageWaitTime).append("</time>");
-        }
-        if (status != null) {
-            buf.append("<status>").append(status).append("</status>");
-        }
-        buf.append("</").append(ELEMENT_NAME).append(">");
-
-        return buf.toString();
-    }
-
-    public static class Provider implements PacketExtensionProvider {
-
-        public PacketExtension parseExtension (XmlPullParser parser) throws Exception {
-            int eventType = parser.getEventType();
-            QueueOverview queueOverview = new QueueOverview();            
-            SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
-
-            if (eventType != XmlPullParser.START_TAG) {
-                // throw exception
-            }
-
-            eventType = parser.next();
-            while ((eventType != XmlPullParser.END_TAG)
-                         || (!ELEMENT_NAME.equals(parser.getName())))
-            {
-                if ("count".equals(parser.getName())) {
-                    queueOverview.setUserCount(Integer.parseInt(parser.nextText()));
-                }
-                else if ("time".equals(parser.getName())) {
-                    queueOverview.setAverageWaitTime(Integer.parseInt(parser.nextText()));
-                }
-                else if ("oldest".equals(parser.getName())) {
-                    queueOverview.setOldestEntry((dateFormat.parse(parser.nextText())));                    
-                }
-                else if ("status".equals(parser.getName())) {
-                    queueOverview.setStatus(WorkgroupQueue.Status.fromString(parser.nextText()));
-                }
-
-                eventType = parser.next();
-
-                if (eventType != XmlPullParser.END_TAG) {
-                    // throw exception
-                }
-            }
-
-            if (eventType != XmlPullParser.END_TAG) {
-                // throw exception
-            }
-
-            return queueOverview;
-        }
-    }
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smackx.workgroup.agent.WorkgroupQueue;
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class QueueOverview implements PacketExtension {
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static String ELEMENT_NAME = "notify-queue";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static String NAMESPACE = "http://jabber.org/protocol/workgroup";
+
+    private static final String DATE_FORMAT = "yyyyMMdd'T'HH:mm:ss";
+    private SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
+
+    private int averageWaitTime;
+    private Date oldestEntry;
+    private int userCount;
+    private WorkgroupQueue.Status status;
+
+    QueueOverview() {
+        this.averageWaitTime = -1;
+        this.oldestEntry = null;
+        this.userCount = -1;
+        this.status = null;
+    }
+
+    void setAverageWaitTime(int averageWaitTime) {
+        this.averageWaitTime = averageWaitTime;
+    }
+
+    public int getAverageWaitTime () {
+        return averageWaitTime;
+    }
+
+    void setOldestEntry(Date oldestEntry) {
+        this.oldestEntry = oldestEntry;
+    }
+
+    public Date getOldestEntry() {
+        return oldestEntry;
+    }
+
+    void setUserCount(int userCount) {
+        this.userCount = userCount;
+    }
+
+    public int getUserCount() {
+        return userCount;
+    }
+
+    public WorkgroupQueue.Status getStatus() {
+        return status;
+    }
+
+    void setStatus(WorkgroupQueue.Status status) {
+        this.status = status;
+    }
+
+    public String getElementName () {
+        return ELEMENT_NAME;
+    }
+
+    public String getNamespace () {
+        return NAMESPACE;
+    }
+
+    public String toXML () {
+        StringBuilder buf = new StringBuilder();
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
+
+        if (userCount != -1) {
+            buf.append("<count>").append(userCount).append("</count>");
+        }
+        if (oldestEntry != null) {
+            buf.append("<oldest>").append(dateFormat.format(oldestEntry)).append("</oldest>");
+        }
+        if (averageWaitTime != -1) {
+            buf.append("<time>").append(averageWaitTime).append("</time>");
+        }
+        if (status != null) {
+            buf.append("<status>").append(status).append("</status>");
+        }
+        buf.append("</").append(ELEMENT_NAME).append(">");
+
+        return buf.toString();
+    }
+
+    public static class Provider implements PacketExtensionProvider {
+
+        public PacketExtension parseExtension (XmlPullParser parser) throws Exception {
+            int eventType = parser.getEventType();
+            QueueOverview queueOverview = new QueueOverview();            
+            SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
+
+            if (eventType != XmlPullParser.START_TAG) {
+                // throw exception
+            }
+
+            eventType = parser.next();
+            while ((eventType != XmlPullParser.END_TAG)
+                         || (!ELEMENT_NAME.equals(parser.getName())))
+            {
+                if ("count".equals(parser.getName())) {
+                    queueOverview.setUserCount(Integer.parseInt(parser.nextText()));
+                }
+                else if ("time".equals(parser.getName())) {
+                    queueOverview.setAverageWaitTime(Integer.parseInt(parser.nextText()));
+                }
+                else if ("oldest".equals(parser.getName())) {
+                    queueOverview.setOldestEntry((dateFormat.parse(parser.nextText())));                    
+                }
+                else if ("status".equals(parser.getName())) {
+                    queueOverview.setStatus(WorkgroupQueue.Status.fromString(parser.nextText()));
+                }
+
+                eventType = parser.next();
+
+                if (eventType != XmlPullParser.END_TAG) {
+                    // throw exception
+                }
+            }
+
+            if (eventType != XmlPullParser.END_TAG) {
+                // throw exception
+            }
+
+            return queueOverview;
+        }
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/QueueUpdate.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/QueueUpdate.java
index c326a57..828f6bb 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/QueueUpdate.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/QueueUpdate.java
@@ -1,122 +1,122 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * An IQ packet that encapsulates both types of workgroup queue
- * status notifications -- position updates, and estimated time
- * left in the queue updates.
- */
-public class QueueUpdate implements PacketExtension {
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "queue-status";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
-
-    private int position;
-    private int remainingTime;
-
-    public QueueUpdate(int position, int remainingTime) {
-        this.position = position;
-        this.remainingTime = remainingTime;
-    }
-
-    /**
-     * Returns the user's position in the workgroup queue, or -1 if the
-     * value isn't set on this packet.
-     *
-     * @return the position in the workgroup queue.
-     */
-    public int getPosition() {
-        return this.position;
-    }
-
-    /**
-     * Returns the user's estimated time left in the workgroup queue, or
-     * -1 if the value isn't set on this packet.
-     *
-     * @return the estimated time left in the workgroup queue.
-     */
-    public int getRemaingTime() {
-        return remainingTime;
-    }
-
-    public String toXML() {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<queue-status xmlns=\"http://jabber.org/protocol/workgroup\">");
-        if (position != -1) {
-            buf.append("<position>").append(position).append("</position>");
-        }
-        if (remainingTime != -1) {
-            buf.append("<time>").append(remainingTime).append("</time>");
-        }
-        buf.append("</queue-status>");
-        return buf.toString();
-    }
-
-    public String getElementName() {
-        return ELEMENT_NAME;
-    }
-
-    public String getNamespace() {
-        return NAMESPACE;
-    }
-
-    public static class Provider implements PacketExtensionProvider {
-
-        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
-            boolean done = false;
-            int position = -1;
-            int timeRemaining = -1;
-            while (!done) {
-                parser.next();
-                String elementName = parser.getName();
-                if (parser.getEventType() == XmlPullParser.START_TAG && "position".equals(elementName)) {
-                    try {
-                        position = Integer.parseInt(parser.nextText());
-                    }
-                    catch (NumberFormatException nfe) {
-                    }
-                }
-                else if (parser.getEventType() == XmlPullParser.START_TAG && "time".equals(elementName)) {
-                    try {
-                        timeRemaining = Integer.parseInt(parser.nextText());
-                    }
-                    catch (NumberFormatException nfe) {
-                    }
-                }
-                else if (parser.getEventType() == XmlPullParser.END_TAG && "queue-status".equals(elementName)) {
-                    done = true;
-                }
-            }
-            return new QueueUpdate(position, timeRemaining);
-        }
-    }
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * An IQ packet that encapsulates both types of workgroup queue
+ * status notifications -- position updates, and estimated time
+ * left in the queue updates.
+ */
+public class QueueUpdate implements PacketExtension {
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "queue-status";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
+
+    private int position;
+    private int remainingTime;
+
+    public QueueUpdate(int position, int remainingTime) {
+        this.position = position;
+        this.remainingTime = remainingTime;
+    }
+
+    /**
+     * Returns the user's position in the workgroup queue, or -1 if the
+     * value isn't set on this packet.
+     *
+     * @return the position in the workgroup queue.
+     */
+    public int getPosition() {
+        return this.position;
+    }
+
+    /**
+     * Returns the user's estimated time left in the workgroup queue, or
+     * -1 if the value isn't set on this packet.
+     *
+     * @return the estimated time left in the workgroup queue.
+     */
+    public int getRemaingTime() {
+        return remainingTime;
+    }
+
+    public String toXML() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("<queue-status xmlns=\"http://jabber.org/protocol/workgroup\">");
+        if (position != -1) {
+            buf.append("<position>").append(position).append("</position>");
+        }
+        if (remainingTime != -1) {
+            buf.append("<time>").append(remainingTime).append("</time>");
+        }
+        buf.append("</queue-status>");
+        return buf.toString();
+    }
+
+    public String getElementName() {
+        return ELEMENT_NAME;
+    }
+
+    public String getNamespace() {
+        return NAMESPACE;
+    }
+
+    public static class Provider implements PacketExtensionProvider {
+
+        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
+            boolean done = false;
+            int position = -1;
+            int timeRemaining = -1;
+            while (!done) {
+                parser.next();
+                String elementName = parser.getName();
+                if (parser.getEventType() == XmlPullParser.START_TAG && "position".equals(elementName)) {
+                    try {
+                        position = Integer.parseInt(parser.nextText());
+                    }
+                    catch (NumberFormatException nfe) {
+                    }
+                }
+                else if (parser.getEventType() == XmlPullParser.START_TAG && "time".equals(elementName)) {
+                    try {
+                        timeRemaining = Integer.parseInt(parser.nextText());
+                    }
+                    catch (NumberFormatException nfe) {
+                    }
+                }
+                else if (parser.getEventType() == XmlPullParser.END_TAG && "queue-status".equals(elementName)) {
+                    done = true;
+                }
+            }
+            return new QueueUpdate(position, timeRemaining);
+        }
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/RoomInvitation.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/RoomInvitation.java
index 34555de..1a6ec9c 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/RoomInvitation.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/RoomInvitation.java
@@ -1,177 +1,177 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * Packet extension for {@link org.jivesoftware.smackx.workgroup.agent.InvitationRequest}.
- *
- * @author Gaston Dombiak
- */
-public class RoomInvitation implements PacketExtension {
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "invite";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
-
-    /**
-     * Type of entity being invited to a groupchat support session.
-     */
-    private Type type;
-    /**
-     * JID of the entity being invited. The entity could be another agent, user , a queue or a workgroup. In
-     * the case of a queue or a workgroup the server will select the best agent to invite. 
-     */
-    private String invitee;
-    /**
-     * Full JID of the user that sent the invitation.
-     */
-    private String inviter;
-    /**
-     * ID of the session that originated the initial user request.
-     */
-    private String sessionID;
-    /**
-     * JID of the room to join if offer is accepted.
-     */
-    private String room;
-    /**
-     * Text provided by the inviter explaining the reason why the invitee is invited. 
-     */
-    private String reason;
-
-    public RoomInvitation(Type type, String invitee, String sessionID, String reason) {
-        this.type = type;
-        this.invitee = invitee;
-        this.sessionID = sessionID;
-        this.reason = reason;
-    }
-
-    private RoomInvitation() {
-    }
-
-    public String getElementName() {
-        return ELEMENT_NAME;
-    }
-
-    public String getNamespace() {
-        return NAMESPACE;
-    }
-
-    public String getInviter() {
-        return inviter;
-    }
-
-    public String getRoom() {
-        return room;
-    }
-
-    public String getReason() {
-        return reason;
-    }
-
-    public String getSessionID() {
-        return sessionID;
-    }
-
-    public String toXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE);
-        buf.append("\" type=\"").append(type).append("\">");
-        buf.append("<session xmlns=\"http://jivesoftware.com/protocol/workgroup\" id=\"").append(sessionID).append("\"></session>");
-        if (invitee != null) {
-            buf.append("<invitee>").append(invitee).append("</invitee>");
-        }
-        if (inviter != null) {
-            buf.append("<inviter>").append(inviter).append("</inviter>");
-        }
-        if (reason != null) {
-            buf.append("<reason>").append(reason).append("</reason>");
-        }
-        // Add packet extensions, if any are defined.
-        buf.append("</").append(ELEMENT_NAME).append("> ");
-
-        return buf.toString();
-    }
-
-    /**
-     * Type of entity being invited to a groupchat support session.
-     */
-    public static enum Type {
-        /**
-         * A user is being invited to a groupchat support session. The user could be another agent
-         * or just a regular XMPP user.
-         */
-        user,
-        /**
-         * Some agent of the specified queue will be invited to the groupchat support session.
-         */
-        queue,
-        /**
-         * Some agent of the specified workgroup will be invited to the groupchat support session.
-         */
-        workgroup
-    }
-
-    public static class Provider implements PacketExtensionProvider {
-
-        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
-            final RoomInvitation invitation = new RoomInvitation();
-            invitation.type = Type.valueOf(parser.getAttributeValue("", "type"));
-
-            boolean done = false;
-            while (!done) {
-                parser.next();
-                String elementName = parser.getName();
-                if (parser.getEventType() == XmlPullParser.START_TAG) {
-                    if ("session".equals(elementName)) {
-                        invitation.sessionID = parser.getAttributeValue("", "id");
-                    }
-                    else if ("invitee".equals(elementName)) {
-                        invitation.invitee = parser.nextText();
-                    }
-                    else if ("inviter".equals(elementName)) {
-                        invitation.inviter = parser.nextText();
-                    }
-                    else if ("reason".equals(elementName)) {
-                        invitation.reason = parser.nextText();
-                    }
-                    else if ("room".equals(elementName)) {
-                        invitation.room = parser.nextText();
-                    }
-                }
-                else if (parser.getEventType() == XmlPullParser.END_TAG && ELEMENT_NAME.equals(elementName)) {
-                    done = true;
-                }
-            }
-            return invitation;
-        }
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * Packet extension for {@link org.jivesoftware.smackx.workgroup.agent.InvitationRequest}.
+ *
+ * @author Gaston Dombiak
+ */
+public class RoomInvitation implements PacketExtension {
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "invite";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
+
+    /**
+     * Type of entity being invited to a groupchat support session.
+     */
+    private Type type;
+    /**
+     * JID of the entity being invited. The entity could be another agent, user , a queue or a workgroup. In
+     * the case of a queue or a workgroup the server will select the best agent to invite. 
+     */
+    private String invitee;
+    /**
+     * Full JID of the user that sent the invitation.
+     */
+    private String inviter;
+    /**
+     * ID of the session that originated the initial user request.
+     */
+    private String sessionID;
+    /**
+     * JID of the room to join if offer is accepted.
+     */
+    private String room;
+    /**
+     * Text provided by the inviter explaining the reason why the invitee is invited. 
+     */
+    private String reason;
+
+    public RoomInvitation(Type type, String invitee, String sessionID, String reason) {
+        this.type = type;
+        this.invitee = invitee;
+        this.sessionID = sessionID;
+        this.reason = reason;
+    }
+
+    private RoomInvitation() {
+    }
+
+    public String getElementName() {
+        return ELEMENT_NAME;
+    }
+
+    public String getNamespace() {
+        return NAMESPACE;
+    }
+
+    public String getInviter() {
+        return inviter;
+    }
+
+    public String getRoom() {
+        return room;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+
+    public String getSessionID() {
+        return sessionID;
+    }
+
+    public String toXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE);
+        buf.append("\" type=\"").append(type).append("\">");
+        buf.append("<session xmlns=\"http://jivesoftware.com/protocol/workgroup\" id=\"").append(sessionID).append("\"></session>");
+        if (invitee != null) {
+            buf.append("<invitee>").append(invitee).append("</invitee>");
+        }
+        if (inviter != null) {
+            buf.append("<inviter>").append(inviter).append("</inviter>");
+        }
+        if (reason != null) {
+            buf.append("<reason>").append(reason).append("</reason>");
+        }
+        // Add packet extensions, if any are defined.
+        buf.append("</").append(ELEMENT_NAME).append("> ");
+
+        return buf.toString();
+    }
+
+    /**
+     * Type of entity being invited to a groupchat support session.
+     */
+    public static enum Type {
+        /**
+         * A user is being invited to a groupchat support session. The user could be another agent
+         * or just a regular XMPP user.
+         */
+        user,
+        /**
+         * Some agent of the specified queue will be invited to the groupchat support session.
+         */
+        queue,
+        /**
+         * Some agent of the specified workgroup will be invited to the groupchat support session.
+         */
+        workgroup
+    }
+
+    public static class Provider implements PacketExtensionProvider {
+
+        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
+            final RoomInvitation invitation = new RoomInvitation();
+            invitation.type = Type.valueOf(parser.getAttributeValue("", "type"));
+
+            boolean done = false;
+            while (!done) {
+                parser.next();
+                String elementName = parser.getName();
+                if (parser.getEventType() == XmlPullParser.START_TAG) {
+                    if ("session".equals(elementName)) {
+                        invitation.sessionID = parser.getAttributeValue("", "id");
+                    }
+                    else if ("invitee".equals(elementName)) {
+                        invitation.invitee = parser.nextText();
+                    }
+                    else if ("inviter".equals(elementName)) {
+                        invitation.inviter = parser.nextText();
+                    }
+                    else if ("reason".equals(elementName)) {
+                        invitation.reason = parser.nextText();
+                    }
+                    else if ("room".equals(elementName)) {
+                        invitation.room = parser.nextText();
+                    }
+                }
+                else if (parser.getEventType() == XmlPullParser.END_TAG && ELEMENT_NAME.equals(elementName)) {
+                    done = true;
+                }
+            }
+            return invitation;
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/RoomTransfer.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/RoomTransfer.java
index d1e83e2..54362e4 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/RoomTransfer.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/RoomTransfer.java
@@ -1,177 +1,177 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * Packet extension for {@link org.jivesoftware.smackx.workgroup.agent.TransferRequest}.
- *
- * @author Gaston Dombiak
- */
-public class RoomTransfer implements PacketExtension {
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "transfer";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
-
-    /**
-     * Type of entity being invited to a groupchat support session.
-     */
-    private RoomTransfer.Type type;
-    /**
-     * JID of the entity being invited. The entity could be another agent, user , a queue or a workgroup. In
-     * the case of a queue or a workgroup the server will select the best agent to invite.
-     */
-    private String invitee;
-    /**
-     * Full JID of the user that sent the invitation.
-     */
-    private String inviter;
-    /**
-     * ID of the session that originated the initial user request.
-     */
-    private String sessionID;
-    /**
-     * JID of the room to join if offer is accepted.
-     */
-    private String room;
-    /**
-     * Text provided by the inviter explaining the reason why the invitee is invited.
-     */
-    private String reason;
-
-    public RoomTransfer(RoomTransfer.Type type, String invitee, String sessionID, String reason) {
-        this.type = type;
-        this.invitee = invitee;
-        this.sessionID = sessionID;
-        this.reason = reason;
-    }
-
-    private RoomTransfer() {
-    }
-
-    public String getElementName() {
-        return ELEMENT_NAME;
-    }
-
-    public String getNamespace() {
-        return NAMESPACE;
-    }
-
-    public String getInviter() {
-        return inviter;
-    }
-
-    public String getRoom() {
-        return room;
-    }
-
-    public String getReason() {
-        return reason;
-    }
-
-    public String getSessionID() {
-        return sessionID;
-    }
-
-    public String toXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE);
-        buf.append("\" type=\"").append(type).append("\">");
-        buf.append("<session xmlns=\"http://jivesoftware.com/protocol/workgroup\" id=\"").append(sessionID).append("\"></session>");
-        if (invitee != null) {
-            buf.append("<invitee>").append(invitee).append("</invitee>");
-        }
-        if (inviter != null) {
-            buf.append("<inviter>").append(inviter).append("</inviter>");
-        }
-        if (reason != null) {
-            buf.append("<reason>").append(reason).append("</reason>");
-        }
-        // Add packet extensions, if any are defined.
-        buf.append("</").append(ELEMENT_NAME).append("> ");
-
-        return buf.toString();
-    }
-
-    /**
-     * Type of entity being invited to a groupchat support session.
-     */
-    public static enum Type {
-        /**
-         * A user is being invited to a groupchat support session. The user could be another agent
-         * or just a regular XMPP user.
-         */
-        user,
-        /**
-         * Some agent of the specified queue will be invited to the groupchat support session.
-         */
-        queue,
-        /**
-         * Some agent of the specified workgroup will be invited to the groupchat support session.
-         */
-        workgroup
-    }
-
-    public static class Provider implements PacketExtensionProvider {
-
-        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
-            final RoomTransfer invitation = new RoomTransfer();
-            invitation.type = RoomTransfer.Type.valueOf(parser.getAttributeValue("", "type"));
-
-            boolean done = false;
-            while (!done) {
-                parser.next();
-                String elementName = parser.getName();
-                if (parser.getEventType() == XmlPullParser.START_TAG) {
-                    if ("session".equals(elementName)) {
-                        invitation.sessionID = parser.getAttributeValue("", "id");
-                    }
-                    else if ("invitee".equals(elementName)) {
-                        invitation.invitee = parser.nextText();
-                    }
-                    else if ("inviter".equals(elementName)) {
-                        invitation.inviter = parser.nextText();
-                    }
-                    else if ("reason".equals(elementName)) {
-                        invitation.reason = parser.nextText();
-                    }
-                    else if ("room".equals(elementName)) {
-                        invitation.room = parser.nextText();
-                    }
-                }
-                else if (parser.getEventType() == XmlPullParser.END_TAG && ELEMENT_NAME.equals(elementName)) {
-                    done = true;
-                }
-            }
-            return invitation;
-        }
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * Packet extension for {@link org.jivesoftware.smackx.workgroup.agent.TransferRequest}.
+ *
+ * @author Gaston Dombiak
+ */
+public class RoomTransfer implements PacketExtension {
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "transfer";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
+
+    /**
+     * Type of entity being invited to a groupchat support session.
+     */
+    private RoomTransfer.Type type;
+    /**
+     * JID of the entity being invited. The entity could be another agent, user , a queue or a workgroup. In
+     * the case of a queue or a workgroup the server will select the best agent to invite.
+     */
+    private String invitee;
+    /**
+     * Full JID of the user that sent the invitation.
+     */
+    private String inviter;
+    /**
+     * ID of the session that originated the initial user request.
+     */
+    private String sessionID;
+    /**
+     * JID of the room to join if offer is accepted.
+     */
+    private String room;
+    /**
+     * Text provided by the inviter explaining the reason why the invitee is invited.
+     */
+    private String reason;
+
+    public RoomTransfer(RoomTransfer.Type type, String invitee, String sessionID, String reason) {
+        this.type = type;
+        this.invitee = invitee;
+        this.sessionID = sessionID;
+        this.reason = reason;
+    }
+
+    private RoomTransfer() {
+    }
+
+    public String getElementName() {
+        return ELEMENT_NAME;
+    }
+
+    public String getNamespace() {
+        return NAMESPACE;
+    }
+
+    public String getInviter() {
+        return inviter;
+    }
+
+    public String getRoom() {
+        return room;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+
+    public String getSessionID() {
+        return sessionID;
+    }
+
+    public String toXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE);
+        buf.append("\" type=\"").append(type).append("\">");
+        buf.append("<session xmlns=\"http://jivesoftware.com/protocol/workgroup\" id=\"").append(sessionID).append("\"></session>");
+        if (invitee != null) {
+            buf.append("<invitee>").append(invitee).append("</invitee>");
+        }
+        if (inviter != null) {
+            buf.append("<inviter>").append(inviter).append("</inviter>");
+        }
+        if (reason != null) {
+            buf.append("<reason>").append(reason).append("</reason>");
+        }
+        // Add packet extensions, if any are defined.
+        buf.append("</").append(ELEMENT_NAME).append("> ");
+
+        return buf.toString();
+    }
+
+    /**
+     * Type of entity being invited to a groupchat support session.
+     */
+    public static enum Type {
+        /**
+         * A user is being invited to a groupchat support session. The user could be another agent
+         * or just a regular XMPP user.
+         */
+        user,
+        /**
+         * Some agent of the specified queue will be invited to the groupchat support session.
+         */
+        queue,
+        /**
+         * Some agent of the specified workgroup will be invited to the groupchat support session.
+         */
+        workgroup
+    }
+
+    public static class Provider implements PacketExtensionProvider {
+
+        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
+            final RoomTransfer invitation = new RoomTransfer();
+            invitation.type = RoomTransfer.Type.valueOf(parser.getAttributeValue("", "type"));
+
+            boolean done = false;
+            while (!done) {
+                parser.next();
+                String elementName = parser.getName();
+                if (parser.getEventType() == XmlPullParser.START_TAG) {
+                    if ("session".equals(elementName)) {
+                        invitation.sessionID = parser.getAttributeValue("", "id");
+                    }
+                    else if ("invitee".equals(elementName)) {
+                        invitation.invitee = parser.nextText();
+                    }
+                    else if ("inviter".equals(elementName)) {
+                        invitation.inviter = parser.nextText();
+                    }
+                    else if ("reason".equals(elementName)) {
+                        invitation.reason = parser.nextText();
+                    }
+                    else if ("room".equals(elementName)) {
+                        invitation.room = parser.nextText();
+                    }
+                }
+                else if (parser.getEventType() == XmlPullParser.END_TAG && ELEMENT_NAME.equals(elementName)) {
+                    done = true;
+                }
+            }
+            return invitation;
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/SessionID.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/SessionID.java
index bfd7cfd..1930532 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/SessionID.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/SessionID.java
@@ -1,77 +1,77 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-public class SessionID implements PacketExtension {
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "session";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
-
-    private String sessionID;
-
-    public SessionID(String sessionID) {
-        this.sessionID = sessionID;
-    }
-
-    public String getSessionID() {
-        return this.sessionID;
-    }
-
-    public String getElementName() {
-        return ELEMENT_NAME;
-    }
-
-    public String getNamespace() {
-        return NAMESPACE;
-    }
-
-    public String toXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\" ");
-        buf.append("id=\"").append(this.getSessionID());
-        buf.append("\"/>");
-
-        return buf.toString();
-    }
-
-    public static class Provider implements PacketExtensionProvider {
-
-        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
-            String sessionID = parser.getAttributeValue("", "id");
-
-            // Advance to end of extension.
-            parser.next();
-
-            return new SessionID(sessionID);
-        }
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+public class SessionID implements PacketExtension {
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "session";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
+
+    private String sessionID;
+
+    public SessionID(String sessionID) {
+        this.sessionID = sessionID;
+    }
+
+    public String getSessionID() {
+        return this.sessionID;
+    }
+
+    public String getElementName() {
+        return ELEMENT_NAME;
+    }
+
+    public String getNamespace() {
+        return NAMESPACE;
+    }
+
+    public String toXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\" ");
+        buf.append("id=\"").append(this.getSessionID());
+        buf.append("\"/>");
+
+        return buf.toString();
+    }
+
+    public static class Provider implements PacketExtensionProvider {
+
+        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
+            String sessionID = parser.getAttributeValue("", "id");
+
+            // Advance to end of extension.
+            parser.next();
+
+            return new SessionID(sessionID);
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/Transcript.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/Transcript.java
index 7f8f29e..6ccd740 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/Transcript.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/Transcript.java
@@ -1,98 +1,98 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Packet;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Represents the conversation transcript that occured in a group chat room between an Agent
- * and a user that requested assistance. The transcript contains all the Messages that were sent
- * to the room as well as the sent presences. 
- *
- * @author Gaston Dombiak
- */
-public class Transcript extends IQ {
-    private String sessionID;
-    private List<Packet> packets;
-
-    /**
-     * Creates a transcript request for the given sessionID.
-     *
-     * @param sessionID the id of the session to get the conversation transcript.
-     */
-    public Transcript(String sessionID) {
-        this.sessionID = sessionID;
-        this.packets = new ArrayList<Packet>();
-    }
-
-    /**
-     * Creates a new transcript for the given sessionID and list of packets. The list of packets
-     * may include Messages and/or Presences.
-     *
-     * @param sessionID the id of the session that generated this conversation transcript.
-     * @param packets the list of messages and presences send to the room.
-     */
-    public Transcript(String sessionID, List<Packet> packets) {
-        this.sessionID = sessionID;
-        this.packets = packets;
-    }
-
-    /**
-     * Returns id of the session that generated this conversation transcript. The sessionID is a
-     * value generated by the server when a new request is received.
-     *
-     * @return id of the session that generated this conversation transcript.
-     */
-    public String getSessionID() {
-        return sessionID;
-    }
-
-    /**
-     * Returns the list of Messages and Presences that were sent to the room.
-     *
-     * @return the list of Messages and Presences that were sent to the room.
-     */
-    public List<Packet> getPackets() {
-        return Collections.unmodifiableList(packets);
-    }
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<transcript xmlns=\"http://jivesoftware.com/protocol/workgroup\" sessionID=\"")
-                .append(sessionID)
-                .append("\">");
-
-        for (Iterator<Packet> it=packets.iterator(); it.hasNext();) {
-            Packet packet = it.next();
-            buf.append(packet.toXML());
-        }
-
-        buf.append("</transcript>");
-
-        return buf.toString();
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Packet;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Represents the conversation transcript that occured in a group chat room between an Agent
+ * and a user that requested assistance. The transcript contains all the Messages that were sent
+ * to the room as well as the sent presences. 
+ *
+ * @author Gaston Dombiak
+ */
+public class Transcript extends IQ {
+    private String sessionID;
+    private List<Packet> packets;
+
+    /**
+     * Creates a transcript request for the given sessionID.
+     *
+     * @param sessionID the id of the session to get the conversation transcript.
+     */
+    public Transcript(String sessionID) {
+        this.sessionID = sessionID;
+        this.packets = new ArrayList<Packet>();
+    }
+
+    /**
+     * Creates a new transcript for the given sessionID and list of packets. The list of packets
+     * may include Messages and/or Presences.
+     *
+     * @param sessionID the id of the session that generated this conversation transcript.
+     * @param packets the list of messages and presences send to the room.
+     */
+    public Transcript(String sessionID, List<Packet> packets) {
+        this.sessionID = sessionID;
+        this.packets = packets;
+    }
+
+    /**
+     * Returns id of the session that generated this conversation transcript. The sessionID is a
+     * value generated by the server when a new request is received.
+     *
+     * @return id of the session that generated this conversation transcript.
+     */
+    public String getSessionID() {
+        return sessionID;
+    }
+
+    /**
+     * Returns the list of Messages and Presences that were sent to the room.
+     *
+     * @return the list of Messages and Presences that were sent to the room.
+     */
+    public List<Packet> getPackets() {
+        return Collections.unmodifiableList(packets);
+    }
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<transcript xmlns=\"http://jivesoftware.com/protocol/workgroup\" sessionID=\"")
+                .append(sessionID)
+                .append("\">");
+
+        for (Iterator<Packet> it=packets.iterator(); it.hasNext();) {
+            Packet packet = it.next();
+            buf.append(packet.toXML());
+        }
+
+        buf.append("</transcript>");
+
+        return buf.toString();
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/TranscriptProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/TranscriptProvider.java
index 791b06e..0e292ca 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/TranscriptProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/TranscriptProvider.java
@@ -1,66 +1,66 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.provider.IQProvider;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smack.util.PacketParserUtils;
-import org.xmlpull.v1.XmlPullParser;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * An IQProvider for transcripts.
- *
- * @author Gaston Dombiak
- */
-public class TranscriptProvider implements IQProvider {
-
-    public TranscriptProvider() {
-        super();
-    }
-
-    public IQ parseIQ(XmlPullParser parser) throws Exception {
-        String sessionID = parser.getAttributeValue("", "sessionID");
-        List<Packet> packets = new ArrayList<Packet>();
-
-        boolean done = false;
-        while (!done) {
-            int eventType = parser.next();
-            if (eventType == XmlPullParser.START_TAG) {
-                if (parser.getName().equals("message")) {
-                    packets.add(PacketParserUtils.parseMessage(parser));
-                }
-                else if (parser.getName().equals("presence")) {
-                    packets.add(PacketParserUtils.parsePresence(parser));
-                }
-            }
-            else if (eventType == XmlPullParser.END_TAG) {
-                if (parser.getName().equals("transcript")) {
-                    done = true;
-                }
-            }
-        }
-
-        return new Transcript(sessionID, packets);
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.provider.IQProvider;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.util.PacketParserUtils;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An IQProvider for transcripts.
+ *
+ * @author Gaston Dombiak
+ */
+public class TranscriptProvider implements IQProvider {
+
+    public TranscriptProvider() {
+        super();
+    }
+
+    public IQ parseIQ(XmlPullParser parser) throws Exception {
+        String sessionID = parser.getAttributeValue("", "sessionID");
+        List<Packet> packets = new ArrayList<Packet>();
+
+        boolean done = false;
+        while (!done) {
+            int eventType = parser.next();
+            if (eventType == XmlPullParser.START_TAG) {
+                if (parser.getName().equals("message")) {
+                    packets.add(PacketParserUtils.parseMessage(parser));
+                }
+                else if (parser.getName().equals("presence")) {
+                    packets.add(PacketParserUtils.parsePresence(parser));
+                }
+            }
+            else if (eventType == XmlPullParser.END_TAG) {
+                if (parser.getName().equals("transcript")) {
+                    done = true;
+                }
+            }
+        }
+
+        return new Transcript(sessionID, packets);
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/TranscriptSearch.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/TranscriptSearch.java
index 72693c4..d7a3db6 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/TranscriptSearch.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/TranscriptSearch.java
@@ -1,87 +1,87 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.jivesoftware.smack.util.PacketParserUtils;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * IQ packet for retrieving the transcript search form, submiting the completed search form
- * or retrieving the answer of a transcript search.
- *
- * @author Gaston Dombiak
- */
-public class TranscriptSearch extends IQ {
-
-    /**
-    * Element name of the packet extension.
-    */
-   public static final String ELEMENT_NAME = "transcript-search";
-
-   /**
-    * Namespace of the packet extension.
-    */
-   public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
-        // Add packet extensions, if any are defined.
-        buf.append(getExtensionsXML());
-        buf.append("</").append(ELEMENT_NAME).append("> ");
-
-        return buf.toString();
-    }
-
-    /**
-     * An IQProvider for TranscriptSearch packets.
-     *
-     * @author Gaston Dombiak
-     */
-    public static class Provider implements IQProvider {
-
-        public Provider() {
-            super();
-        }
-
-        public IQ parseIQ(XmlPullParser parser) throws Exception {
-            TranscriptSearch answer = new TranscriptSearch();
-
-            boolean done = false;
-            while (!done) {
-                int eventType = parser.next();
-                if (eventType == XmlPullParser.START_TAG) {
-                    // Parse the packet extension
-                    answer.addExtension(PacketParserUtils.parsePacketExtension(parser.getName(), parser.getNamespace(), parser));
-                }
-                else if (eventType == XmlPullParser.END_TAG) {
-                    if (parser.getName().equals(ELEMENT_NAME)) {
-                        done = true;
-                    }
-                }
-            }
-
-            return answer;
-        }
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.jivesoftware.smack.util.PacketParserUtils;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * IQ packet for retrieving the transcript search form, submiting the completed search form
+ * or retrieving the answer of a transcript search.
+ *
+ * @author Gaston Dombiak
+ */
+public class TranscriptSearch extends IQ {
+
+    /**
+    * Element name of the packet extension.
+    */
+   public static final String ELEMENT_NAME = "transcript-search";
+
+   /**
+    * Namespace of the packet extension.
+    */
+   public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
+        // Add packet extensions, if any are defined.
+        buf.append(getExtensionsXML());
+        buf.append("</").append(ELEMENT_NAME).append("> ");
+
+        return buf.toString();
+    }
+
+    /**
+     * An IQProvider for TranscriptSearch packets.
+     *
+     * @author Gaston Dombiak
+     */
+    public static class Provider implements IQProvider {
+
+        public Provider() {
+            super();
+        }
+
+        public IQ parseIQ(XmlPullParser parser) throws Exception {
+            TranscriptSearch answer = new TranscriptSearch();
+
+            boolean done = false;
+            while (!done) {
+                int eventType = parser.next();
+                if (eventType == XmlPullParser.START_TAG) {
+                    // Parse the packet extension
+                    answer.addExtension(PacketParserUtils.parsePacketExtension(parser.getName(), parser.getNamespace(), parser));
+                }
+                else if (eventType == XmlPullParser.END_TAG) {
+                    if (parser.getName().equals(ELEMENT_NAME)) {
+                        done = true;
+                    }
+                }
+            }
+
+            return answer;
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/Transcripts.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/Transcripts.java
index 66ddaad..86311c9 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/Transcripts.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/Transcripts.java
@@ -1,247 +1,247 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.packet.IQ;
-
-import java.text.SimpleDateFormat;
-import java.util.*;
-
-/**
- * Represents a list of conversation transcripts that a user had in all his history. Each
- * transcript summary includes the sessionID which may be used for getting more detailed
- * information about the conversation. {@link org.jivesoftware.smackx.workgroup.packet.Transcript}
- *
- * @author Gaston Dombiak
- */
-public class Transcripts extends IQ {
-
-    private static final SimpleDateFormat UTC_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
-    static {
-        UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+0"));
-    }
-
-    private String userID;
-    private List<Transcripts.TranscriptSummary> summaries;
-
-
-    /**
-     * Creates a transcripts request for the given userID.
-     *
-     * @param userID the id of the user to get his conversations transcripts.
-     */
-    public Transcripts(String userID) {
-        this.userID = userID;
-        this.summaries = new ArrayList<Transcripts.TranscriptSummary>();
-    }
-
-    /**
-     * Creates a Transcripts which will contain the transcript summaries of the given user.
-     *
-     * @param userID the id of the user. Could be a real JID or a unique String that identifies
-     *        anonymous users.
-     * @param summaries the list of TranscriptSummaries.
-     */
-    public Transcripts(String userID, List<Transcripts.TranscriptSummary> summaries) {
-        this.userID = userID;
-        this.summaries = summaries;
-    }
-
-    /**
-     * Returns the id of the user that was involved in the conversations. The userID could be a
-     * real JID if the connected user was not anonymous. Otherwise, the userID will be a String
-     * that was provided by the anonymous user as a way to idenitify the user across many user
-     * sessions.
-     *
-     * @return the id of the user that was involved in the conversations.
-     */
-    public String getUserID() {
-        return userID;
-    }
-
-    /**
-     * Returns a list of TranscriptSummary. A TranscriptSummary does not contain the conversation
-     * transcript but some summary information like the sessionID and the time when the
-     * conversation started and finished. Once you have the sessionID it is possible to get the
-     * full conversation transcript.
-     *
-     * @return a list of TranscriptSummary.
-     */
-    public List<Transcripts.TranscriptSummary> getSummaries() {
-        return Collections.unmodifiableList(summaries);
-    }
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<transcripts xmlns=\"http://jivesoftware.com/protocol/workgroup\" userID=\"")
-                .append(userID)
-                .append("\">");
-
-        for (TranscriptSummary transcriptSummary : summaries) {
-            buf.append(transcriptSummary.toXML());
-        }
-
-        buf.append("</transcripts>");
-
-        return buf.toString();
-    }
-
-    /**
-     * A TranscriptSummary contains some information about a conversation such as the ID of the
-     * session or the date when the conversation started and finished. You will need to use the
-     * sessionID to get the full conversation transcript.
-     */
-    public static class TranscriptSummary {
-        private String sessionID;
-        private Date joinTime;
-        private Date leftTime;
-        private List<AgentDetail> agentDetails;
-
-        public TranscriptSummary(String sessionID, Date joinTime, Date leftTime, List<AgentDetail> agentDetails) {
-            this.sessionID = sessionID;
-            this.joinTime = joinTime;
-            this.leftTime = leftTime;
-            this.agentDetails = agentDetails;
-        }
-
-        /**
-         * Returns the ID of the session that is related to this conversation transcript. The
-         * sessionID could be used for getting the full conversation transcript.
-         *
-         * @return the ID of the session that is related to this conversation transcript.
-         */
-        public String getSessionID() {
-            return sessionID;
-        }
-
-        /**
-         * Returns the Date when the conversation started.
-         *
-         * @return the Date when the conversation started.
-         */
-        public Date getJoinTime() {
-            return joinTime;
-        }
-
-        /**
-         * Returns the Date when the conversation finished.
-         *
-         * @return the Date when the conversation finished.
-         */
-        public Date getLeftTime() {
-            return leftTime;
-        }
-
-        /**
-         * Returns a list of AgentDetails. For each Agent that was involved in the conversation
-         * the list will include an AgentDetail. An AgentDetail contains the JID of the agent
-         * as well as the time when the Agent joined and left the conversation.
-         *
-         * @return a list of AgentDetails.
-         */
-        public List<AgentDetail> getAgentDetails() {
-            return agentDetails;
-        }
-
-        public String toXML() {
-            StringBuilder buf = new StringBuilder();
-
-            buf.append("<transcript sessionID=\"")
-                    .append(sessionID)
-                    .append("\">");
-
-            if (joinTime != null) {
-                buf.append("<joinTime>").append(UTC_FORMAT.format(joinTime)).append("</joinTime>");
-            }
-            if (leftTime != null) {
-                buf.append("<leftTime>").append(UTC_FORMAT.format(leftTime)).append("</leftTime>");
-            }
-            buf.append("<agents>");
-            for (AgentDetail agentDetail : agentDetails) {
-                buf.append(agentDetail.toXML());
-            }
-            buf.append("</agents></transcript>");
-
-            return buf.toString();
-        }
-    }
-
-    /**
-     * An AgentDetail contains information of an Agent that was involved in a conversation. 
-     */
-    public static class AgentDetail {
-        private String agentJID;
-        private Date joinTime;
-        private Date leftTime;
-
-        public AgentDetail(String agentJID, Date joinTime, Date leftTime) {
-            this.agentJID = agentJID;
-            this.joinTime = joinTime;
-            this.leftTime = leftTime;
-        }
-
-        /**
-         * Returns the bare JID of the Agent that was involved in the conversation.
-         *
-         * @return the bared JID of the Agent that was involved in the conversation.
-         */
-        public String getAgentJID() {
-            return agentJID;
-        }
-
-        /**
-         * Returns the Date when the Agent joined the conversation.
-         *
-         * @return the Date when the Agent joined the conversation.
-         */
-        public Date getJoinTime() {
-            return joinTime;
-        }
-
-        /**
-         * Returns the Date when the Agent left the conversation.
-         *
-         * @return the Date when the Agent left the conversation.
-         */
-        public Date getLeftTime() {
-            return leftTime;
-        }
-
-        public String toXML() {
-            StringBuilder buf = new StringBuilder();
-
-            buf.append("<agent>");
-
-            if (agentJID != null) {
-                buf.append("<agentJID>").append(agentJID).append("</agentJID>");
-            }
-            if (joinTime != null) {
-                buf.append("<joinTime>").append(UTC_FORMAT.format(joinTime)).append("</joinTime>");
-            }
-            if (leftTime != null) {
-                buf.append("<leftTime>").append(UTC_FORMAT.format(leftTime)).append("</leftTime>");
-            }
-            buf.append("</agent>");
-
-            return buf.toString();
-        }
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.packet.IQ;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * Represents a list of conversation transcripts that a user had in all his history. Each
+ * transcript summary includes the sessionID which may be used for getting more detailed
+ * information about the conversation. {@link org.jivesoftware.smackx.workgroup.packet.Transcript}
+ *
+ * @author Gaston Dombiak
+ */
+public class Transcripts extends IQ {
+
+    private static final SimpleDateFormat UTC_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
+    static {
+        UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+0"));
+    }
+
+    private String userID;
+    private List<Transcripts.TranscriptSummary> summaries;
+
+
+    /**
+     * Creates a transcripts request for the given userID.
+     *
+     * @param userID the id of the user to get his conversations transcripts.
+     */
+    public Transcripts(String userID) {
+        this.userID = userID;
+        this.summaries = new ArrayList<Transcripts.TranscriptSummary>();
+    }
+
+    /**
+     * Creates a Transcripts which will contain the transcript summaries of the given user.
+     *
+     * @param userID the id of the user. Could be a real JID or a unique String that identifies
+     *        anonymous users.
+     * @param summaries the list of TranscriptSummaries.
+     */
+    public Transcripts(String userID, List<Transcripts.TranscriptSummary> summaries) {
+        this.userID = userID;
+        this.summaries = summaries;
+    }
+
+    /**
+     * Returns the id of the user that was involved in the conversations. The userID could be a
+     * real JID if the connected user was not anonymous. Otherwise, the userID will be a String
+     * that was provided by the anonymous user as a way to idenitify the user across many user
+     * sessions.
+     *
+     * @return the id of the user that was involved in the conversations.
+     */
+    public String getUserID() {
+        return userID;
+    }
+
+    /**
+     * Returns a list of TranscriptSummary. A TranscriptSummary does not contain the conversation
+     * transcript but some summary information like the sessionID and the time when the
+     * conversation started and finished. Once you have the sessionID it is possible to get the
+     * full conversation transcript.
+     *
+     * @return a list of TranscriptSummary.
+     */
+    public List<Transcripts.TranscriptSummary> getSummaries() {
+        return Collections.unmodifiableList(summaries);
+    }
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<transcripts xmlns=\"http://jivesoftware.com/protocol/workgroup\" userID=\"")
+                .append(userID)
+                .append("\">");
+
+        for (TranscriptSummary transcriptSummary : summaries) {
+            buf.append(transcriptSummary.toXML());
+        }
+
+        buf.append("</transcripts>");
+
+        return buf.toString();
+    }
+
+    /**
+     * A TranscriptSummary contains some information about a conversation such as the ID of the
+     * session or the date when the conversation started and finished. You will need to use the
+     * sessionID to get the full conversation transcript.
+     */
+    public static class TranscriptSummary {
+        private String sessionID;
+        private Date joinTime;
+        private Date leftTime;
+        private List<AgentDetail> agentDetails;
+
+        public TranscriptSummary(String sessionID, Date joinTime, Date leftTime, List<AgentDetail> agentDetails) {
+            this.sessionID = sessionID;
+            this.joinTime = joinTime;
+            this.leftTime = leftTime;
+            this.agentDetails = agentDetails;
+        }
+
+        /**
+         * Returns the ID of the session that is related to this conversation transcript. The
+         * sessionID could be used for getting the full conversation transcript.
+         *
+         * @return the ID of the session that is related to this conversation transcript.
+         */
+        public String getSessionID() {
+            return sessionID;
+        }
+
+        /**
+         * Returns the Date when the conversation started.
+         *
+         * @return the Date when the conversation started.
+         */
+        public Date getJoinTime() {
+            return joinTime;
+        }
+
+        /**
+         * Returns the Date when the conversation finished.
+         *
+         * @return the Date when the conversation finished.
+         */
+        public Date getLeftTime() {
+            return leftTime;
+        }
+
+        /**
+         * Returns a list of AgentDetails. For each Agent that was involved in the conversation
+         * the list will include an AgentDetail. An AgentDetail contains the JID of the agent
+         * as well as the time when the Agent joined and left the conversation.
+         *
+         * @return a list of AgentDetails.
+         */
+        public List<AgentDetail> getAgentDetails() {
+            return agentDetails;
+        }
+
+        public String toXML() {
+            StringBuilder buf = new StringBuilder();
+
+            buf.append("<transcript sessionID=\"")
+                    .append(sessionID)
+                    .append("\">");
+
+            if (joinTime != null) {
+                buf.append("<joinTime>").append(UTC_FORMAT.format(joinTime)).append("</joinTime>");
+            }
+            if (leftTime != null) {
+                buf.append("<leftTime>").append(UTC_FORMAT.format(leftTime)).append("</leftTime>");
+            }
+            buf.append("<agents>");
+            for (AgentDetail agentDetail : agentDetails) {
+                buf.append(agentDetail.toXML());
+            }
+            buf.append("</agents></transcript>");
+
+            return buf.toString();
+        }
+    }
+
+    /**
+     * An AgentDetail contains information of an Agent that was involved in a conversation. 
+     */
+    public static class AgentDetail {
+        private String agentJID;
+        private Date joinTime;
+        private Date leftTime;
+
+        public AgentDetail(String agentJID, Date joinTime, Date leftTime) {
+            this.agentJID = agentJID;
+            this.joinTime = joinTime;
+            this.leftTime = leftTime;
+        }
+
+        /**
+         * Returns the bare JID of the Agent that was involved in the conversation.
+         *
+         * @return the bared JID of the Agent that was involved in the conversation.
+         */
+        public String getAgentJID() {
+            return agentJID;
+        }
+
+        /**
+         * Returns the Date when the Agent joined the conversation.
+         *
+         * @return the Date when the Agent joined the conversation.
+         */
+        public Date getJoinTime() {
+            return joinTime;
+        }
+
+        /**
+         * Returns the Date when the Agent left the conversation.
+         *
+         * @return the Date when the Agent left the conversation.
+         */
+        public Date getLeftTime() {
+            return leftTime;
+        }
+
+        public String toXML() {
+            StringBuilder buf = new StringBuilder();
+
+            buf.append("<agent>");
+
+            if (agentJID != null) {
+                buf.append("<agentJID>").append(agentJID).append("</agentJID>");
+            }
+            if (joinTime != null) {
+                buf.append("<joinTime>").append(UTC_FORMAT.format(joinTime)).append("</joinTime>");
+            }
+            if (leftTime != null) {
+                buf.append("<leftTime>").append(UTC_FORMAT.format(leftTime)).append("</leftTime>");
+            }
+            buf.append("</agent>");
+
+            return buf.toString();
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/TranscriptsProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/TranscriptsProvider.java
index cb8f429..c0ef7a8 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/TranscriptsProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/TranscriptsProvider.java
@@ -1,148 +1,148 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.TimeZone;
-
-/**
- * An IQProvider for transcripts summaries.
- *
- * @author Gaston Dombiak
- */
-public class TranscriptsProvider implements IQProvider {
-
-    private static final SimpleDateFormat UTC_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
-    static {
-        UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+0"));
-    }
-
-    public TranscriptsProvider() {
-        super();
-    }
-
-    public IQ parseIQ(XmlPullParser parser) throws Exception {
-        String userID = parser.getAttributeValue("", "userID");
-        List<Transcripts.TranscriptSummary> summaries = new ArrayList<Transcripts.TranscriptSummary>();
-
-        boolean done = false;
-        while (!done) {
-            int eventType = parser.next();
-            if (eventType == XmlPullParser.START_TAG) {
-                if (parser.getName().equals("transcript")) {
-                    summaries.add(parseSummary(parser));
-                }
-            }
-            else if (eventType == XmlPullParser.END_TAG) {
-                if (parser.getName().equals("transcripts")) {
-                    done = true;
-                }
-            }
-        }
-
-        return new Transcripts(userID, summaries);
-    }
-
-    private Transcripts.TranscriptSummary parseSummary(XmlPullParser parser) throws IOException,
-            XmlPullParserException {
-        String sessionID =  parser.getAttributeValue("", "sessionID");
-        Date joinTime = null;
-        Date leftTime = null;
-        List<Transcripts.AgentDetail> agents = new ArrayList<Transcripts.AgentDetail>();
-
-        boolean done = false;
-        while (!done) {
-            int eventType = parser.next();
-            if (eventType == XmlPullParser.START_TAG) {
-                if (parser.getName().equals("joinTime")) {
-                    try {
-                        joinTime = UTC_FORMAT.parse(parser.nextText());
-                    } catch (ParseException e) {}
-                }
-                else if (parser.getName().equals("leftTime")) {
-                    try {
-                        leftTime = UTC_FORMAT.parse(parser.nextText());
-                    } catch (ParseException e) {}
-                }
-                else if (parser.getName().equals("agents")) {
-                    agents = parseAgents(parser);
-                }
-            }
-            else if (eventType == XmlPullParser.END_TAG) {
-                if (parser.getName().equals("transcript")) {
-                    done = true;
-                }
-            }
-        }
-
-        return new Transcripts.TranscriptSummary(sessionID, joinTime, leftTime, agents);
-    }
-
-    private List<Transcripts.AgentDetail> parseAgents(XmlPullParser parser) throws IOException, XmlPullParserException {
-        List<Transcripts.AgentDetail> agents = new ArrayList<Transcripts.AgentDetail>();
-        String agentJID =  null;
-        Date joinTime = null;
-        Date leftTime = null;
-
-        boolean done = false;
-        while (!done) {
-            int eventType = parser.next();
-            if (eventType == XmlPullParser.START_TAG) {
-                if (parser.getName().equals("agentJID")) {
-                    agentJID = parser.nextText();
-                }
-                else if (parser.getName().equals("joinTime")) {
-                    try {
-                        joinTime = UTC_FORMAT.parse(parser.nextText());
-                    } catch (ParseException e) {}
-                }
-                else if (parser.getName().equals("leftTime")) {
-                    try {
-                        leftTime = UTC_FORMAT.parse(parser.nextText());
-                    } catch (ParseException e) {}
-                }
-                else if (parser.getName().equals("agent")) {
-                    agentJID =  null;
-                    joinTime = null;
-                    leftTime = null;
-                }
-            }
-            else if (eventType == XmlPullParser.END_TAG) {
-                if (parser.getName().equals("agents")) {
-                    done = true;
-                }
-                else if (parser.getName().equals("agent")) {
-                    agents.add(new Transcripts.AgentDetail(agentJID, joinTime, leftTime));
-                }
-            }
-        }
-        return agents;
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.TimeZone;
+
+/**
+ * An IQProvider for transcripts summaries.
+ *
+ * @author Gaston Dombiak
+ */
+public class TranscriptsProvider implements IQProvider {
+
+    private static final SimpleDateFormat UTC_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
+    static {
+        UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+0"));
+    }
+
+    public TranscriptsProvider() {
+        super();
+    }
+
+    public IQ parseIQ(XmlPullParser parser) throws Exception {
+        String userID = parser.getAttributeValue("", "userID");
+        List<Transcripts.TranscriptSummary> summaries = new ArrayList<Transcripts.TranscriptSummary>();
+
+        boolean done = false;
+        while (!done) {
+            int eventType = parser.next();
+            if (eventType == XmlPullParser.START_TAG) {
+                if (parser.getName().equals("transcript")) {
+                    summaries.add(parseSummary(parser));
+                }
+            }
+            else if (eventType == XmlPullParser.END_TAG) {
+                if (parser.getName().equals("transcripts")) {
+                    done = true;
+                }
+            }
+        }
+
+        return new Transcripts(userID, summaries);
+    }
+
+    private Transcripts.TranscriptSummary parseSummary(XmlPullParser parser) throws IOException,
+            XmlPullParserException {
+        String sessionID =  parser.getAttributeValue("", "sessionID");
+        Date joinTime = null;
+        Date leftTime = null;
+        List<Transcripts.AgentDetail> agents = new ArrayList<Transcripts.AgentDetail>();
+
+        boolean done = false;
+        while (!done) {
+            int eventType = parser.next();
+            if (eventType == XmlPullParser.START_TAG) {
+                if (parser.getName().equals("joinTime")) {
+                    try {
+                        joinTime = UTC_FORMAT.parse(parser.nextText());
+                    } catch (ParseException e) {}
+                }
+                else if (parser.getName().equals("leftTime")) {
+                    try {
+                        leftTime = UTC_FORMAT.parse(parser.nextText());
+                    } catch (ParseException e) {}
+                }
+                else if (parser.getName().equals("agents")) {
+                    agents = parseAgents(parser);
+                }
+            }
+            else if (eventType == XmlPullParser.END_TAG) {
+                if (parser.getName().equals("transcript")) {
+                    done = true;
+                }
+            }
+        }
+
+        return new Transcripts.TranscriptSummary(sessionID, joinTime, leftTime, agents);
+    }
+
+    private List<Transcripts.AgentDetail> parseAgents(XmlPullParser parser) throws IOException, XmlPullParserException {
+        List<Transcripts.AgentDetail> agents = new ArrayList<Transcripts.AgentDetail>();
+        String agentJID =  null;
+        Date joinTime = null;
+        Date leftTime = null;
+
+        boolean done = false;
+        while (!done) {
+            int eventType = parser.next();
+            if (eventType == XmlPullParser.START_TAG) {
+                if (parser.getName().equals("agentJID")) {
+                    agentJID = parser.nextText();
+                }
+                else if (parser.getName().equals("joinTime")) {
+                    try {
+                        joinTime = UTC_FORMAT.parse(parser.nextText());
+                    } catch (ParseException e) {}
+                }
+                else if (parser.getName().equals("leftTime")) {
+                    try {
+                        leftTime = UTC_FORMAT.parse(parser.nextText());
+                    } catch (ParseException e) {}
+                }
+                else if (parser.getName().equals("agent")) {
+                    agentJID =  null;
+                    joinTime = null;
+                    leftTime = null;
+                }
+            }
+            else if (eventType == XmlPullParser.END_TAG) {
+                if (parser.getName().equals("agents")) {
+                    done = true;
+                }
+                else if (parser.getName().equals("agent")) {
+                    agents.add(new Transcripts.AgentDetail(agentJID, joinTime, leftTime));
+                }
+            }
+        }
+        return agents;
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/UserID.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/UserID.java
index 8bf4589..4d50abf 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/UserID.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/UserID.java
@@ -1,77 +1,77 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-public class UserID implements PacketExtension {
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "user";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
-
-    private String userID;
-
-    public UserID(String userID) {
-        this.userID = userID;
-    }
-
-    public String getUserID() {
-        return this.userID;
-    }
-
-    public String getElementName() {
-        return ELEMENT_NAME;
-    }
-
-    public String getNamespace() {
-        return NAMESPACE;
-    }
-
-    public String toXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\" ");
-        buf.append("id=\"").append(this.getUserID());
-        buf.append("\"/>");
-
-        return buf.toString();
-    }
-
-    public static class Provider implements PacketExtensionProvider {
-
-        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
-            String userID = parser.getAttributeValue("", "id");
-
-            // Advance to end of extension.
-            parser.next();
-
-            return new UserID(userID);
-        }
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+public class UserID implements PacketExtension {
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "user";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
+
+    private String userID;
+
+    public UserID(String userID) {
+        this.userID = userID;
+    }
+
+    public String getUserID() {
+        return this.userID;
+    }
+
+    public String getElementName() {
+        return ELEMENT_NAME;
+    }
+
+    public String getNamespace() {
+        return NAMESPACE;
+    }
+
+    public String toXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\" ");
+        buf.append("id=\"").append(this.getUserID());
+        buf.append("\"/>");
+
+        return buf.toString();
+    }
+
+    public static class Provider implements PacketExtensionProvider {
+
+        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
+            String userID = parser.getAttributeValue("", "id");
+
+            // Advance to end of extension.
+            parser.next();
+
+            return new UserID(userID);
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/WorkgroupInformation.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/WorkgroupInformation.java
index b0ea447..87086bd 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/WorkgroupInformation.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/packet/WorkgroupInformation.java
@@ -1,86 +1,86 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.packet;
-
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * A packet extension that contains information about the user and agent in a
- * workgroup chat. The packet extension is attached to group chat invitations.
- */
-public class WorkgroupInformation implements PacketExtension {
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "workgroup";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
-
-    private String workgroupJID;
-
-    public WorkgroupInformation(String workgroupJID){
-        this.workgroupJID = workgroupJID;
-    }
-
-    public String getWorkgroupJID() {
-        return workgroupJID;
-    }
-
-    public String getElementName() {
-        return ELEMENT_NAME;
-    }
-
-    public String getNamespace() {
-        return NAMESPACE;
-    }
-
-    public String toXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append('<').append(ELEMENT_NAME);
-        buf.append(" jid=\"").append(getWorkgroupJID()).append("\"");
-        buf.append(" xmlns=\"").append(NAMESPACE).append("\" />");
-
-        return buf.toString();
-    }
-
-    public static class Provider implements PacketExtensionProvider {
-
-        /**
-         * PacketExtensionProvider implementation
-         */
-        public PacketExtension parseExtension (XmlPullParser parser)
-            throws Exception {
-            String workgroupJID = parser.getAttributeValue("", "jid");
-
-            // since this is a start and end tag, and we arrive on the start, this should guarantee
-            //      we leave on the end
-            parser.next();
-
-            return new WorkgroupInformation(workgroupJID);
-        }
-    }
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.packet;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * A packet extension that contains information about the user and agent in a
+ * workgroup chat. The packet extension is attached to group chat invitations.
+ */
+public class WorkgroupInformation implements PacketExtension {
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "workgroup";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
+
+    private String workgroupJID;
+
+    public WorkgroupInformation(String workgroupJID){
+        this.workgroupJID = workgroupJID;
+    }
+
+    public String getWorkgroupJID() {
+        return workgroupJID;
+    }
+
+    public String getElementName() {
+        return ELEMENT_NAME;
+    }
+
+    public String getNamespace() {
+        return NAMESPACE;
+    }
+
+    public String toXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append('<').append(ELEMENT_NAME);
+        buf.append(" jid=\"").append(getWorkgroupJID()).append("\"");
+        buf.append(" xmlns=\"").append(NAMESPACE).append("\" />");
+
+        return buf.toString();
+    }
+
+    public static class Provider implements PacketExtensionProvider {
+
+        /**
+         * PacketExtensionProvider implementation
+         */
+        public PacketExtension parseExtension (XmlPullParser parser)
+            throws Exception {
+            String workgroupJID = parser.getAttributeValue("", "jid");
+
+            // since this is a start and end tag, and we arrive on the start, this should guarantee
+            //      we leave on the end
+            parser.next();
+
+            return new WorkgroupInformation(workgroupJID);
+        }
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/settings/ChatSetting.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/settings/ChatSetting.java
index 921134a..30674a1 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/settings/ChatSetting.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/settings/ChatSetting.java
@@ -1,56 +1,56 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.settings;
-
-public class ChatSetting {
-    private String key;
-    private String value;
-    private int type;
-
-    public ChatSetting(String key, String value, int type){
-        setKey(key);
-        setValue(value);
-        setType(type);
-    }
-
-    public String getKey() {
-        return key;
-    }
-
-    public void setKey(String key) {
-        this.key = key;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
-
-    public int getType() {
-        return type;
-    }
-
-    public void setType(int type) {
-        this.type = type;
-    }
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.settings;
+
+public class ChatSetting {
+    private String key;
+    private String value;
+    private int type;
+
+    public ChatSetting(String key, String value, int type){
+        setKey(key);
+        setValue(value);
+        setType(type);
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public int getType() {
+        return type;
+    }
+
+    public void setType(int type) {
+        this.type = type;
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/settings/ChatSettings.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/settings/ChatSettings.java
index ccc7a40..eec5884 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/settings/ChatSettings.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/settings/ChatSettings.java
@@ -1,179 +1,179 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.settings;
-
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-public class ChatSettings extends IQ {
-
-    /**
-     * Defined as image type.
-     */
-    public static final int IMAGE_SETTINGS = 0;
-
-    /**
-     * Defined as Text settings type.
-     */
-    public static final int TEXT_SETTINGS = 1;
-
-    /**
-     * Defined as Bot settings type.
-     */
-    public static final int BOT_SETTINGS = 2;
-
-    private List<ChatSetting> settings;
-    private String key;
-    private int type = -1;
-
-    public ChatSettings() {
-        settings = new ArrayList<ChatSetting>();
-    }
-
-    public ChatSettings(String key) {
-        setKey(key);
-    }
-
-    public void setKey(String key) {
-        this.key = key;
-    }
-
-    public void setType(int type) {
-        this.type = type;
-    }
-
-    public void addSetting(ChatSetting setting) {
-        settings.add(setting);
-    }
-
-    public Collection<ChatSetting> getSettings() {
-        return settings;
-    }
-
-    public ChatSetting getChatSetting(String key) {
-        Collection<ChatSetting> col = getSettings();
-        if (col != null) {
-            Iterator<ChatSetting> iter = col.iterator();
-            while (iter.hasNext()) {
-                ChatSetting chatSetting = iter.next();
-                if (chatSetting.getKey().equals(key)) {
-                    return chatSetting;
-                }
-            }
-        }
-        return null;
-    }
-
-    public ChatSetting getFirstEntry() {
-        if (settings.size() > 0) {
-            return (ChatSetting)settings.get(0);
-        }
-        return null;
-    }
-
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "chat-settings";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=");
-        buf.append('"');
-        buf.append(NAMESPACE);
-        buf.append('"');
-        if (key != null) {
-            buf.append(" key=\"" + key + "\"");
-        }
-
-        if (type != -1) {
-            buf.append(" type=\"" + type + "\"");
-        }
-
-        buf.append("></").append(ELEMENT_NAME).append("> ");
-        return buf.toString();
-    }
-
-    /**
-     * Packet extension provider for AgentStatusRequest packets.
-     */
-    public static class InternalProvider implements IQProvider {
-
-        public IQ parseIQ(XmlPullParser parser) throws Exception {
-            if (parser.getEventType() != XmlPullParser.START_TAG) {
-                throw new IllegalStateException("Parser not in proper position, or bad XML.");
-            }
-
-            ChatSettings chatSettings = new ChatSettings();
-
-            boolean done = false;
-            while (!done) {
-                int eventType = parser.next();
-                if ((eventType == XmlPullParser.START_TAG) && ("chat-setting".equals(parser.getName()))) {
-                    chatSettings.addSetting(parseChatSetting(parser));
-
-                }
-                else if (eventType == XmlPullParser.END_TAG && ELEMENT_NAME.equals(parser.getName())) {
-                    done = true;
-                }
-            }
-            return chatSettings;
-        }
-
-        private ChatSetting parseChatSetting(XmlPullParser parser) throws Exception {
-
-            boolean done = false;
-            String key = null;
-            String value = null;
-            int type = 0;
-
-            while (!done) {
-                int eventType = parser.next();
-                if ((eventType == XmlPullParser.START_TAG) && ("key".equals(parser.getName()))) {
-                    key = parser.nextText();
-                }
-                else if ((eventType == XmlPullParser.START_TAG) && ("value".equals(parser.getName()))) {
-                    value = parser.nextText();
-                }
-                else if ((eventType == XmlPullParser.START_TAG) && ("type".equals(parser.getName()))) {
-                    type = Integer.parseInt(parser.nextText());
-                }
-                else if (eventType == XmlPullParser.END_TAG && "chat-setting".equals(parser.getName())) {
-                    done = true;
-                }
-            }
-            return new ChatSetting(key, value, type);
-        }
-    }
-}
-
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.settings;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+public class ChatSettings extends IQ {
+
+    /**
+     * Defined as image type.
+     */
+    public static final int IMAGE_SETTINGS = 0;
+
+    /**
+     * Defined as Text settings type.
+     */
+    public static final int TEXT_SETTINGS = 1;
+
+    /**
+     * Defined as Bot settings type.
+     */
+    public static final int BOT_SETTINGS = 2;
+
+    private List<ChatSetting> settings;
+    private String key;
+    private int type = -1;
+
+    public ChatSettings() {
+        settings = new ArrayList<ChatSetting>();
+    }
+
+    public ChatSettings(String key) {
+        setKey(key);
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public void setType(int type) {
+        this.type = type;
+    }
+
+    public void addSetting(ChatSetting setting) {
+        settings.add(setting);
+    }
+
+    public Collection<ChatSetting> getSettings() {
+        return settings;
+    }
+
+    public ChatSetting getChatSetting(String key) {
+        Collection<ChatSetting> col = getSettings();
+        if (col != null) {
+            Iterator<ChatSetting> iter = col.iterator();
+            while (iter.hasNext()) {
+                ChatSetting chatSetting = iter.next();
+                if (chatSetting.getKey().equals(key)) {
+                    return chatSetting;
+                }
+            }
+        }
+        return null;
+    }
+
+    public ChatSetting getFirstEntry() {
+        if (settings.size() > 0) {
+            return (ChatSetting)settings.get(0);
+        }
+        return null;
+    }
+
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "chat-settings";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=");
+        buf.append('"');
+        buf.append(NAMESPACE);
+        buf.append('"');
+        if (key != null) {
+            buf.append(" key=\"" + key + "\"");
+        }
+
+        if (type != -1) {
+            buf.append(" type=\"" + type + "\"");
+        }
+
+        buf.append("></").append(ELEMENT_NAME).append("> ");
+        return buf.toString();
+    }
+
+    /**
+     * Packet extension provider for AgentStatusRequest packets.
+     */
+    public static class InternalProvider implements IQProvider {
+
+        public IQ parseIQ(XmlPullParser parser) throws Exception {
+            if (parser.getEventType() != XmlPullParser.START_TAG) {
+                throw new IllegalStateException("Parser not in proper position, or bad XML.");
+            }
+
+            ChatSettings chatSettings = new ChatSettings();
+
+            boolean done = false;
+            while (!done) {
+                int eventType = parser.next();
+                if ((eventType == XmlPullParser.START_TAG) && ("chat-setting".equals(parser.getName()))) {
+                    chatSettings.addSetting(parseChatSetting(parser));
+
+                }
+                else if (eventType == XmlPullParser.END_TAG && ELEMENT_NAME.equals(parser.getName())) {
+                    done = true;
+                }
+            }
+            return chatSettings;
+        }
+
+        private ChatSetting parseChatSetting(XmlPullParser parser) throws Exception {
+
+            boolean done = false;
+            String key = null;
+            String value = null;
+            int type = 0;
+
+            while (!done) {
+                int eventType = parser.next();
+                if ((eventType == XmlPullParser.START_TAG) && ("key".equals(parser.getName()))) {
+                    key = parser.nextText();
+                }
+                else if ((eventType == XmlPullParser.START_TAG) && ("value".equals(parser.getName()))) {
+                    value = parser.nextText();
+                }
+                else if ((eventType == XmlPullParser.START_TAG) && ("type".equals(parser.getName()))) {
+                    type = Integer.parseInt(parser.nextText());
+                }
+                else if (eventType == XmlPullParser.END_TAG && "chat-setting".equals(parser.getName())) {
+                    done = true;
+                }
+            }
+            return new ChatSetting(key, value, type);
+        }
+    }
+}
+
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/settings/OfflineSettings.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/settings/OfflineSettings.java
index 15136fd..14102af 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/settings/OfflineSettings.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/settings/OfflineSettings.java
@@ -1,155 +1,155 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.settings;
-
-import org.jivesoftware.smackx.workgroup.util.ModelUtil;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-public class OfflineSettings extends IQ {
-    private String redirectURL;
-
-    private String offlineText;
-    private String emailAddress;
-    private String subject;
-
-    public String getRedirectURL() {
-        if (!ModelUtil.hasLength(redirectURL)) {
-            return "";
-        }
-        return redirectURL;
-    }
-
-    public void setRedirectURL(String redirectURL) {
-        this.redirectURL = redirectURL;
-    }
-
-    public String getOfflineText() {
-        if (!ModelUtil.hasLength(offlineText)) {
-            return "";
-        }
-        return offlineText;
-    }
-
-    public void setOfflineText(String offlineText) {
-        this.offlineText = offlineText;
-    }
-
-    public String getEmailAddress() {
-        if (!ModelUtil.hasLength(emailAddress)) {
-            return "";
-        }
-        return emailAddress;
-    }
-
-    public void setEmailAddress(String emailAddress) {
-        this.emailAddress = emailAddress;
-    }
-
-    public String getSubject() {
-        if (!ModelUtil.hasLength(subject)) {
-            return "";
-        }
-        return subject;
-    }
-
-    public void setSubject(String subject) {
-        this.subject = subject;
-    }
-
-    public boolean redirects() {
-        return (ModelUtil.hasLength(getRedirectURL()));
-    }
-
-    public boolean isConfigured(){
-        return ModelUtil.hasLength(getEmailAddress()) &&
-               ModelUtil.hasLength(getSubject()) &&
-               ModelUtil.hasLength(getOfflineText());
-    }
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "offline-settings";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=");
-        buf.append('"');
-        buf.append(NAMESPACE);
-        buf.append('"');
-        buf.append("></").append(ELEMENT_NAME).append("> ");
-        return buf.toString();
-    }
-
-
-    /**
-     * Packet extension provider for AgentStatusRequest packets.
-     */
-    public static class InternalProvider implements IQProvider {
-
-        public IQ parseIQ(XmlPullParser parser) throws Exception {
-            if (parser.getEventType() != XmlPullParser.START_TAG) {
-                throw new IllegalStateException("Parser not in proper position, or bad XML.");
-            }
-
-            OfflineSettings offlineSettings = new OfflineSettings();
-
-            boolean done = false;
-            String redirectPage = null;
-            String subject = null;
-            String offlineText = null;
-            String emailAddress = null;
-
-            while (!done) {
-                int eventType = parser.next();
-                if ((eventType == XmlPullParser.START_TAG) && ("redirectPage".equals(parser.getName()))) {
-                    redirectPage = parser.nextText();
-                }
-                else if ((eventType == XmlPullParser.START_TAG) && ("subject".equals(parser.getName()))) {
-                    subject = parser.nextText();
-                }
-                else if ((eventType == XmlPullParser.START_TAG) && ("offlineText".equals(parser.getName()))) {
-                    offlineText = parser.nextText();
-                }
-                else if ((eventType == XmlPullParser.START_TAG) && ("emailAddress".equals(parser.getName()))) {
-                    emailAddress = parser.nextText();
-                }
-                else if (eventType == XmlPullParser.END_TAG && "offline-settings".equals(parser.getName())) {
-                    done = true;
-                }
-            }
-
-            offlineSettings.setEmailAddress(emailAddress);
-            offlineSettings.setRedirectURL(redirectPage);
-            offlineSettings.setSubject(subject);
-            offlineSettings.setOfflineText(offlineText);
-            return offlineSettings;
-        }
-    }
-}
-
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.settings;
+
+import org.jivesoftware.smackx.workgroup.util.ModelUtil;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+public class OfflineSettings extends IQ {
+    private String redirectURL;
+
+    private String offlineText;
+    private String emailAddress;
+    private String subject;
+
+    public String getRedirectURL() {
+        if (!ModelUtil.hasLength(redirectURL)) {
+            return "";
+        }
+        return redirectURL;
+    }
+
+    public void setRedirectURL(String redirectURL) {
+        this.redirectURL = redirectURL;
+    }
+
+    public String getOfflineText() {
+        if (!ModelUtil.hasLength(offlineText)) {
+            return "";
+        }
+        return offlineText;
+    }
+
+    public void setOfflineText(String offlineText) {
+        this.offlineText = offlineText;
+    }
+
+    public String getEmailAddress() {
+        if (!ModelUtil.hasLength(emailAddress)) {
+            return "";
+        }
+        return emailAddress;
+    }
+
+    public void setEmailAddress(String emailAddress) {
+        this.emailAddress = emailAddress;
+    }
+
+    public String getSubject() {
+        if (!ModelUtil.hasLength(subject)) {
+            return "";
+        }
+        return subject;
+    }
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+    public boolean redirects() {
+        return (ModelUtil.hasLength(getRedirectURL()));
+    }
+
+    public boolean isConfigured(){
+        return ModelUtil.hasLength(getEmailAddress()) &&
+               ModelUtil.hasLength(getSubject()) &&
+               ModelUtil.hasLength(getOfflineText());
+    }
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "offline-settings";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=");
+        buf.append('"');
+        buf.append(NAMESPACE);
+        buf.append('"');
+        buf.append("></").append(ELEMENT_NAME).append("> ");
+        return buf.toString();
+    }
+
+
+    /**
+     * Packet extension provider for AgentStatusRequest packets.
+     */
+    public static class InternalProvider implements IQProvider {
+
+        public IQ parseIQ(XmlPullParser parser) throws Exception {
+            if (parser.getEventType() != XmlPullParser.START_TAG) {
+                throw new IllegalStateException("Parser not in proper position, or bad XML.");
+            }
+
+            OfflineSettings offlineSettings = new OfflineSettings();
+
+            boolean done = false;
+            String redirectPage = null;
+            String subject = null;
+            String offlineText = null;
+            String emailAddress = null;
+
+            while (!done) {
+                int eventType = parser.next();
+                if ((eventType == XmlPullParser.START_TAG) && ("redirectPage".equals(parser.getName()))) {
+                    redirectPage = parser.nextText();
+                }
+                else if ((eventType == XmlPullParser.START_TAG) && ("subject".equals(parser.getName()))) {
+                    subject = parser.nextText();
+                }
+                else if ((eventType == XmlPullParser.START_TAG) && ("offlineText".equals(parser.getName()))) {
+                    offlineText = parser.nextText();
+                }
+                else if ((eventType == XmlPullParser.START_TAG) && ("emailAddress".equals(parser.getName()))) {
+                    emailAddress = parser.nextText();
+                }
+                else if (eventType == XmlPullParser.END_TAG && "offline-settings".equals(parser.getName())) {
+                    done = true;
+                }
+            }
+
+            offlineSettings.setEmailAddress(emailAddress);
+            offlineSettings.setRedirectURL(redirectPage);
+            offlineSettings.setSubject(subject);
+            offlineSettings.setOfflineText(offlineText);
+            return offlineSettings;
+        }
+    }
+}
+
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/settings/SearchSettings.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/settings/SearchSettings.java
index 98d59fc..037af78 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/settings/SearchSettings.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/settings/SearchSettings.java
@@ -1,112 +1,112 @@
-/**
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jivesoftware.smackx.workgroup.settings;
-
-import org.jivesoftware.smackx.workgroup.util.ModelUtil;
-import org.jivesoftware.smack.packet.IQ;
-import org.jivesoftware.smack.provider.IQProvider;
-import org.xmlpull.v1.XmlPullParser;
-
-public class SearchSettings extends IQ {
-    private String forumsLocation;
-    private String kbLocation;
-
-    public boolean isSearchEnabled() {
-        return ModelUtil.hasLength(getForumsLocation()) && ModelUtil.hasLength(getKbLocation());
-    }
-
-    public String getForumsLocation() {
-        return forumsLocation;
-    }
-
-    public void setForumsLocation(String forumsLocation) {
-        this.forumsLocation = forumsLocation;
-    }
-
-    public String getKbLocation() {
-        return kbLocation;
-    }
-
-    public void setKbLocation(String kbLocation) {
-        this.kbLocation = kbLocation;
-    }
-
-    public boolean hasKB(){
-        return ModelUtil.hasLength(getKbLocation());
-    }
-
-    public boolean hasForums(){
-        return ModelUtil.hasLength(getForumsLocation());
-    }
-
-
-    /**
-     * Element name of the packet extension.
-     */
-    public static final String ELEMENT_NAME = "search-settings";
-
-    /**
-     * Namespace of the packet extension.
-     */
-    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
-
-    public String getChildElementXML() {
-        StringBuilder buf = new StringBuilder();
-
-        buf.append("<").append(ELEMENT_NAME).append(" xmlns=");
-        buf.append('"');
-        buf.append(NAMESPACE);
-        buf.append('"');
-        buf.append("></").append(ELEMENT_NAME).append("> ");
-        return buf.toString();
-    }
-
-
-    /**
-     * Packet extension provider for AgentStatusRequest packets.
-     */
-    public static class InternalProvider implements IQProvider {
-
-        public IQ parseIQ(XmlPullParser parser) throws Exception {
-            if (parser.getEventType() != XmlPullParser.START_TAG) {
-                throw new IllegalStateException("Parser not in proper position, or bad XML.");
-            }
-
-            SearchSettings settings = new SearchSettings();
-
-            boolean done = false;
-            String kb = null;
-            String forums = null;
-
-            while (!done) {
-                int eventType = parser.next();
-                if ((eventType == XmlPullParser.START_TAG) && ("forums".equals(parser.getName()))) {
-                    forums = parser.nextText();
-                }
-                else if ((eventType == XmlPullParser.START_TAG) && ("kb".equals(parser.getName()))) {
-                    kb = parser.nextText();
-                }
-                else if (eventType == XmlPullParser.END_TAG && "search-settings".equals(parser.getName())) {
-                    done = true;
-                }
-            }
-
-            settings.setForumsLocation(forums);
-            settings.setKbLocation(kb);
-            return settings;
-        }
-    }
-}
+/**
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.workgroup.settings;
+
+import org.jivesoftware.smackx.workgroup.util.ModelUtil;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+public class SearchSettings extends IQ {
+    private String forumsLocation;
+    private String kbLocation;
+
+    public boolean isSearchEnabled() {
+        return ModelUtil.hasLength(getForumsLocation()) && ModelUtil.hasLength(getKbLocation());
+    }
+
+    public String getForumsLocation() {
+        return forumsLocation;
+    }
+
+    public void setForumsLocation(String forumsLocation) {
+        this.forumsLocation = forumsLocation;
+    }
+
+    public String getKbLocation() {
+        return kbLocation;
+    }
+
+    public void setKbLocation(String kbLocation) {
+        this.kbLocation = kbLocation;
+    }
+
+    public boolean hasKB(){
+        return ModelUtil.hasLength(getKbLocation());
+    }
+
+    public boolean hasForums(){
+        return ModelUtil.hasLength(getForumsLocation());
+    }
+
+
+    /**
+     * Element name of the packet extension.
+     */
+    public static final String ELEMENT_NAME = "search-settings";
+
+    /**
+     * Namespace of the packet extension.
+     */
+    public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
+
+    public String getChildElementXML() {
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("<").append(ELEMENT_NAME).append(" xmlns=");
+        buf.append('"');
+        buf.append(NAMESPACE);
+        buf.append('"');
+        buf.append("></").append(ELEMENT_NAME).append("> ");
+        return buf.toString();
+    }
+
+
+    /**
+     * Packet extension provider for AgentStatusRequest packets.
+     */
+    public static class InternalProvider implements IQProvider {
+
+        public IQ parseIQ(XmlPullParser parser) throws Exception {
+            if (parser.getEventType() != XmlPullParser.START_TAG) {
+                throw new IllegalStateException("Parser not in proper position, or bad XML.");
+            }
+
+            SearchSettings settings = new SearchSettings();
+
+            boolean done = false;
+            String kb = null;
+            String forums = null;
+
+            while (!done) {
+                int eventType = parser.next();
+                if ((eventType == XmlPullParser.START_TAG) && ("forums".equals(parser.getName()))) {
+                    forums = parser.nextText();
+                }
+                else if ((eventType == XmlPullParser.START_TAG) && ("kb".equals(parser.getName()))) {
+                    kb = parser.nextText();
+                }
+                else if (eventType == XmlPullParser.END_TAG && "search-settings".equals(parser.getName())) {
+                    done = true;
+                }
+            }
+
+            settings.setForumsLocation(forums);
+            settings.setKbLocation(kb);
+            return settings;
+        }
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/user/QueueListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/user/QueueListener.java
index fa3e6a6..734897f 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/user/QueueListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/user/QueueListener.java
@@ -1,55 +1,55 @@
-/**
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.user;
-
-/**
- * Listener interface for those that wish to be notified of workgroup queue events.
- *
- * @see Workgroup#addQueueListener(QueueListener)
- * @author loki der quaeler
- */
-public interface QueueListener {
-
-    /**
-     * The user joined the workgroup queue.
-     */
-    public void joinedQueue();
-
-    /**
-     * The user departed the workgroup queue.
-     */
-    public void departedQueue();
-
-    /**
-     * The user's queue position has been updated to a new value.
-     *
-     * @param currentPosition the user's current position in the queue.
-     */
-    public void queuePositionUpdated(int currentPosition);
-
-    /**
-     * The user's estimated remaining wait time in the queue has been updated.
-     *
-     * @param secondsRemaining the estimated number of seconds remaining until the
-     *      the user is routed to the agent.
-     */
-    public void queueWaitTimeUpdated(int secondsRemaining);
-
-}
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.user;
+
+/**
+ * Listener interface for those that wish to be notified of workgroup queue events.
+ *
+ * @see Workgroup#addQueueListener(QueueListener)
+ * @author loki der quaeler
+ */
+public interface QueueListener {
+
+    /**
+     * The user joined the workgroup queue.
+     */
+    public void joinedQueue();
+
+    /**
+     * The user departed the workgroup queue.
+     */
+    public void departedQueue();
+
+    /**
+     * The user's queue position has been updated to a new value.
+     *
+     * @param currentPosition the user's current position in the queue.
+     */
+    public void queuePositionUpdated(int currentPosition);
+
+    /**
+     * The user's estimated remaining wait time in the queue has been updated.
+     *
+     * @param secondsRemaining the estimated number of seconds remaining until the
+     *      the user is routed to the agent.
+     */
+    public void queueWaitTimeUpdated(int secondsRemaining);
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/user/Workgroup.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/user/Workgroup.java
index 237337f..4ccd034 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/user/Workgroup.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/user/Workgroup.java
@@ -1,868 +1,868 @@
-/**
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.user;
-
-import org.jivesoftware.smackx.workgroup.MetaData;
-import org.jivesoftware.smackx.workgroup.WorkgroupInvitation;
-import org.jivesoftware.smackx.workgroup.WorkgroupInvitationListener;
-import org.jivesoftware.smackx.workgroup.ext.forms.WorkgroupForm;
-import org.jivesoftware.smackx.workgroup.packet.DepartQueuePacket;
-import org.jivesoftware.smackx.workgroup.packet.QueueUpdate;
-import org.jivesoftware.smackx.workgroup.packet.SessionID;
-import org.jivesoftware.smackx.workgroup.packet.UserID;
-import org.jivesoftware.smackx.workgroup.settings.*;
-import org.jivesoftware.smack.*;
-import org.jivesoftware.smack.filter.*;
-import org.jivesoftware.smack.packet.*;
-import org.jivesoftware.smack.util.StringUtils;
-import org.jivesoftware.smackx.Form;
-import org.jivesoftware.smackx.FormField;
-import org.jivesoftware.smackx.ServiceDiscoveryManager;
-import org.jivesoftware.smackx.muc.MultiUserChat;
-import org.jivesoftware.smackx.packet.DataForm;
-import org.jivesoftware.smackx.packet.DiscoverInfo;
-import org.jivesoftware.smackx.packet.MUCUser;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Provides workgroup services for users. Users can join the workgroup queue, depart the
- * queue, find status information about their placement in the queue, and register to
- * be notified when they are routed to an agent.<p>
- * <p/>
- * This class only provides a users perspective into a workgroup and is not intended
- * for use by agents.
- *
- * @author Matt Tucker
- * @author Derek DeMoro
- */
-public class Workgroup {
-
-    private String workgroupJID;
-    private Connection connection;
-    private boolean inQueue;
-    private List<WorkgroupInvitationListener> invitationListeners;
-    private List<QueueListener> queueListeners;
-
-    private int queuePosition = -1;
-    private int queueRemainingTime = -1;
-
-    /**
-     * Creates a new workgroup instance using the specified workgroup JID
-     * (eg support@workgroup.example.com) and XMPP connection. The connection must have
-     * undergone a successful login before being used to construct an instance of
-     * this class.
-     *
-     * @param workgroupJID the JID of the workgroup.
-     * @param connection   an XMPP connection which must have already undergone a
-     *                     successful login.
-     */
-    public Workgroup(String workgroupJID, Connection connection) {
-        // Login must have been done before passing in connection.
-        if (!connection.isAuthenticated()) {
-            throw new IllegalStateException("Must login to server before creating workgroup.");
-        }
-
-        this.workgroupJID = workgroupJID;
-        this.connection = connection;
-        inQueue = false;
-        invitationListeners = new ArrayList<WorkgroupInvitationListener>();
-        queueListeners = new ArrayList<QueueListener>();
-
-        // Register as a queue listener for internal usage by this instance.
-        addQueueListener(new QueueListener() {
-            public void joinedQueue() {
-                inQueue = true;
-            }
-
-            public void departedQueue() {
-                inQueue = false;
-                queuePosition = -1;
-                queueRemainingTime = -1;
-            }
-
-            public void queuePositionUpdated(int currentPosition) {
-                queuePosition = currentPosition;
-            }
-
-            public void queueWaitTimeUpdated(int secondsRemaining) {
-                queueRemainingTime = secondsRemaining;
-            }
-        });
-
-        /**
-         * Internal handling of an invitation.Recieving an invitation removes the user from the queue.
-         */
-        MultiUserChat.addInvitationListener(connection,
-                new org.jivesoftware.smackx.muc.InvitationListener() {
-                    public void invitationReceived(Connection conn, String room, String inviter,
-                                                   String reason, String password, Message message) {
-                        inQueue = false;
-                        queuePosition = -1;
-                        queueRemainingTime = -1;
-                    }
-                });
-
-        // Register a packet listener for all the messages sent to this client.
-        PacketFilter typeFilter = new PacketTypeFilter(Message.class);
-
-        connection.addPacketListener(new PacketListener() {
-            public void processPacket(Packet packet) {
-                handlePacket(packet);
-            }
-        }, typeFilter);
-    }
-
-    /**
-     * Returns the name of this workgroup (eg support@example.com).
-     *
-     * @return the name of the workgroup.
-     */
-    public String getWorkgroupJID() {
-        return workgroupJID;
-    }
-
-    /**
-     * Returns true if the user is currently waiting in the workgroup queue.
-     *
-     * @return true if currently waiting in the queue.
-     */
-    public boolean isInQueue() {
-        return inQueue;
-    }
-
-    /**
-     * Returns true if the workgroup is available for receiving new requests. The workgroup will be
-     * available only when agents are available for this workgroup.
-     *
-     * @return true if the workgroup is available for receiving new requests.
-     */
-    public boolean isAvailable() {
-        Presence directedPresence = new Presence(Presence.Type.available);
-        directedPresence.setTo(workgroupJID);
-        PacketFilter typeFilter = new PacketTypeFilter(Presence.class);
-        PacketFilter fromFilter = new FromContainsFilter(workgroupJID);
-        PacketCollector collector = connection.createPacketCollector(new AndFilter(fromFilter,
-                typeFilter));
-
-        connection.sendPacket(directedPresence);
-
-        Presence response = (Presence)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            return false;
-        }
-        else if (response.getError() != null) {
-            return false;
-        }
-        else {
-            return Presence.Type.available == response.getType();
-        }
-    }
-
-    /**
-     * Returns the users current position in the workgroup queue. A value of 0 means
-     * the user is next in line to be routed; therefore, if the queue position
-     * is being displayed to the end user it is usually a good idea to add 1 to
-     * the value this method returns before display. If the user is not currently
-     * waiting in the workgroup, or no queue position information is available, -1
-     * will be returned.
-     *
-     * @return the user's current position in the workgroup queue, or -1 if the
-     *         position isn't available or if the user isn't in the queue.
-     */
-    public int getQueuePosition() {
-        return queuePosition;
-    }
-
-    /**
-     * Returns the estimated time (in seconds) that the user has to left wait in
-     * the workgroup queue before being routed. If the user is not currently waiting
-     * int he workgroup, or no queue time information is available, -1 will be
-     * returned.
-     *
-     * @return the estimated time remaining (in seconds) that the user has to
-     *         wait inthe workgroupu queue, or -1 if time information isn't available
-     *         or if the user isn't int the queue.
-     */
-    public int getQueueRemainingTime() {
-        return queueRemainingTime;
-    }
-
-    /**
-     * Joins the workgroup queue to wait to be routed to an agent. After joining
-     * the queue, queue status events will be sent to indicate the user's position and
-     * estimated time left in the queue. Once joining the queue, there are three ways
-     * the user can leave the queue: <ul>
-     * <p/>
-     * <li>The user is routed to an agent, which triggers a GroupChat invitation.
-     * <li>The user asks to leave the queue by calling the {@link #departQueue} method.
-     * <li>A server error occurs, or an administrator explicitly removes the user
-     * from the queue.
-     * </ul>
-     * <p/>
-     * A user cannot request to join the queue again if already in the queue. Therefore,
-     * this method will throw an IllegalStateException if the user is already in the queue.<p>
-     * <p/>
-     * Some servers may be configured to require certain meta-data in order to
-     * join the queue. In that case, the {@link #joinQueue(Form)} method should be
-     * used instead of this method so that meta-data may be passed in.<p>
-     * <p/>
-     * The server tracks the conversations that a user has with agents over time. By
-     * default, that tracking is done using the user's JID. However, this is not always
-     * possible. For example, when the user is logged in anonymously using a web client.
-     * In that case the user ID might be a randomly generated value put into a persistent
-     * cookie or a username obtained via the session. A userID can be explicitly
-     * passed in by using the {@link #joinQueue(Form, String)} method. When specified,
-     * that userID will be used instead of the user's JID to track conversations. The
-     * server will ignore a manually specified userID if the user's connection to the server
-     * is not anonymous.
-     *
-     * @throws XMPPException if an error occured joining the queue. An error may indicate
-     *                       that a connection failure occured or that the server explicitly rejected the
-     *                       request to join the queue.
-     */
-    public void joinQueue() throws XMPPException {
-        joinQueue(null);
-    }
-
-    /**
-     * Joins the workgroup queue to wait to be routed to an agent. After joining
-     * the queue, queue status events will be sent to indicate the user's position and
-     * estimated time left in the queue. Once joining the queue, there are three ways
-     * the user can leave the queue: <ul>
-     * <p/>
-     * <li>The user is routed to an agent, which triggers a GroupChat invitation.
-     * <li>The user asks to leave the queue by calling the {@link #departQueue} method.
-     * <li>A server error occurs, or an administrator explicitly removes the user
-     * from the queue.
-     * </ul>
-     * <p/>
-     * A user cannot request to join the queue again if already in the queue. Therefore,
-     * this method will throw an IllegalStateException if the user is already in the queue.<p>
-     * <p/>
-     * Some servers may be configured to require certain meta-data in order to
-     * join the queue.<p>
-     * <p/>
-     * The server tracks the conversations that a user has with agents over time. By
-     * default, that tracking is done using the user's JID. However, this is not always
-     * possible. For example, when the user is logged in anonymously using a web client.
-     * In that case the user ID might be a randomly generated value put into a persistent
-     * cookie or a username obtained via the session. A userID can be explicitly
-     * passed in by using the {@link #joinQueue(Form, String)} method. When specified,
-     * that userID will be used instead of the user's JID to track conversations. The
-     * server will ignore a manually specified userID if the user's connection to the server
-     * is not anonymous.
-     *
-     * @param answerForm the completed form the send for the join request.
-     * @throws XMPPException if an error occured joining the queue. An error may indicate
-     *                       that a connection failure occured or that the server explicitly rejected the
-     *                       request to join the queue.
-     */
-    public void joinQueue(Form answerForm) throws XMPPException {
-        joinQueue(answerForm, null);
-    }
-
-    /**
-     * <p>Joins the workgroup queue to wait to be routed to an agent. After joining
-     * the queue, queue status events will be sent to indicate the user's position and
-     * estimated time left in the queue. Once joining the queue, there are three ways
-     * the user can leave the queue: <ul>
-     * <p/>
-     * <li>The user is routed to an agent, which triggers a GroupChat invitation.
-     * <li>The user asks to leave the queue by calling the {@link #departQueue} method.
-     * <li>A server error occurs, or an administrator explicitly removes the user
-     * from the queue.
-     * </ul>
-     * <p/>
-     * A user cannot request to join the queue again if already in the queue. Therefore,
-     * this method will throw an IllegalStateException if the user is already in the queue.<p>
-     * <p/>
-     * Some servers may be configured to require certain meta-data in order to
-     * join the queue.<p>
-     * <p/>
-     * The server tracks the conversations that a user has with agents over time. By
-     * default, that tracking is done using the user's JID. However, this is not always
-     * possible. For example, when the user is logged in anonymously using a web client.
-     * In that case the user ID might be a randomly generated value put into a persistent
-     * cookie or a username obtained via the session. When specified, that userID will
-     * be used instead of the user's JID to track conversations. The server will ignore a
-     * manually specified userID if the user's connection to the server is not anonymous.
-     *
-     * @param answerForm the completed form associated with the join reqest.
-     * @param userID     String that represents the ID of the user when using anonymous sessions
-     *                   or <tt>null</tt> if a userID should not be used.
-     * @throws XMPPException if an error occured joining the queue. An error may indicate
-     *                       that a connection failure occured or that the server explicitly rejected the
-     *                       request to join the queue.
-     */
-    public void joinQueue(Form answerForm, String userID) throws XMPPException {
-        // If already in the queue ignore the join request.
-        if (inQueue) {
-            throw new IllegalStateException("Already in queue " + workgroupJID);
-        }
-
-        JoinQueuePacket joinPacket = new JoinQueuePacket(workgroupJID, answerForm, userID);
-
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(joinPacket.getPacketID()));
-
-        this.connection.sendPacket(joinPacket);
-
-        IQ response = (IQ)collector.nextResult(10000);
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from the server.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-
-        // Notify listeners that we've joined the queue.
-        fireQueueJoinedEvent();
-    }
-
-    /**
-     * <p>Joins the workgroup queue to wait to be routed to an agent. After joining
-     * the queue, queue status events will be sent to indicate the user's position and
-     * estimated time left in the queue. Once joining the queue, there are three ways
-     * the user can leave the queue: <ul>
-     * <p/>
-     * <li>The user is routed to an agent, which triggers a GroupChat invitation.
-     * <li>The user asks to leave the queue by calling the {@link #departQueue} method.
-     * <li>A server error occurs, or an administrator explicitly removes the user
-     * from the queue.
-     * </ul>
-     * <p/>
-     * A user cannot request to join the queue again if already in the queue. Therefore,
-     * this method will throw an IllegalStateException if the user is already in the queue.<p>
-     * <p/>
-     * Some servers may be configured to require certain meta-data in order to
-     * join the queue.<p>
-     * <p/>
-     * The server tracks the conversations that a user has with agents over time. By
-     * default, that tracking is done using the user's JID. However, this is not always
-     * possible. For example, when the user is logged in anonymously using a web client.
-     * In that case the user ID might be a randomly generated value put into a persistent
-     * cookie or a username obtained via the session. When specified, that userID will
-     * be used instead of the user's JID to track conversations. The server will ignore a
-     * manually specified userID if the user's connection to the server is not anonymous.
-     *
-     * @param metadata metadata to create a dataform from.
-     * @param userID   String that represents the ID of the user when using anonymous sessions
-     *                 or <tt>null</tt> if a userID should not be used.
-     * @throws XMPPException if an error occured joining the queue. An error may indicate
-     *                       that a connection failure occured or that the server explicitly rejected the
-     *                       request to join the queue.
-     */
-    public void joinQueue(Map<String,Object> metadata, String userID) throws XMPPException {
-        // If already in the queue ignore the join request.
-        if (inQueue) {
-            throw new IllegalStateException("Already in queue " + workgroupJID);
-        }
-
-        // Build dataform from metadata
-        Form form = new Form(Form.TYPE_SUBMIT);
-        Iterator<String> iter = metadata.keySet().iterator();
-        while (iter.hasNext()) {
-            String name = iter.next();
-            String value = metadata.get(name).toString();
-
-            String escapedName = StringUtils.escapeForXML(name);
-            String escapedValue = StringUtils.escapeForXML(value);
-
-            FormField field = new FormField(escapedName);
-            field.setType(FormField.TYPE_TEXT_SINGLE);
-            form.addField(field);
-            form.setAnswer(escapedName, escapedValue);
-        }
-        joinQueue(form, userID);
-    }
-
-    /**
-     * Departs the workgroup queue. If the user is not currently in the queue, this
-     * method will do nothing.<p>
-     * <p/>
-     * Normally, the user would not manually leave the queue. However, they may wish to
-     * under certain circumstances -- for example, if they no longer wish to be routed
-     * to an agent because they've been waiting too long.
-     *
-     * @throws XMPPException if an error occured trying to send the depart queue
-     *                       request to the server.
-     */
-    public void departQueue() throws XMPPException {
-        // If not in the queue ignore the depart request.
-        if (!inQueue) {
-            return;
-        }
-
-        DepartQueuePacket departPacket = new DepartQueuePacket(this.workgroupJID);
-        PacketCollector collector = this.connection.createPacketCollector(new PacketIDFilter(departPacket.getPacketID()));
-
-        connection.sendPacket(departPacket);
-
-        IQ response = (IQ)collector.nextResult(5000);
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from the server.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-
-        // Notify listeners that we're no longer in the queue.
-        fireQueueDepartedEvent();
-    }
-
-    /**
-     * Adds a queue listener that will be notified of queue events for the user
-     * that created this Workgroup instance.
-     *
-     * @param queueListener the queue listener.
-     */
-    public void addQueueListener(QueueListener queueListener) {
-        synchronized (queueListeners) {
-            if (!queueListeners.contains(queueListener)) {
-                queueListeners.add(queueListener);
-            }
-        }
-    }
-
-    /**
-     * Removes a queue listener.
-     *
-     * @param queueListener the queue listener.
-     */
-    public void removeQueueListener(QueueListener queueListener) {
-        synchronized (queueListeners) {
-            queueListeners.remove(queueListener);
-        }
-    }
-
-    /**
-     * Adds an invitation listener that will be notified of groupchat invitations
-     * from the workgroup for the the user that created this Workgroup instance.
-     *
-     * @param invitationListener the invitation listener.
-     */
-    public void addInvitationListener(WorkgroupInvitationListener invitationListener) {
-        synchronized (invitationListeners) {
-            if (!invitationListeners.contains(invitationListener)) {
-                invitationListeners.add(invitationListener);
-            }
-        }
-    }
-
-    /**
-     * Removes an invitation listener.
-     *
-     * @param invitationListener the invitation listener.
-     */
-    public void removeQueueListener(WorkgroupInvitationListener invitationListener) {
-        synchronized (invitationListeners) {
-            invitationListeners.remove(invitationListener);
-        }
-    }
-
-    private void fireInvitationEvent(WorkgroupInvitation invitation) {
-        synchronized (invitationListeners) {
-            for (Iterator<WorkgroupInvitationListener> i = invitationListeners.iterator(); i.hasNext();) {
-                WorkgroupInvitationListener listener = i.next();
-                listener.invitationReceived(invitation);
-            }
-        }
-    }
-
-    private void fireQueueJoinedEvent() {
-        synchronized (queueListeners) {
-            for (Iterator<QueueListener> i = queueListeners.iterator(); i.hasNext();) {
-                QueueListener listener = i.next();
-                listener.joinedQueue();
-            }
-        }
-    }
-
-    private void fireQueueDepartedEvent() {
-        synchronized (queueListeners) {
-            for (Iterator<QueueListener> i = queueListeners.iterator(); i.hasNext();) {
-                QueueListener listener = i.next();
-                listener.departedQueue();
-            }
-        }
-    }
-
-    private void fireQueuePositionEvent(int currentPosition) {
-        synchronized (queueListeners) {
-            for (Iterator<QueueListener> i = queueListeners.iterator(); i.hasNext();) {
-                QueueListener listener = i.next();
-                listener.queuePositionUpdated(currentPosition);
-            }
-        }
-    }
-
-    private void fireQueueTimeEvent(int secondsRemaining) {
-        synchronized (queueListeners) {
-            for (Iterator<QueueListener> i = queueListeners.iterator(); i.hasNext();) {
-                QueueListener listener = i.next();
-                listener.queueWaitTimeUpdated(secondsRemaining);
-            }
-        }
-    }
-
-    // PacketListener Implementation.
-
-    private void handlePacket(Packet packet) {
-        if (packet instanceof Message) {
-            Message msg = (Message)packet;
-            // Check to see if the user left the queue.
-            PacketExtension pe = msg.getExtension("depart-queue", "http://jabber.org/protocol/workgroup");
-            PacketExtension queueStatus = msg.getExtension("queue-status", "http://jabber.org/protocol/workgroup");
-
-            if (pe != null) {
-                fireQueueDepartedEvent();
-            }
-            else if (queueStatus != null) {
-                QueueUpdate queueUpdate = (QueueUpdate)queueStatus;
-                if (queueUpdate.getPosition() != -1) {
-                    fireQueuePositionEvent(queueUpdate.getPosition());
-                }
-                if (queueUpdate.getRemaingTime() != -1) {
-                    fireQueueTimeEvent(queueUpdate.getRemaingTime());
-                }
-            }
-
-            else {
-                // Check if a room invitation was sent and if the sender is the workgroup
-                MUCUser mucUser = (MUCUser)msg.getExtension("x", "http://jabber.org/protocol/muc#user");
-                MUCUser.Invite invite = mucUser != null ? mucUser.getInvite() : null;
-                if (invite != null && workgroupJID.equals(invite.getFrom())) {
-                    String sessionID = null;
-                    Map<String, List<String>> metaData = null;
-
-                    pe = msg.getExtension(SessionID.ELEMENT_NAME,
-                            SessionID.NAMESPACE);
-                    if (pe != null) {
-                        sessionID = ((SessionID)pe).getSessionID();
-                    }
-
-                    pe = msg.getExtension(MetaData.ELEMENT_NAME,
-                            MetaData.NAMESPACE);
-                    if (pe != null) {
-                        metaData = ((MetaData)pe).getMetaData();
-                    }
-
-                    WorkgroupInvitation inv = new WorkgroupInvitation(connection.getUser(), msg.getFrom(),
-                            workgroupJID, sessionID, msg.getBody(),
-                            msg.getFrom(), metaData);
-
-                    fireInvitationEvent(inv);
-                }
-            }
-        }
-    }
-
-    /**
-     * IQ packet to request joining the workgroup queue.
-     */
-    private class JoinQueuePacket extends IQ {
-
-        private String userID = null;
-        private DataForm form;
-
-        public JoinQueuePacket(String workgroup, Form answerForm, String userID) {
-            this.userID = userID;
-
-            setTo(workgroup);
-            setType(IQ.Type.SET);
-
-            form = answerForm.getDataFormToSend();
-            addExtension(form);
-        }
-
-        public String getChildElementXML() {
-            StringBuilder buf = new StringBuilder();
-
-            buf.append("<join-queue xmlns=\"http://jabber.org/protocol/workgroup\">");
-            buf.append("<queue-notifications/>");
-            // Add the user unique identification if the session is anonymous
-            if (connection.isAnonymous()) {
-                buf.append(new UserID(userID).toXML());
-            }
-
-            // Append data form text
-            buf.append(form.toXML());
-
-            buf.append("</join-queue>");
-
-            return buf.toString();
-        }
-    }
-
-    /**
-     * Returns a single chat setting based on it's identified key.
-     *
-     * @param key the key to find.
-     * @return the ChatSetting if found, otherwise false.
-     * @throws XMPPException if an error occurs while getting information from the server.
-     */
-    public ChatSetting getChatSetting(String key) throws XMPPException {
-        ChatSettings chatSettings = getChatSettings(key, -1);
-        return chatSettings.getFirstEntry();
-    }
-
-    /**
-     * Returns ChatSettings based on type.
-     *
-     * @param type the type of ChatSettings to return.
-     * @return the ChatSettings of given type, otherwise null.
-     * @throws XMPPException if an error occurs while getting information from the server.
-     */
-    public ChatSettings getChatSettings(int type) throws XMPPException {
-        return getChatSettings(null, type);
-    }
-
-    /**
-     * Returns all ChatSettings.
-     *
-     * @return all ChatSettings of a given workgroup.
-     * @throws XMPPException if an error occurs while getting information from the server.
-     */
-    public ChatSettings getChatSettings() throws XMPPException {
-        return getChatSettings(null, -1);
-    }
-
-
-    /**
-     * Asks the workgroup for it's Chat Settings.
-     *
-     * @return key specify a key to retrieve only that settings. Otherwise for all settings, key should be null.
-     * @throws XMPPException if an error occurs while getting information from the server.
-     */
-    private ChatSettings getChatSettings(String key, int type) throws XMPPException {
-        ChatSettings request = new ChatSettings();
-        if (key != null) {
-            request.setKey(key);
-        }
-        if (type != -1) {
-            request.setType(type);
-        }
-        request.setType(IQ.Type.GET);
-        request.setTo(workgroupJID);
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
-        connection.sendPacket(request);
-
-
-        ChatSettings response = (ChatSettings)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response;
-    }
-
-    /**
-     * The workgroup service may be configured to send email. This queries the Workgroup Service
-     * to see if the email service has been configured and is available.
-     *
-     * @return true if the email service is available, otherwise return false.
-     */
-    public boolean isEmailAvailable() {
-        ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);
-
-        try {
-            String workgroupService = StringUtils.parseServer(workgroupJID);
-            DiscoverInfo infoResult = discoManager.discoverInfo(workgroupService);
-            return infoResult.containsFeature("jive:email:provider");
-        }
-        catch (XMPPException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Asks the workgroup for it's Offline Settings.
-     *
-     * @return offlineSettings the offline settings for this workgroup.
-     * @throws XMPPException if an error occurs while getting information from the server.
-     */
-    public OfflineSettings getOfflineSettings() throws XMPPException {
-        OfflineSettings request = new OfflineSettings();
-        request.setType(IQ.Type.GET);
-        request.setTo(workgroupJID);
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
-        connection.sendPacket(request);
-
-
-        OfflineSettings response = (OfflineSettings)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response;
-    }
-
-    /**
-     * Asks the workgroup for it's Sound Settings.
-     *
-     * @return soundSettings the sound settings for the specified workgroup.
-     * @throws XMPPException if an error occurs while getting information from the server.
-     */
-    public SoundSettings getSoundSettings() throws XMPPException {
-        SoundSettings request = new SoundSettings();
-        request.setType(IQ.Type.GET);
-        request.setTo(workgroupJID);
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
-        connection.sendPacket(request);
-
-
-        SoundSettings response = (SoundSettings)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response;
-    }
-
-    /**
-     * Asks the workgroup for it's Properties
-     *
-     * @return the WorkgroupProperties for the specified workgroup.
-     * @throws XMPPException if an error occurs while getting information from the server.
-     */
-    public WorkgroupProperties getWorkgroupProperties() throws XMPPException {
-        WorkgroupProperties request = new WorkgroupProperties();
-        request.setType(IQ.Type.GET);
-        request.setTo(workgroupJID);
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
-        connection.sendPacket(request);
-
-
-        WorkgroupProperties response = (WorkgroupProperties)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response;
-    }
-
-    /**
-     * Asks the workgroup for it's Properties
-     *
-     * @param jid the jid of the user who's information you would like the workgroup to retreive.
-     * @return the WorkgroupProperties for the specified workgroup.
-     * @throws XMPPException if an error occurs while getting information from the server.
-     */
-    public WorkgroupProperties getWorkgroupProperties(String jid) throws XMPPException {
-        WorkgroupProperties request = new WorkgroupProperties();
-        request.setJid(jid);
-        request.setType(IQ.Type.GET);
-        request.setTo(workgroupJID);
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
-        connection.sendPacket(request);
-
-
-        WorkgroupProperties response = (WorkgroupProperties)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return response;
-    }
-
-
-    /**
-     * Returns the Form to use for all clients of a workgroup. It is unlikely that the server
-     * will change the form (without a restart) so it is safe to keep the returned form
-     * for future submissions.
-     *
-     * @return the Form to use for searching transcripts.
-     * @throws XMPPException if an error occurs while sending the request to the server.
-     */
-    public Form getWorkgroupForm() throws XMPPException {
-        WorkgroupForm workgroupForm = new WorkgroupForm();
-        workgroupForm.setType(IQ.Type.GET);
-        workgroupForm.setTo(workgroupJID);
-
-        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(workgroupForm.getPacketID()));
-        connection.sendPacket(workgroupForm);
-
-        WorkgroupForm response = (WorkgroupForm)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
-        // Cancel the collector.
-        collector.cancel();
-        if (response == null) {
-            throw new XMPPException("No response from server on status set.");
-        }
-        if (response.getError() != null) {
-            throw new XMPPException(response.getError());
-        }
-        return Form.getFormFrom(response);
-    }
-
-    /*
-    public static void main(String args[]) throws Exception {
-        Connection con = new XMPPConnection("anteros");
-        con.connect();
-        con.loginAnonymously();
-
-        Workgroup workgroup = new Workgroup("demo@workgroup.anteros", con);
-        WorkgroupProperties props = workgroup.getWorkgroupProperties("derek@anteros.com");
-
-        System.out.print(props);
-        con.disconnect();
-    }
-    */
-
-
+/**
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.user;
+
+import org.jivesoftware.smackx.workgroup.MetaData;
+import org.jivesoftware.smackx.workgroup.WorkgroupInvitation;
+import org.jivesoftware.smackx.workgroup.WorkgroupInvitationListener;
+import org.jivesoftware.smackx.workgroup.ext.forms.WorkgroupForm;
+import org.jivesoftware.smackx.workgroup.packet.DepartQueuePacket;
+import org.jivesoftware.smackx.workgroup.packet.QueueUpdate;
+import org.jivesoftware.smackx.workgroup.packet.SessionID;
+import org.jivesoftware.smackx.workgroup.packet.UserID;
+import org.jivesoftware.smackx.workgroup.settings.*;
+import org.jivesoftware.smack.*;
+import org.jivesoftware.smack.filter.*;
+import org.jivesoftware.smack.packet.*;
+import org.jivesoftware.smack.util.StringUtils;
+import org.jivesoftware.smackx.Form;
+import org.jivesoftware.smackx.FormField;
+import org.jivesoftware.smackx.ServiceDiscoveryManager;
+import org.jivesoftware.smackx.muc.MultiUserChat;
+import org.jivesoftware.smackx.packet.DataForm;
+import org.jivesoftware.smackx.packet.DiscoverInfo;
+import org.jivesoftware.smackx.packet.MUCUser;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Provides workgroup services for users. Users can join the workgroup queue, depart the
+ * queue, find status information about their placement in the queue, and register to
+ * be notified when they are routed to an agent.<p>
+ * <p/>
+ * This class only provides a users perspective into a workgroup and is not intended
+ * for use by agents.
+ *
+ * @author Matt Tucker
+ * @author Derek DeMoro
+ */
+public class Workgroup {
+
+    private String workgroupJID;
+    private Connection connection;
+    private boolean inQueue;
+    private List<WorkgroupInvitationListener> invitationListeners;
+    private List<QueueListener> queueListeners;
+
+    private int queuePosition = -1;
+    private int queueRemainingTime = -1;
+
+    /**
+     * Creates a new workgroup instance using the specified workgroup JID
+     * (eg support@workgroup.example.com) and XMPP connection. The connection must have
+     * undergone a successful login before being used to construct an instance of
+     * this class.
+     *
+     * @param workgroupJID the JID of the workgroup.
+     * @param connection   an XMPP connection which must have already undergone a
+     *                     successful login.
+     */
+    public Workgroup(String workgroupJID, Connection connection) {
+        // Login must have been done before passing in connection.
+        if (!connection.isAuthenticated()) {
+            throw new IllegalStateException("Must login to server before creating workgroup.");
+        }
+
+        this.workgroupJID = workgroupJID;
+        this.connection = connection;
+        inQueue = false;
+        invitationListeners = new ArrayList<WorkgroupInvitationListener>();
+        queueListeners = new ArrayList<QueueListener>();
+
+        // Register as a queue listener for internal usage by this instance.
+        addQueueListener(new QueueListener() {
+            public void joinedQueue() {
+                inQueue = true;
+            }
+
+            public void departedQueue() {
+                inQueue = false;
+                queuePosition = -1;
+                queueRemainingTime = -1;
+            }
+
+            public void queuePositionUpdated(int currentPosition) {
+                queuePosition = currentPosition;
+            }
+
+            public void queueWaitTimeUpdated(int secondsRemaining) {
+                queueRemainingTime = secondsRemaining;
+            }
+        });
+
+        /**
+         * Internal handling of an invitation.Recieving an invitation removes the user from the queue.
+         */
+        MultiUserChat.addInvitationListener(connection,
+                new org.jivesoftware.smackx.muc.InvitationListener() {
+                    public void invitationReceived(Connection conn, String room, String inviter,
+                                                   String reason, String password, Message message) {
+                        inQueue = false;
+                        queuePosition = -1;
+                        queueRemainingTime = -1;
+                    }
+                });
+
+        // Register a packet listener for all the messages sent to this client.
+        PacketFilter typeFilter = new PacketTypeFilter(Message.class);
+
+        connection.addPacketListener(new PacketListener() {
+            public void processPacket(Packet packet) {
+                handlePacket(packet);
+            }
+        }, typeFilter);
+    }
+
+    /**
+     * Returns the name of this workgroup (eg support@example.com).
+     *
+     * @return the name of the workgroup.
+     */
+    public String getWorkgroupJID() {
+        return workgroupJID;
+    }
+
+    /**
+     * Returns true if the user is currently waiting in the workgroup queue.
+     *
+     * @return true if currently waiting in the queue.
+     */
+    public boolean isInQueue() {
+        return inQueue;
+    }
+
+    /**
+     * Returns true if the workgroup is available for receiving new requests. The workgroup will be
+     * available only when agents are available for this workgroup.
+     *
+     * @return true if the workgroup is available for receiving new requests.
+     */
+    public boolean isAvailable() {
+        Presence directedPresence = new Presence(Presence.Type.available);
+        directedPresence.setTo(workgroupJID);
+        PacketFilter typeFilter = new PacketTypeFilter(Presence.class);
+        PacketFilter fromFilter = new FromContainsFilter(workgroupJID);
+        PacketCollector collector = connection.createPacketCollector(new AndFilter(fromFilter,
+                typeFilter));
+
+        connection.sendPacket(directedPresence);
+
+        Presence response = (Presence)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            return false;
+        }
+        else if (response.getError() != null) {
+            return false;
+        }
+        else {
+            return Presence.Type.available == response.getType();
+        }
+    }
+
+    /**
+     * Returns the users current position in the workgroup queue. A value of 0 means
+     * the user is next in line to be routed; therefore, if the queue position
+     * is being displayed to the end user it is usually a good idea to add 1 to
+     * the value this method returns before display. If the user is not currently
+     * waiting in the workgroup, or no queue position information is available, -1
+     * will be returned.
+     *
+     * @return the user's current position in the workgroup queue, or -1 if the
+     *         position isn't available or if the user isn't in the queue.
+     */
+    public int getQueuePosition() {
+        return queuePosition;
+    }
+
+    /**
+     * Returns the estimated time (in seconds) that the user has to left wait in
+     * the workgroup queue before being routed. If the user is not currently waiting
+     * int he workgroup, or no queue time information is available, -1 will be
+     * returned.
+     *
+     * @return the estimated time remaining (in seconds) that the user has to
+     *         wait inthe workgroupu queue, or -1 if time information isn't available
+     *         or if the user isn't int the queue.
+     */
+    public int getQueueRemainingTime() {
+        return queueRemainingTime;
+    }
+
+    /**
+     * Joins the workgroup queue to wait to be routed to an agent. After joining
+     * the queue, queue status events will be sent to indicate the user's position and
+     * estimated time left in the queue. Once joining the queue, there are three ways
+     * the user can leave the queue: <ul>
+     * <p/>
+     * <li>The user is routed to an agent, which triggers a GroupChat invitation.
+     * <li>The user asks to leave the queue by calling the {@link #departQueue} method.
+     * <li>A server error occurs, or an administrator explicitly removes the user
+     * from the queue.
+     * </ul>
+     * <p/>
+     * A user cannot request to join the queue again if already in the queue. Therefore,
+     * this method will throw an IllegalStateException if the user is already in the queue.<p>
+     * <p/>
+     * Some servers may be configured to require certain meta-data in order to
+     * join the queue. In that case, the {@link #joinQueue(Form)} method should be
+     * used instead of this method so that meta-data may be passed in.<p>
+     * <p/>
+     * The server tracks the conversations that a user has with agents over time. By
+     * default, that tracking is done using the user's JID. However, this is not always
+     * possible. For example, when the user is logged in anonymously using a web client.
+     * In that case the user ID might be a randomly generated value put into a persistent
+     * cookie or a username obtained via the session. A userID can be explicitly
+     * passed in by using the {@link #joinQueue(Form, String)} method. When specified,
+     * that userID will be used instead of the user's JID to track conversations. The
+     * server will ignore a manually specified userID if the user's connection to the server
+     * is not anonymous.
+     *
+     * @throws XMPPException if an error occured joining the queue. An error may indicate
+     *                       that a connection failure occured or that the server explicitly rejected the
+     *                       request to join the queue.
+     */
+    public void joinQueue() throws XMPPException {
+        joinQueue(null);
+    }
+
+    /**
+     * Joins the workgroup queue to wait to be routed to an agent. After joining
+     * the queue, queue status events will be sent to indicate the user's position and
+     * estimated time left in the queue. Once joining the queue, there are three ways
+     * the user can leave the queue: <ul>
+     * <p/>
+     * <li>The user is routed to an agent, which triggers a GroupChat invitation.
+     * <li>The user asks to leave the queue by calling the {@link #departQueue} method.
+     * <li>A server error occurs, or an administrator explicitly removes the user
+     * from the queue.
+     * </ul>
+     * <p/>
+     * A user cannot request to join the queue again if already in the queue. Therefore,
+     * this method will throw an IllegalStateException if the user is already in the queue.<p>
+     * <p/>
+     * Some servers may be configured to require certain meta-data in order to
+     * join the queue.<p>
+     * <p/>
+     * The server tracks the conversations that a user has with agents over time. By
+     * default, that tracking is done using the user's JID. However, this is not always
+     * possible. For example, when the user is logged in anonymously using a web client.
+     * In that case the user ID might be a randomly generated value put into a persistent
+     * cookie or a username obtained via the session. A userID can be explicitly
+     * passed in by using the {@link #joinQueue(Form, String)} method. When specified,
+     * that userID will be used instead of the user's JID to track conversations. The
+     * server will ignore a manually specified userID if the user's connection to the server
+     * is not anonymous.
+     *
+     * @param answerForm the completed form the send for the join request.
+     * @throws XMPPException if an error occured joining the queue. An error may indicate
+     *                       that a connection failure occured or that the server explicitly rejected the
+     *                       request to join the queue.
+     */
+    public void joinQueue(Form answerForm) throws XMPPException {
+        joinQueue(answerForm, null);
+    }
+
+    /**
+     * <p>Joins the workgroup queue to wait to be routed to an agent. After joining
+     * the queue, queue status events will be sent to indicate the user's position and
+     * estimated time left in the queue. Once joining the queue, there are three ways
+     * the user can leave the queue: <ul>
+     * <p/>
+     * <li>The user is routed to an agent, which triggers a GroupChat invitation.
+     * <li>The user asks to leave the queue by calling the {@link #departQueue} method.
+     * <li>A server error occurs, or an administrator explicitly removes the user
+     * from the queue.
+     * </ul>
+     * <p/>
+     * A user cannot request to join the queue again if already in the queue. Therefore,
+     * this method will throw an IllegalStateException if the user is already in the queue.<p>
+     * <p/>
+     * Some servers may be configured to require certain meta-data in order to
+     * join the queue.<p>
+     * <p/>
+     * The server tracks the conversations that a user has with agents over time. By
+     * default, that tracking is done using the user's JID. However, this is not always
+     * possible. For example, when the user is logged in anonymously using a web client.
+     * In that case the user ID might be a randomly generated value put into a persistent
+     * cookie or a username obtained via the session. When specified, that userID will
+     * be used instead of the user's JID to track conversations. The server will ignore a
+     * manually specified userID if the user's connection to the server is not anonymous.
+     *
+     * @param answerForm the completed form associated with the join reqest.
+     * @param userID     String that represents the ID of the user when using anonymous sessions
+     *                   or <tt>null</tt> if a userID should not be used.
+     * @throws XMPPException if an error occured joining the queue. An error may indicate
+     *                       that a connection failure occured or that the server explicitly rejected the
+     *                       request to join the queue.
+     */
+    public void joinQueue(Form answerForm, String userID) throws XMPPException {
+        // If already in the queue ignore the join request.
+        if (inQueue) {
+            throw new IllegalStateException("Already in queue " + workgroupJID);
+        }
+
+        JoinQueuePacket joinPacket = new JoinQueuePacket(workgroupJID, answerForm, userID);
+
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(joinPacket.getPacketID()));
+
+        this.connection.sendPacket(joinPacket);
+
+        IQ response = (IQ)collector.nextResult(10000);
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from the server.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+
+        // Notify listeners that we've joined the queue.
+        fireQueueJoinedEvent();
+    }
+
+    /**
+     * <p>Joins the workgroup queue to wait to be routed to an agent. After joining
+     * the queue, queue status events will be sent to indicate the user's position and
+     * estimated time left in the queue. Once joining the queue, there are three ways
+     * the user can leave the queue: <ul>
+     * <p/>
+     * <li>The user is routed to an agent, which triggers a GroupChat invitation.
+     * <li>The user asks to leave the queue by calling the {@link #departQueue} method.
+     * <li>A server error occurs, or an administrator explicitly removes the user
+     * from the queue.
+     * </ul>
+     * <p/>
+     * A user cannot request to join the queue again if already in the queue. Therefore,
+     * this method will throw an IllegalStateException if the user is already in the queue.<p>
+     * <p/>
+     * Some servers may be configured to require certain meta-data in order to
+     * join the queue.<p>
+     * <p/>
+     * The server tracks the conversations that a user has with agents over time. By
+     * default, that tracking is done using the user's JID. However, this is not always
+     * possible. For example, when the user is logged in anonymously using a web client.
+     * In that case the user ID might be a randomly generated value put into a persistent
+     * cookie or a username obtained via the session. When specified, that userID will
+     * be used instead of the user's JID to track conversations. The server will ignore a
+     * manually specified userID if the user's connection to the server is not anonymous.
+     *
+     * @param metadata metadata to create a dataform from.
+     * @param userID   String that represents the ID of the user when using anonymous sessions
+     *                 or <tt>null</tt> if a userID should not be used.
+     * @throws XMPPException if an error occured joining the queue. An error may indicate
+     *                       that a connection failure occured or that the server explicitly rejected the
+     *                       request to join the queue.
+     */
+    public void joinQueue(Map<String,Object> metadata, String userID) throws XMPPException {
+        // If already in the queue ignore the join request.
+        if (inQueue) {
+            throw new IllegalStateException("Already in queue " + workgroupJID);
+        }
+
+        // Build dataform from metadata
+        Form form = new Form(Form.TYPE_SUBMIT);
+        Iterator<String> iter = metadata.keySet().iterator();
+        while (iter.hasNext()) {
+            String name = iter.next();
+            String value = metadata.get(name).toString();
+
+            String escapedName = StringUtils.escapeForXML(name);
+            String escapedValue = StringUtils.escapeForXML(value);
+
+            FormField field = new FormField(escapedName);
+            field.setType(FormField.TYPE_TEXT_SINGLE);
+            form.addField(field);
+            form.setAnswer(escapedName, escapedValue);
+        }
+        joinQueue(form, userID);
+    }
+
+    /**
+     * Departs the workgroup queue. If the user is not currently in the queue, this
+     * method will do nothing.<p>
+     * <p/>
+     * Normally, the user would not manually leave the queue. However, they may wish to
+     * under certain circumstances -- for example, if they no longer wish to be routed
+     * to an agent because they've been waiting too long.
+     *
+     * @throws XMPPException if an error occured trying to send the depart queue
+     *                       request to the server.
+     */
+    public void departQueue() throws XMPPException {
+        // If not in the queue ignore the depart request.
+        if (!inQueue) {
+            return;
+        }
+
+        DepartQueuePacket departPacket = new DepartQueuePacket(this.workgroupJID);
+        PacketCollector collector = this.connection.createPacketCollector(new PacketIDFilter(departPacket.getPacketID()));
+
+        connection.sendPacket(departPacket);
+
+        IQ response = (IQ)collector.nextResult(5000);
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from the server.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+
+        // Notify listeners that we're no longer in the queue.
+        fireQueueDepartedEvent();
+    }
+
+    /**
+     * Adds a queue listener that will be notified of queue events for the user
+     * that created this Workgroup instance.
+     *
+     * @param queueListener the queue listener.
+     */
+    public void addQueueListener(QueueListener queueListener) {
+        synchronized (queueListeners) {
+            if (!queueListeners.contains(queueListener)) {
+                queueListeners.add(queueListener);
+            }
+        }
+    }
+
+    /**
+     * Removes a queue listener.
+     *
+     * @param queueListener the queue listener.
+     */
+    public void removeQueueListener(QueueListener queueListener) {
+        synchronized (queueListeners) {
+            queueListeners.remove(queueListener);
+        }
+    }
+
+    /**
+     * Adds an invitation listener that will be notified of groupchat invitations
+     * from the workgroup for the the user that created this Workgroup instance.
+     *
+     * @param invitationListener the invitation listener.
+     */
+    public void addInvitationListener(WorkgroupInvitationListener invitationListener) {
+        synchronized (invitationListeners) {
+            if (!invitationListeners.contains(invitationListener)) {
+                invitationListeners.add(invitationListener);
+            }
+        }
+    }
+
+    /**
+     * Removes an invitation listener.
+     *
+     * @param invitationListener the invitation listener.
+     */
+    public void removeQueueListener(WorkgroupInvitationListener invitationListener) {
+        synchronized (invitationListeners) {
+            invitationListeners.remove(invitationListener);
+        }
+    }
+
+    private void fireInvitationEvent(WorkgroupInvitation invitation) {
+        synchronized (invitationListeners) {
+            for (Iterator<WorkgroupInvitationListener> i = invitationListeners.iterator(); i.hasNext();) {
+                WorkgroupInvitationListener listener = i.next();
+                listener.invitationReceived(invitation);
+            }
+        }
+    }
+
+    private void fireQueueJoinedEvent() {
+        synchronized (queueListeners) {
+            for (Iterator<QueueListener> i = queueListeners.iterator(); i.hasNext();) {
+                QueueListener listener = i.next();
+                listener.joinedQueue();
+            }
+        }
+    }
+
+    private void fireQueueDepartedEvent() {
+        synchronized (queueListeners) {
+            for (Iterator<QueueListener> i = queueListeners.iterator(); i.hasNext();) {
+                QueueListener listener = i.next();
+                listener.departedQueue();
+            }
+        }
+    }
+
+    private void fireQueuePositionEvent(int currentPosition) {
+        synchronized (queueListeners) {
+            for (Iterator<QueueListener> i = queueListeners.iterator(); i.hasNext();) {
+                QueueListener listener = i.next();
+                listener.queuePositionUpdated(currentPosition);
+            }
+        }
+    }
+
+    private void fireQueueTimeEvent(int secondsRemaining) {
+        synchronized (queueListeners) {
+            for (Iterator<QueueListener> i = queueListeners.iterator(); i.hasNext();) {
+                QueueListener listener = i.next();
+                listener.queueWaitTimeUpdated(secondsRemaining);
+            }
+        }
+    }
+
+    // PacketListener Implementation.
+
+    private void handlePacket(Packet packet) {
+        if (packet instanceof Message) {
+            Message msg = (Message)packet;
+            // Check to see if the user left the queue.
+            PacketExtension pe = msg.getExtension("depart-queue", "http://jabber.org/protocol/workgroup");
+            PacketExtension queueStatus = msg.getExtension("queue-status", "http://jabber.org/protocol/workgroup");
+
+            if (pe != null) {
+                fireQueueDepartedEvent();
+            }
+            else if (queueStatus != null) {
+                QueueUpdate queueUpdate = (QueueUpdate)queueStatus;
+                if (queueUpdate.getPosition() != -1) {
+                    fireQueuePositionEvent(queueUpdate.getPosition());
+                }
+                if (queueUpdate.getRemaingTime() != -1) {
+                    fireQueueTimeEvent(queueUpdate.getRemaingTime());
+                }
+            }
+
+            else {
+                // Check if a room invitation was sent and if the sender is the workgroup
+                MUCUser mucUser = (MUCUser)msg.getExtension("x", "http://jabber.org/protocol/muc#user");
+                MUCUser.Invite invite = mucUser != null ? mucUser.getInvite() : null;
+                if (invite != null && workgroupJID.equals(invite.getFrom())) {
+                    String sessionID = null;
+                    Map<String, List<String>> metaData = null;
+
+                    pe = msg.getExtension(SessionID.ELEMENT_NAME,
+                            SessionID.NAMESPACE);
+                    if (pe != null) {
+                        sessionID = ((SessionID)pe).getSessionID();
+                    }
+
+                    pe = msg.getExtension(MetaData.ELEMENT_NAME,
+                            MetaData.NAMESPACE);
+                    if (pe != null) {
+                        metaData = ((MetaData)pe).getMetaData();
+                    }
+
+                    WorkgroupInvitation inv = new WorkgroupInvitation(connection.getUser(), msg.getFrom(),
+                            workgroupJID, sessionID, msg.getBody(),
+                            msg.getFrom(), metaData);
+
+                    fireInvitationEvent(inv);
+                }
+            }
+        }
+    }
+
+    /**
+     * IQ packet to request joining the workgroup queue.
+     */
+    private class JoinQueuePacket extends IQ {
+
+        private String userID = null;
+        private DataForm form;
+
+        public JoinQueuePacket(String workgroup, Form answerForm, String userID) {
+            this.userID = userID;
+
+            setTo(workgroup);
+            setType(IQ.Type.SET);
+
+            form = answerForm.getDataFormToSend();
+            addExtension(form);
+        }
+
+        public String getChildElementXML() {
+            StringBuilder buf = new StringBuilder();
+
+            buf.append("<join-queue xmlns=\"http://jabber.org/protocol/workgroup\">");
+            buf.append("<queue-notifications/>");
+            // Add the user unique identification if the session is anonymous
+            if (connection.isAnonymous()) {
+                buf.append(new UserID(userID).toXML());
+            }
+
+            // Append data form text
+            buf.append(form.toXML());
+
+            buf.append("</join-queue>");
+
+            return buf.toString();
+        }
+    }
+
+    /**
+     * Returns a single chat setting based on it's identified key.
+     *
+     * @param key the key to find.
+     * @return the ChatSetting if found, otherwise false.
+     * @throws XMPPException if an error occurs while getting information from the server.
+     */
+    public ChatSetting getChatSetting(String key) throws XMPPException {
+        ChatSettings chatSettings = getChatSettings(key, -1);
+        return chatSettings.getFirstEntry();
+    }
+
+    /**
+     * Returns ChatSettings based on type.
+     *
+     * @param type the type of ChatSettings to return.
+     * @return the ChatSettings of given type, otherwise null.
+     * @throws XMPPException if an error occurs while getting information from the server.
+     */
+    public ChatSettings getChatSettings(int type) throws XMPPException {
+        return getChatSettings(null, type);
+    }
+
+    /**
+     * Returns all ChatSettings.
+     *
+     * @return all ChatSettings of a given workgroup.
+     * @throws XMPPException if an error occurs while getting information from the server.
+     */
+    public ChatSettings getChatSettings() throws XMPPException {
+        return getChatSettings(null, -1);
+    }
+
+
+    /**
+     * Asks the workgroup for it's Chat Settings.
+     *
+     * @return key specify a key to retrieve only that settings. Otherwise for all settings, key should be null.
+     * @throws XMPPException if an error occurs while getting information from the server.
+     */
+    private ChatSettings getChatSettings(String key, int type) throws XMPPException {
+        ChatSettings request = new ChatSettings();
+        if (key != null) {
+            request.setKey(key);
+        }
+        if (type != -1) {
+            request.setType(type);
+        }
+        request.setType(IQ.Type.GET);
+        request.setTo(workgroupJID);
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
+        connection.sendPacket(request);
+
+
+        ChatSettings response = (ChatSettings)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response;
+    }
+
+    /**
+     * The workgroup service may be configured to send email. This queries the Workgroup Service
+     * to see if the email service has been configured and is available.
+     *
+     * @return true if the email service is available, otherwise return false.
+     */
+    public boolean isEmailAvailable() {
+        ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);
+
+        try {
+            String workgroupService = StringUtils.parseServer(workgroupJID);
+            DiscoverInfo infoResult = discoManager.discoverInfo(workgroupService);
+            return infoResult.containsFeature("jive:email:provider");
+        }
+        catch (XMPPException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Asks the workgroup for it's Offline Settings.
+     *
+     * @return offlineSettings the offline settings for this workgroup.
+     * @throws XMPPException if an error occurs while getting information from the server.
+     */
+    public OfflineSettings getOfflineSettings() throws XMPPException {
+        OfflineSettings request = new OfflineSettings();
+        request.setType(IQ.Type.GET);
+        request.setTo(workgroupJID);
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
+        connection.sendPacket(request);
+
+
+        OfflineSettings response = (OfflineSettings)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response;
+    }
+
+    /**
+     * Asks the workgroup for it's Sound Settings.
+     *
+     * @return soundSettings the sound settings for the specified workgroup.
+     * @throws XMPPException if an error occurs while getting information from the server.
+     */
+    public SoundSettings getSoundSettings() throws XMPPException {
+        SoundSettings request = new SoundSettings();
+        request.setType(IQ.Type.GET);
+        request.setTo(workgroupJID);
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
+        connection.sendPacket(request);
+
+
+        SoundSettings response = (SoundSettings)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response;
+    }
+
+    /**
+     * Asks the workgroup for it's Properties
+     *
+     * @return the WorkgroupProperties for the specified workgroup.
+     * @throws XMPPException if an error occurs while getting information from the server.
+     */
+    public WorkgroupProperties getWorkgroupProperties() throws XMPPException {
+        WorkgroupProperties request = new WorkgroupProperties();
+        request.setType(IQ.Type.GET);
+        request.setTo(workgroupJID);
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
+        connection.sendPacket(request);
+
+
+        WorkgroupProperties response = (WorkgroupProperties)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response;
+    }
+
+    /**
+     * Asks the workgroup for it's Properties
+     *
+     * @param jid the jid of the user who's information you would like the workgroup to retreive.
+     * @return the WorkgroupProperties for the specified workgroup.
+     * @throws XMPPException if an error occurs while getting information from the server.
+     */
+    public WorkgroupProperties getWorkgroupProperties(String jid) throws XMPPException {
+        WorkgroupProperties request = new WorkgroupProperties();
+        request.setJid(jid);
+        request.setType(IQ.Type.GET);
+        request.setTo(workgroupJID);
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
+        connection.sendPacket(request);
+
+
+        WorkgroupProperties response = (WorkgroupProperties)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return response;
+    }
+
+
+    /**
+     * Returns the Form to use for all clients of a workgroup. It is unlikely that the server
+     * will change the form (without a restart) so it is safe to keep the returned form
+     * for future submissions.
+     *
+     * @return the Form to use for searching transcripts.
+     * @throws XMPPException if an error occurs while sending the request to the server.
+     */
+    public Form getWorkgroupForm() throws XMPPException {
+        WorkgroupForm workgroupForm = new WorkgroupForm();
+        workgroupForm.setType(IQ.Type.GET);
+        workgroupForm.setTo(workgroupJID);
+
+        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(workgroupForm.getPacketID()));
+        connection.sendPacket(workgroupForm);
+
+        WorkgroupForm response = (WorkgroupForm)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+        // Cancel the collector.
+        collector.cancel();
+        if (response == null) {
+            throw new XMPPException("No response from server on status set.");
+        }
+        if (response.getError() != null) {
+            throw new XMPPException(response.getError());
+        }
+        return Form.getFormFrom(response);
+    }
+
+    /*
+    public static void main(String args[]) throws Exception {
+        Connection con = new XMPPConnection("anteros");
+        con.connect();
+        con.loginAnonymously();
+
+        Workgroup workgroup = new Workgroup("demo@workgroup.anteros", con);
+        WorkgroupProperties props = workgroup.getWorkgroupProperties("derek@anteros.com");
+
+        System.out.print(props);
+        con.disconnect();
+    }
+    */
+
+
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/util/ListenerEventDispatcher.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/util/ListenerEventDispatcher.java
index 533b9a1..2376701 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/util/ListenerEventDispatcher.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/util/ListenerEventDispatcher.java
@@ -1,132 +1,132 @@
-/**
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.util;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.ListIterator;
-
-/**
- * This class is a very flexible event dispatcher which implements Runnable so that it can
- * dispatch easily from a newly created thread. The usage of this in code is more or less:
- * create a new instance of this class, use addListenerTriplet to add as many listeners
- * as desired to be messaged, create a new Thread using the instance of this class created
- * as the argument to the constructor, start the new Thread instance.<p>
- *
- * Also, this is intended to be used to message methods that either return void, or have
- * a return which the developer using this class is uninterested in receiving.
- *
- * @author loki der quaeler
- */
-public class ListenerEventDispatcher
-    implements Runnable {
-
-    protected transient ArrayList<TripletContainer> triplets;
-
-    protected transient boolean hasFinishedDispatching;
-    protected transient boolean isRunning;
-
-    public ListenerEventDispatcher () {
-        super();
-
-        this.triplets = new ArrayList<TripletContainer>();
-
-        this.hasFinishedDispatching = false;
-        this.isRunning = false;
-    }
-
-    /**
-     * Add a listener triplet - the instance of the listener to be messaged, the Method on which
-     *  the listener should be messaged, and the Object array of arguments to be supplied to the
-     *  Method. No attempts are made to determine whether this triplet was already added.<br>
-     *
-     * Messages are dispatched in the order in which they're added via this method; so if triplet
-     *  X is added after triplet Z, then triplet Z will undergo messaging prior to triplet X.<br>
-     *
-     * This method should not be called once the owning Thread instance has been started; if it
-     *  is called, the triplet will not be added to the messaging queue.<br>
-     *
-     * @param listenerInstance the instance of the listener to receive the associated notification
-     * @param listenerMethod the Method instance representing the method through which notification
-     *                          will occur
-     * @param methodArguments the arguments supplied to the notification method
-     */
-    public void addListenerTriplet(Object listenerInstance, Method listenerMethod,
-            Object[] methodArguments)
-    {
-        if (!this.isRunning) {
-            this.triplets.add(new TripletContainer(listenerInstance, listenerMethod,
-                    methodArguments));
-        }
-    }
-
-    /**
-     * @return whether this instance has finished dispatching its messages
-     */
-    public boolean hasFinished() {
-        return this.hasFinishedDispatching;
-    }
-
-    public void run() {
-        ListIterator<TripletContainer> li = null;
-
-        this.isRunning = true;
-
-        li = this.triplets.listIterator();
-        while (li.hasNext()) {
-            TripletContainer tc = li.next();
-
-            try {
-                tc.getListenerMethod().invoke(tc.getListenerInstance(), tc.getMethodArguments());
-            } catch (Exception e) {
-                System.err.println("Exception dispatching an event: " + e);
-
-                e.printStackTrace();
-            }
-        }
-
-        this.hasFinishedDispatching = true;
-    }
-
-
-    protected class TripletContainer {
-
-        protected Object listenerInstance;
-        protected Method listenerMethod;
-        protected Object[] methodArguments;
-
-        protected TripletContainer (Object inst, Method meth, Object[] args) {
-            super();
-
-            this.listenerInstance = inst;
-            this.listenerMethod = meth;
-            this.methodArguments = args;
-        }
-
-        protected Object getListenerInstance() {
-            return this.listenerInstance;
-        }
-
-        protected Method getListenerMethod() {
-            return this.listenerMethod;
-        }
-
-        protected Object[] getMethodArguments() {
-            return this.methodArguments;
-        }
-    }
+/**
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.util;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.ListIterator;
+
+/**
+ * This class is a very flexible event dispatcher which implements Runnable so that it can
+ * dispatch easily from a newly created thread. The usage of this in code is more or less:
+ * create a new instance of this class, use addListenerTriplet to add as many listeners
+ * as desired to be messaged, create a new Thread using the instance of this class created
+ * as the argument to the constructor, start the new Thread instance.<p>
+ *
+ * Also, this is intended to be used to message methods that either return void, or have
+ * a return which the developer using this class is uninterested in receiving.
+ *
+ * @author loki der quaeler
+ */
+public class ListenerEventDispatcher
+    implements Runnable {
+
+    protected transient ArrayList<TripletContainer> triplets;
+
+    protected transient boolean hasFinishedDispatching;
+    protected transient boolean isRunning;
+
+    public ListenerEventDispatcher () {
+        super();
+
+        this.triplets = new ArrayList<TripletContainer>();
+
+        this.hasFinishedDispatching = false;
+        this.isRunning = false;
+    }
+
+    /**
+     * Add a listener triplet - the instance of the listener to be messaged, the Method on which
+     *  the listener should be messaged, and the Object array of arguments to be supplied to the
+     *  Method. No attempts are made to determine whether this triplet was already added.<br>
+     *
+     * Messages are dispatched in the order in which they're added via this method; so if triplet
+     *  X is added after triplet Z, then triplet Z will undergo messaging prior to triplet X.<br>
+     *
+     * This method should not be called once the owning Thread instance has been started; if it
+     *  is called, the triplet will not be added to the messaging queue.<br>
+     *
+     * @param listenerInstance the instance of the listener to receive the associated notification
+     * @param listenerMethod the Method instance representing the method through which notification
+     *                          will occur
+     * @param methodArguments the arguments supplied to the notification method
+     */
+    public void addListenerTriplet(Object listenerInstance, Method listenerMethod,
+            Object[] methodArguments)
+    {
+        if (!this.isRunning) {
+            this.triplets.add(new TripletContainer(listenerInstance, listenerMethod,
+                    methodArguments));
+        }
+    }
+
+    /**
+     * @return whether this instance has finished dispatching its messages
+     */
+    public boolean hasFinished() {
+        return this.hasFinishedDispatching;
+    }
+
+    public void run() {
+        ListIterator<TripletContainer> li = null;
+
+        this.isRunning = true;
+
+        li = this.triplets.listIterator();
+        while (li.hasNext()) {
+            TripletContainer tc = li.next();
+
+            try {
+                tc.getListenerMethod().invoke(tc.getListenerInstance(), tc.getMethodArguments());
+            } catch (Exception e) {
+                System.err.println("Exception dispatching an event: " + e);
+
+                e.printStackTrace();
+            }
+        }
+
+        this.hasFinishedDispatching = true;
+    }
+
+
+    protected class TripletContainer {
+
+        protected Object listenerInstance;
+        protected Method listenerMethod;
+        protected Object[] methodArguments;
+
+        protected TripletContainer (Object inst, Method meth, Object[] args) {
+            super();
+
+            this.listenerInstance = inst;
+            this.listenerMethod = meth;
+            this.methodArguments = args;
+        }
+
+        protected Object getListenerInstance() {
+            return this.listenerInstance;
+        }
+
+        protected Method getListenerMethod() {
+            return this.listenerMethod;
+        }
+
+        protected Object[] getMethodArguments() {
+            return this.methodArguments;
+        }
+    }
 }
\ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/util/MetaDataUtils.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/util/MetaDataUtils.java
index 5be1c1a..7f8df0d 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/util/MetaDataUtils.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/util/MetaDataUtils.java
@@ -1,103 +1,103 @@
-/**
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.util;
-
-import org.jivesoftware.smackx.workgroup.MetaData;
-import org.jivesoftware.smack.util.StringUtils;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Utility class for meta-data parsing and writing.
- *
- * @author Matt Tucker
- */
-public class MetaDataUtils {
-
-    /**
-     * Parses any available meta-data and returns it as a Map of String name/value pairs. The
-     * parser must be positioned at an opening meta-data tag, or the an empty map will be returned.
-     *
-     * @param parser the XML parser positioned at an opening meta-data tag.
-     * @return the meta-data.
-     * @throws XmlPullParserException if an error occurs while parsing the XML.
-     * @throws IOException            if an error occurs while parsing the XML.
-     */
-    public static Map<String, List<String>> parseMetaData(XmlPullParser parser) throws XmlPullParserException, IOException {
-        int eventType = parser.getEventType();
-
-        // If correctly positioned on an opening meta-data tag, parse meta-data.
-        if ((eventType == XmlPullParser.START_TAG)
-                && parser.getName().equals(MetaData.ELEMENT_NAME)
-                && parser.getNamespace().equals(MetaData.NAMESPACE)) {
-            Map<String, List<String>> metaData = new Hashtable<String, List<String>>();
-
-            eventType = parser.nextTag();
-
-            // Keep parsing until we've gotten to end of meta-data.
-            while ((eventType != XmlPullParser.END_TAG)
-                    || (!parser.getName().equals(MetaData.ELEMENT_NAME))) {
-                String name = parser.getAttributeValue(0);
-                String value = parser.nextText();
-
-                if (metaData.containsKey(name)) {
-                    List<String> values = metaData.get(name);
-                    values.add(value);
-                }
-                else {
-                    List<String> values = new ArrayList<String>();
-                    values.add(value);
-                    metaData.put(name, values);
-                }
-
-                eventType = parser.nextTag();
-            }
-
-            return metaData;
-        }
-
-        return Collections.emptyMap();
-    }
-
-    /**
-     * Serializes a Map of String name/value pairs into the meta-data XML format.
-     *
-     * @param metaData the Map of meta-data as Map&lt;String,List&lt;String>>
-     * @return the meta-data values in XML form.
-     */
-    public static String serializeMetaData(Map<String, List<String>> metaData) {
-        StringBuilder buf = new StringBuilder();
-        if (metaData != null && metaData.size() > 0) {
-            buf.append("<metadata xmlns=\"http://jivesoftware.com/protocol/workgroup\">");
-            for (Iterator<String> i = metaData.keySet().iterator(); i.hasNext();) {
-                String key = i.next();
-                List<String> value = metaData.get(key);
-                for (Iterator<String> it = value.iterator(); it.hasNext();) {
-                    String v = it.next();
-                    buf.append("<value name=\"").append(key).append("\">");
-                    buf.append(StringUtils.escapeForXML(v));
-                    buf.append("</value>");
-                }
-            }
-            buf.append("</metadata>");
-        }
-        return buf.toString();
-    }
-}
+/**
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.util;
+
+import org.jivesoftware.smackx.workgroup.MetaData;
+import org.jivesoftware.smack.util.StringUtils;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Utility class for meta-data parsing and writing.
+ *
+ * @author Matt Tucker
+ */
+public class MetaDataUtils {
+
+    /**
+     * Parses any available meta-data and returns it as a Map of String name/value pairs. The
+     * parser must be positioned at an opening meta-data tag, or the an empty map will be returned.
+     *
+     * @param parser the XML parser positioned at an opening meta-data tag.
+     * @return the meta-data.
+     * @throws XmlPullParserException if an error occurs while parsing the XML.
+     * @throws IOException            if an error occurs while parsing the XML.
+     */
+    public static Map<String, List<String>> parseMetaData(XmlPullParser parser) throws XmlPullParserException, IOException {
+        int eventType = parser.getEventType();
+
+        // If correctly positioned on an opening meta-data tag, parse meta-data.
+        if ((eventType == XmlPullParser.START_TAG)
+                && parser.getName().equals(MetaData.ELEMENT_NAME)
+                && parser.getNamespace().equals(MetaData.NAMESPACE)) {
+            Map<String, List<String>> metaData = new Hashtable<String, List<String>>();
+
+            eventType = parser.nextTag();
+
+            // Keep parsing until we've gotten to end of meta-data.
+            while ((eventType != XmlPullParser.END_TAG)
+                    || (!parser.getName().equals(MetaData.ELEMENT_NAME))) {
+                String name = parser.getAttributeValue(0);
+                String value = parser.nextText();
+
+                if (metaData.containsKey(name)) {
+                    List<String> values = metaData.get(name);
+                    values.add(value);
+                }
+                else {
+                    List<String> values = new ArrayList<String>();
+                    values.add(value);
+                    metaData.put(name, values);
+                }
+
+                eventType = parser.nextTag();
+            }
+
+            return metaData;
+        }
+
+        return Collections.emptyMap();
+    }
+
+    /**
+     * Serializes a Map of String name/value pairs into the meta-data XML format.
+     *
+     * @param metaData the Map of meta-data as Map&lt;String,List&lt;String>>
+     * @return the meta-data values in XML form.
+     */
+    public static String serializeMetaData(Map<String, List<String>> metaData) {
+        StringBuilder buf = new StringBuilder();
+        if (metaData != null && metaData.size() > 0) {
+            buf.append("<metadata xmlns=\"http://jivesoftware.com/protocol/workgroup\">");
+            for (Iterator<String> i = metaData.keySet().iterator(); i.hasNext();) {
+                String key = i.next();
+                List<String> value = metaData.get(key);
+                for (Iterator<String> it = value.iterator(); it.hasNext();) {
+                    String v = it.next();
+                    buf.append("<value name=\"").append(key).append("\">");
+                    buf.append(StringUtils.escapeForXML(v));
+                    buf.append("</value>");
+                }
+            }
+            buf.append("</metadata>");
+        }
+        return buf.toString();
+    }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/util/ModelUtil.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/util/ModelUtil.java
index 06a72b0..7f0c59b 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/util/ModelUtil.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/workgroup/util/ModelUtil.java
@@ -1,321 +1,321 @@
-/**
- * Copyright 2003-2007 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smackx.workgroup.util;
-
-import java.util.*;
-
-/**
- * Utility methods frequently used by data classes and design-time
- * classes.
- */
-public final class ModelUtil {
-    private ModelUtil() {
-        //  Prevents instantiation.
-    }
-
-    /**
-     * This is a utility method that compares two objects when one or
-     * both of the objects might be <CODE>null</CODE>  The result of
-     * this method is determined as follows:
-     * <OL>
-     * <LI>If <CODE>o1</CODE> and <CODE>o2</CODE> are the same object
-     * according to the <CODE>==</CODE> operator, return
-     * <CODE>true</CODE>.
-     * <LI>Otherwise, if either <CODE>o1</CODE> or <CODE>o2</CODE> is
-     * <CODE>null</CODE>, return <CODE>false</CODE>.
-     * <LI>Otherwise, return <CODE>o1.equals(o2)</CODE>.
-     * </OL>
-     * <p/>
-     * This method produces the exact logically inverted result as the
-     * {@link #areDifferent(Object, Object)} method.<P>
-     * <p/>
-     * For array types, one of the <CODE>equals</CODE> methods in
-     * {@link java.util.Arrays} should be used instead of this method.
-     * Note that arrays with more than one dimension will require some
-     * custom code in order to implement <CODE>equals</CODE> properly.
-     */
-    public static final boolean areEqual(Object o1, Object o2) {
-        if (o1 == o2) {
-            return true;
-        }
-        else if (o1 == null || o2 == null) {
-            return false;
-        }
-        else {
-            return o1.equals(o2);
-        }
-    }
-
-    /**
-     * This is a utility method that compares two Booleans when one or
-     * both of the objects might be <CODE>null</CODE>  The result of
-     * this method is determined as follows:
-     * <OL>
-     * <LI>If <CODE>b1</CODE> and <CODE>b2</CODE> are both TRUE or
-     * neither <CODE>b1</CODE> nor <CODE>b2</CODE> is TRUE,
-     * return <CODE>true</CODE>.
-     * <LI>Otherwise, return <CODE>false</CODE>.
-     * </OL>
-     * <p/>
-     */
-    public static final boolean areBooleansEqual(Boolean b1, Boolean b2) {
-        // !jwetherb treat NULL the same as Boolean.FALSE
-        return (b1 == Boolean.TRUE && b2 == Boolean.TRUE) ||
-                (b1 != Boolean.TRUE && b2 != Boolean.TRUE);
-    }
-
-    /**
-     * This is a utility method that compares two objects when one or
-     * both of the objects might be <CODE>null</CODE>.  The result
-     * returned by this method is determined as follows:
-     * <OL>
-     * <LI>If <CODE>o1</CODE> and <CODE>o2</CODE> are the same object
-     * according to the <CODE>==</CODE> operator, return
-     * <CODE>false</CODE>.
-     * <LI>Otherwise, if either <CODE>o1</CODE> or <CODE>o2</CODE> is
-     * <CODE>null</CODE>, return <CODE>true</CODE>.
-     * <LI>Otherwise, return <CODE>!o1.equals(o2)</CODE>.
-     * </OL>
-     * <p/>
-     * This method produces the exact logically inverted result as the
-     * {@link #areEqual(Object, Object)} method.<P>
-     * <p/>
-     * For array types, one of the <CODE>equals</CODE> methods in
-     * {@link java.util.Arrays} should be used instead of this method.
-     * Note that arrays with more than one dimension will require some
-     * custom code in order to implement <CODE>equals</CODE> properly.
-     */
-    public static final boolean areDifferent(Object o1, Object o2) {
-        return !areEqual(o1, o2);
-    }
-
-
-    /**
-     * This is a utility method that compares two Booleans when one or
-     * both of the objects might be <CODE>null</CODE>  The result of
-     * this method is determined as follows:
-     * <OL>
-     * <LI>If <CODE>b1</CODE> and <CODE>b2</CODE> are both TRUE or
-     * neither <CODE>b1</CODE> nor <CODE>b2</CODE> is TRUE,
-     * return <CODE>false</CODE>.
-     * <LI>Otherwise, return <CODE>true</CODE>.
-     * </OL>
-     * <p/>
-     * This method produces the exact logically inverted result as the
-     * {@link #areBooleansEqual(Boolean, Boolean)} method.<P>
-     */
-    public static final boolean areBooleansDifferent(Boolean b1, Boolean b2) {
-        return !areBooleansEqual(b1, b2);
-    }
-
-
-    /**
-     * Returns <CODE>true</CODE> if the specified array is not null
-     * and contains a non-null element.  Returns <CODE>false</CODE>
-     * if the array is null or if all the array elements are null.
-     */
-    public static final boolean hasNonNullElement(Object[] array) {
-        if (array != null) {
-            final int n = array.length;
-            for (int i = 0; i < n; i++) {
-                if (array[i] != null) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns a single string that is the concatenation of all the
-     * strings in the specified string array.  A single space is
-     * put between each string array element.  Null array elements
-     * are skipped.  If the array itself is null, the empty string
-     * is returned.  This method is guaranteed to return a non-null
-     * value, if no expections are thrown.
-     */
-    public static final String concat(String[] strs) {
-        return concat(strs, " ");  //NOTRANS
-    }
-
-    /**
-     * Returns a single string that is the concatenation of all the
-     * strings in the specified string array.  The strings are separated
-     * by the specified delimiter.  Null array elements are skipped.  If
-     * the array itself is null, the empty string is returned.  This
-     * method is guaranteed to return a non-null value, if no expections
-     * are thrown.
-     */
-    public static final String concat(String[] strs, String delim) {
-        if (strs != null) {
-            final StringBuilder buf = new StringBuilder();
-            final int n = strs.length;
-            for (int i = 0; i < n; i++) {
-                final String str = strs[i];
-                if (str != null) {
-                    buf.append(str).append(delim);
-                }
-            }
-            final int length = buf.length();
-            if (length > 0) {
-                //  Trim trailing space.
-                buf.setLength(length - 1);
-            }
-            return buf.toString();
-        }
-        else {
-            return ""; // NOTRANS
-        }
-    }
-
-    /**
-     * Returns <CODE>true</CODE> if the specified {@link String} is not
-     * <CODE>null</CODE> and has a length greater than zero.  This is
-     * a very frequently occurring check.
-     */
-    public static final boolean hasLength(String s) {
-        return (s != null && s.length() > 0);
-    }
-
-
-    /**
-     * Returns <CODE>null</CODE> if the specified string is empty or
-     * <CODE>null</CODE>.  Otherwise the string itself is returned.
-     */
-    public static final String nullifyIfEmpty(String s) {
-        return ModelUtil.hasLength(s) ? s : null;
-    }
-
-    /**
-     * Returns <CODE>null</CODE> if the specified object is null
-     * or if its <CODE>toString()</CODE> representation is empty.
-     * Otherwise, the <CODE>toString()</CODE> representation of the
-     * object itself is returned.
-     */
-    public static final String nullifyingToString(Object o) {
-        return o != null ? nullifyIfEmpty(o.toString()) : null;
-    }
-
-    /**
-     * Determines if a string has been changed.
-     *
-     * @param oldString is the initial value of the String
-     * @param newString is the new value of the String
-     * @return true If both oldString and newString are null or if they are
-     *         both not null and equal to each other.  Otherwise returns false.
-     */
-    public static boolean hasStringChanged(String oldString, String newString) {
-        if (oldString == null && newString == null) {
-            return false;
-        }
-        else if ((oldString == null && newString != null)
-                || (oldString != null && newString == null)) {
-            return true;
-        }
-        else {
-            return !oldString.equals(newString);
-        }
-    }
-
-    public static String getTimeFromLong(long diff) {
-        final String HOURS = "h";
-        final String MINUTES = "min";
-        final String SECONDS = "sec";
-
-        final long MS_IN_A_DAY = 1000 * 60 * 60 * 24;
-        final long MS_IN_AN_HOUR = 1000 * 60 * 60;
-        final long MS_IN_A_MINUTE = 1000 * 60;
-        final long MS_IN_A_SECOND = 1000;
-        diff = diff % MS_IN_A_DAY;
-        long numHours = diff / MS_IN_AN_HOUR;
-        diff = diff % MS_IN_AN_HOUR;
-        long numMinutes = diff / MS_IN_A_MINUTE;
-        diff = diff % MS_IN_A_MINUTE;
-        long numSeconds = diff / MS_IN_A_SECOND;
-        diff = diff % MS_IN_A_SECOND;
-
-        StringBuilder buf = new StringBuilder();
-        if (numHours > 0) {
-            buf.append(numHours + " " + HOURS + ", ");
-        }
-
-        if (numMinutes > 0) {
-            buf.append(numMinutes + " " + MINUTES + ", ");
-        }
-
-        buf.append(numSeconds + " " + SECONDS);
-
-        String result = buf.toString();
-        return result;
-    }
-
-
-    /**
-     * Build a List of all elements in an Iterator.
-     */
-    public static <T> List<T> iteratorAsList(Iterator<T> i) {
-        ArrayList<T> list = new ArrayList<T>(10);
-        while (i.hasNext()) {
-            list.add(i.next());
-        }
-        return list;
-    }
-
-    /**
-     * Creates an Iterator that is the reverse of a ListIterator.
-     */
-    public static <T> Iterator<T> reverseListIterator(ListIterator<T> i) {
-        return new ReverseListIterator<T>(i);
-    }
-}
-
-/**
- * An Iterator that is the reverse of a ListIterator.
- */
-class ReverseListIterator<T> implements Iterator<T> {
-    private ListIterator<T> _i;
-
-    ReverseListIterator(ListIterator<T> i) {
-        _i = i;
-        while (_i.hasNext())
-            _i.next();
-    }
-
-    public boolean hasNext() {
-        return _i.hasPrevious();
-    }
-
-    public T next() {
-        return _i.previous();
-    }
-
-    public void remove() {
-        _i.remove();
-    }
-
-}
-
-
-
-
-
-
-
-
-
-
-
+/**
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.workgroup.util;
+
+import java.util.*;
+
+/**
+ * Utility methods frequently used by data classes and design-time
+ * classes.
+ */
+public final class ModelUtil {
+    private ModelUtil() {
+        //  Prevents instantiation.
+    }
+
+    /**
+     * This is a utility method that compares two objects when one or
+     * both of the objects might be <CODE>null</CODE>  The result of
+     * this method is determined as follows:
+     * <OL>
+     * <LI>If <CODE>o1</CODE> and <CODE>o2</CODE> are the same object
+     * according to the <CODE>==</CODE> operator, return
+     * <CODE>true</CODE>.
+     * <LI>Otherwise, if either <CODE>o1</CODE> or <CODE>o2</CODE> is
+     * <CODE>null</CODE>, return <CODE>false</CODE>.
+     * <LI>Otherwise, return <CODE>o1.equals(o2)</CODE>.
+     * </OL>
+     * <p/>
+     * This method produces the exact logically inverted result as the
+     * {@link #areDifferent(Object, Object)} method.<P>
+     * <p/>
+     * For array types, one of the <CODE>equals</CODE> methods in
+     * {@link java.util.Arrays} should be used instead of this method.
+     * Note that arrays with more than one dimension will require some
+     * custom code in order to implement <CODE>equals</CODE> properly.
+     */
+    public static final boolean areEqual(Object o1, Object o2) {
+        if (o1 == o2) {
+            return true;
+        }
+        else if (o1 == null || o2 == null) {
+            return false;
+        }
+        else {
+            return o1.equals(o2);
+        }
+    }
+
+    /**
+     * This is a utility method that compares two Booleans when one or
+     * both of the objects might be <CODE>null</CODE>  The result of
+     * this method is determined as follows:
+     * <OL>
+     * <LI>If <CODE>b1</CODE> and <CODE>b2</CODE> are both TRUE or
+     * neither <CODE>b1</CODE> nor <CODE>b2</CODE> is TRUE,
+     * return <CODE>true</CODE>.
+     * <LI>Otherwise, return <CODE>false</CODE>.
+     * </OL>
+     * <p/>
+     */
+    public static final boolean areBooleansEqual(Boolean b1, Boolean b2) {
+        // !jwetherb treat NULL the same as Boolean.FALSE
+        return (b1 == Boolean.TRUE && b2 == Boolean.TRUE) ||
+                (b1 != Boolean.TRUE && b2 != Boolean.TRUE);
+    }
+
+    /**
+     * This is a utility method that compares two objects when one or
+     * both of the objects might be <CODE>null</CODE>.  The result
+     * returned by this method is determined as follows:
+     * <OL>
+     * <LI>If <CODE>o1</CODE> and <CODE>o2</CODE> are the same object
+     * according to the <CODE>==</CODE> operator, return
+     * <CODE>false</CODE>.
+     * <LI>Otherwise, if either <CODE>o1</CODE> or <CODE>o2</CODE> is
+     * <CODE>null</CODE>, return <CODE>true</CODE>.
+     * <LI>Otherwise, return <CODE>!o1.equals(o2)</CODE>.
+     * </OL>
+     * <p/>
+     * This method produces the exact logically inverted result as the
+     * {@link #areEqual(Object, Object)} method.<P>
+     * <p/>
+     * For array types, one of the <CODE>equals</CODE> methods in
+     * {@link java.util.Arrays} should be used instead of this method.
+     * Note that arrays with more than one dimension will require some
+     * custom code in order to implement <CODE>equals</CODE> properly.
+     */
+    public static final boolean areDifferent(Object o1, Object o2) {
+        return !areEqual(o1, o2);
+    }
+
+
+    /**
+     * This is a utility method that compares two Booleans when one or
+     * both of the objects might be <CODE>null</CODE>  The result of
+     * this method is determined as follows:
+     * <OL>
+     * <LI>If <CODE>b1</CODE> and <CODE>b2</CODE> are both TRUE or
+     * neither <CODE>b1</CODE> nor <CODE>b2</CODE> is TRUE,
+     * return <CODE>false</CODE>.
+     * <LI>Otherwise, return <CODE>true</CODE>.
+     * </OL>
+     * <p/>
+     * This method produces the exact logically inverted result as the
+     * {@link #areBooleansEqual(Boolean, Boolean)} method.<P>
+     */
+    public static final boolean areBooleansDifferent(Boolean b1, Boolean b2) {
+        return !areBooleansEqual(b1, b2);
+    }
+
+
+    /**
+     * Returns <CODE>true</CODE> if the specified array is not null
+     * and contains a non-null element.  Returns <CODE>false</CODE>
+     * if the array is null or if all the array elements are null.
+     */
+    public static final boolean hasNonNullElement(Object[] array) {
+        if (array != null) {
+            final int n = array.length;
+            for (int i = 0; i < n; i++) {
+                if (array[i] != null) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns a single string that is the concatenation of all the
+     * strings in the specified string array.  A single space is
+     * put between each string array element.  Null array elements
+     * are skipped.  If the array itself is null, the empty string
+     * is returned.  This method is guaranteed to return a non-null
+     * value, if no expections are thrown.
+     */
+    public static final String concat(String[] strs) {
+        return concat(strs, " ");  //NOTRANS
+    }
+
+    /**
+     * Returns a single string that is the concatenation of all the
+     * strings in the specified string array.  The strings are separated
+     * by the specified delimiter.  Null array elements are skipped.  If
+     * the array itself is null, the empty string is returned.  This
+     * method is guaranteed to return a non-null value, if no expections
+     * are thrown.
+     */
+    public static final String concat(String[] strs, String delim) {
+        if (strs != null) {
+            final StringBuilder buf = new StringBuilder();
+            final int n = strs.length;
+            for (int i = 0; i < n; i++) {
+                final String str = strs[i];
+                if (str != null) {
+                    buf.append(str).append(delim);
+                }
+            }
+            final int length = buf.length();
+            if (length > 0) {
+                //  Trim trailing space.
+                buf.setLength(length - 1);
+            }
+            return buf.toString();
+        }
+        else {
+            return ""; // NOTRANS
+        }
+    }
+
+    /**
+     * Returns <CODE>true</CODE> if the specified {@link String} is not
+     * <CODE>null</CODE> and has a length greater than zero.  This is
+     * a very frequently occurring check.
+     */
+    public static final boolean hasLength(String s) {
+        return (s != null && s.length() > 0);
+    }
+
+
+    /**
+     * Returns <CODE>null</CODE> if the specified string is empty or
+     * <CODE>null</CODE>.  Otherwise the string itself is returned.
+     */
+    public static final String nullifyIfEmpty(String s) {
+        return ModelUtil.hasLength(s) ? s : null;
+    }
+
+    /**
+     * Returns <CODE>null</CODE> if the specified object is null
+     * or if its <CODE>toString()</CODE> representation is empty.
+     * Otherwise, the <CODE>toString()</CODE> representation of the
+     * object itself is returned.
+     */
+    public static final String nullifyingToString(Object o) {
+        return o != null ? nullifyIfEmpty(o.toString()) : null;
+    }
+
+    /**
+     * Determines if a string has been changed.
+     *
+     * @param oldString is the initial value of the String
+     * @param newString is the new value of the String
+     * @return true If both oldString and newString are null or if they are
+     *         both not null and equal to each other.  Otherwise returns false.
+     */
+    public static boolean hasStringChanged(String oldString, String newString) {
+        if (oldString == null && newString == null) {
+            return false;
+        }
+        else if ((oldString == null && newString != null)
+                || (oldString != null && newString == null)) {
+            return true;
+        }
+        else {
+            return !oldString.equals(newString);
+        }
+    }
+
+    public static String getTimeFromLong(long diff) {
+        final String HOURS = "h";
+        final String MINUTES = "min";
+        final String SECONDS = "sec";
+
+        final long MS_IN_A_DAY = 1000 * 60 * 60 * 24;
+        final long MS_IN_AN_HOUR = 1000 * 60 * 60;
+        final long MS_IN_A_MINUTE = 1000 * 60;
+        final long MS_IN_A_SECOND = 1000;
+        diff = diff % MS_IN_A_DAY;
+        long numHours = diff / MS_IN_AN_HOUR;
+        diff = diff % MS_IN_AN_HOUR;
+        long numMinutes = diff / MS_IN_A_MINUTE;
+        diff = diff % MS_IN_A_MINUTE;
+        long numSeconds = diff / MS_IN_A_SECOND;
+        diff = diff % MS_IN_A_SECOND;
+
+        StringBuilder buf = new StringBuilder();
+        if (numHours > 0) {
+            buf.append(numHours + " " + HOURS + ", ");
+        }
+
+        if (numMinutes > 0) {
+            buf.append(numMinutes + " " + MINUTES + ", ");
+        }
+
+        buf.append(numSeconds + " " + SECONDS);
+
+        String result = buf.toString();
+        return result;
+    }
+
+
+    /**
+     * Build a List of all elements in an Iterator.
+     */
+    public static <T> List<T> iteratorAsList(Iterator<T> i) {
+        ArrayList<T> list = new ArrayList<T>(10);
+        while (i.hasNext()) {
+            list.add(i.next());
+        }
+        return list;
+    }
+
+    /**
+     * Creates an Iterator that is the reverse of a ListIterator.
+     */
+    public static <T> Iterator<T> reverseListIterator(ListIterator<T> i) {
+        return new ReverseListIterator<T>(i);
+    }
+}
+
+/**
+ * An Iterator that is the reverse of a ListIterator.
+ */
+class ReverseListIterator<T> implements Iterator<T> {
+    private ListIterator<T> _i;
+
+    ReverseListIterator(ListIterator<T> i) {
+        _i = i;
+        while (_i.hasNext())
+            _i.next();
+    }
+
+    public boolean hasNext() {
+        return _i.hasPrevious();
+    }
+
+    public T next() {
+        return _i.previous();
+    }
+
+    public void remove() {
+        _i.remove();
+    }
+
+}
+
+
+
+
+
+
+
+
+
+
+
