/**
 * $RCSfile$
 * $Revision$
 * $Date$
 *
 * Copyright 2009 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 java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;

import org.jivesoftware.smack.compression.JzlibInputOutputStream;
import org.jivesoftware.smack.compression.XMPPInputOutputStream;
import org.jivesoftware.smack.compression.Java7ZlibInputOutputStream;
import org.jivesoftware.smack.debugger.SmackDebugger;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;

/**
 * The abstract Connection class provides an interface for connections to a
 * XMPP server and implements shared methods which are used by the
 * different types of connections (e.g. XMPPConnection or BoshConnection).
 * 
 * To create a connection to a XMPP server a simple usage of this API might
 * look like the following:
 * <pre>
 * // Create a connection to the igniterealtime.org XMPP server.
 * Connection con = new XMPPConnection("igniterealtime.org");
 * // Connect to the server
 * con.connect();
 * // Most servers require you to login before performing other tasks.
 * con.login("jsmith", "mypass");
 * // Start a new conversation with John Doe and send him a message.
 * Chat chat = connection.getChatManager().createChat("jdoe@igniterealtime.org"</font>, new MessageListener() {
 * <p/>
 *     public void processMessage(Chat chat, Message message) {
 *         // Print out any messages we get back to standard out.
 *         System.out.println(<font color="green">"Received message: "</font> + message);
 *     }
 * });
 * chat.sendMessage(<font color="green">"Howdy!"</font>);
 * // Disconnect from the server
 * con.disconnect();
 * </pre>
 * <p/>
 * Connections can be reused between connections. This means that an Connection
 * may be connected, disconnected and then connected again. Listeners of the Connection
 * will be retained accross connections.<p>
 * <p/>
 * If a connected Connection gets disconnected abruptly then it will try to reconnect
 * again. To stop the reconnection process, use {@link #disconnect()}. Once stopped
 * you can use {@link #connect()} to manually connect to the server.
 * 
 * @see XMPPConnection
 * @author Matt Tucker
 * @author Guenther Niess
 */
public abstract class Connection {

    /** 
     * Counter to uniquely identify connections that are created.
     */
    private final static AtomicInteger connectionCounter = new AtomicInteger(0);

    /**
     * A set of listeners which will be invoked if a new connection is created.
     */
    private final static Set<ConnectionCreationListener> connectionEstablishedListeners =
            new CopyOnWriteArraySet<ConnectionCreationListener>();

    protected final static List<XMPPInputOutputStream> compressionHandlers = new ArrayList<XMPPInputOutputStream>(2);

    /**
     * Value that indicates whether debugging is enabled. When enabled, a debug
     * window will apear for each new connection that will contain the following
     * information:<ul>
     * <li> Client Traffic -- raw XML traffic generated by Smack and sent to the server.
     * <li> Server Traffic -- raw XML traffic sent by the server to the client.
     * <li> Interpreted Packets -- shows XML packets from the server as parsed by Smack.
     * </ul>
     * <p/>
     * Debugging can be enabled by setting this field to true, or by setting the Java system
     * property <tt>smack.debugEnabled</tt> to true. The system property can be set on the
     * command line such as "java SomeApp -Dsmack.debugEnabled=true".
     */
    public static boolean DEBUG_ENABLED = false;

    static {
        // Use try block since we may not have permission to get a system
        // property (for example, when an applet).
        try {
            DEBUG_ENABLED = Boolean.getBoolean("smack.debugEnabled");
        }
        catch (Exception e) {
            // Ignore.
        }
        // Ensure the SmackConfiguration class is loaded by calling a method in it.
        SmackConfiguration.getVersion();
        // Add the Java7 compression handler first, since it's preferred
        compressionHandlers.add(new Java7ZlibInputOutputStream());
        // If we don't have access to the Java7 API use the JZlib compression handler
        compressionHandlers.add(new JzlibInputOutputStream());
    }

    /**
     * A collection of ConnectionListeners which listen for connection closing
     * and reconnection events.
     */
    protected final Collection<ConnectionListener> connectionListeners =
            new CopyOnWriteArrayList<ConnectionListener>();

    /**
     * A collection of PacketCollectors which collects packets for a specified filter
     * and perform blocking and polling operations on the result queue.
     */
    protected final Collection<PacketCollector> collectors = new ConcurrentLinkedQueue<PacketCollector>();

    /**
     * List of PacketListeners that will be notified when a new packet was received.
     */
    protected final Map<PacketListener, ListenerWrapper> recvListeners =
            new ConcurrentHashMap<PacketListener, ListenerWrapper>();

    /**
     * List of PacketListeners that will be notified when a new packet was sent.
     */
    protected final Map<PacketListener, ListenerWrapper> sendListeners =
            new ConcurrentHashMap<PacketListener, ListenerWrapper>();

    /**
     * List of PacketInterceptors that will be notified when a new packet is about to be
     * sent to the server. These interceptors may modify the packet before it is being
     * actually sent to the server.
     */
    protected final Map<PacketInterceptor, InterceptorWrapper> interceptors =
            new ConcurrentHashMap<PacketInterceptor, InterceptorWrapper>();

    /**
     * The AccountManager allows creation and management of accounts on an XMPP server.
     */
    private AccountManager accountManager = null;

    /**
     * The ChatManager keeps track of references to all current chats.
     */
    protected ChatManager chatManager = null;

    /**
     * The SmackDebugger allows to log and debug XML traffic.
     */
    protected SmackDebugger debugger = null;

    /**
     * The Reader which is used for the {@see debugger}.
     */
    protected Reader reader;

    /**
     * The Writer which is used for the {@see debugger}.
     */
    protected Writer writer;
    
    /**
     * The permanent storage for the roster
     */
    protected RosterStorage rosterStorage;


    /**
     * The SASLAuthentication manager that is responsible for authenticating with the server.
     */
    protected SASLAuthentication saslAuthentication = new SASLAuthentication(this);

    /**
     * A number to uniquely identify connections that are created. This is distinct from the
     * connection ID, which is a value sent by the server once a connection is made.
     */
    protected final int connectionCounterValue = connectionCounter.getAndIncrement();

    /**
     * Holds the initial configuration used while creating the connection.
     */
    protected final ConnectionConfiguration config;

    /**
     * Holds the Caps Node information for the used XMPP service (i.e. the XMPP server)
     */
    private String serviceCapsNode;

    protected XMPPInputOutputStream compressionHandler;

    /**
     * Create a new Connection to a XMPP server.
     * 
     * @param configuration The configuration which is used to establish the connection.
     */
    protected Connection(ConnectionConfiguration configuration) {
        config = configuration;
    }

    /**
     * Returns the configuration used to connect to the server.
     * 
     * @return the configuration used to connect to the server.
     */
    protected ConnectionConfiguration getConfiguration() {
        return config;
    }

    /**
     * Returns the name of the service provided by the XMPP server for this connection.
     * This is also called XMPP domain of the connected server. After
     * authenticating with the server the returned value may be different.
     * 
     * @return the name of the service provided by the XMPP server.
     */
    public String getServiceName() {
        return config.getServiceName();
    }

    /**
     * Returns the host name of the server where the XMPP server is running. This would be the
     * IP address of the server or a name that may be resolved by a DNS server.
     * 
     * @return the host name of the server where the XMPP server is running.
     */
    public String getHost() {
        return config.getHost();
    }

    /**
     * Returns the port number of the XMPP server for this connection. The default port
     * for normal connections is 5222. The default port for SSL connections is 5223.
     * 
     * @return the port number of the XMPP server.
     */
    public int getPort() {
        return config.getPort();
    }

    /**
     * Returns the full XMPP address of the user that is logged in to the connection or
     * <tt>null</tt> if not logged in yet. An XMPP address is in the form
     * username@server/resource.
     * 
     * @return the full XMPP address of the user logged in.
     */
    public abstract String getUser();

    /**
     * Returns the connection ID for this connection, which is the value set by the server
     * when opening a XMPP stream. If the server does not set a connection ID, this value
     * will be null. This value will be <tt>null</tt> if not connected to the server.
     * 
     * @return the ID of this connection returned from the XMPP server or <tt>null</tt> if
     *      not connected to the server.
     */
    public abstract String getConnectionID();

    /**
     * Returns true if currently connected to the XMPP server.
     * 
     * @return true if connected.
     */
    public abstract boolean isConnected();

    /**
     * Returns true if currently authenticated by successfully calling the login method.
     * 
     * @return true if authenticated.
     */
    public abstract boolean isAuthenticated();

    /**
     * Returns true if currently authenticated anonymously.
     * 
     * @return true if authenticated anonymously.
     */
    public abstract boolean isAnonymous();

    /**
     * Returns true if the connection to the server has successfully negotiated encryption. 
     * 
     * @return true if a secure connection to the server.
     */
    public abstract boolean isSecureConnection();

    /**
     * Returns if the reconnection mechanism is allowed to be used. By default
     * reconnection is allowed.
     * 
     * @return true if the reconnection mechanism is allowed to be used.
     */
    protected boolean isReconnectionAllowed() {
        return config.isReconnectionAllowed();
    }

    /**
     * Returns true if network traffic is being compressed. When using stream compression network
     * traffic can be reduced up to 90%. Therefore, stream compression is ideal when using a slow
     * speed network connection. However, the server will need to use more CPU time in order to
     * un/compress network data so under high load the server performance might be affected.
     * 
     * @return true if network traffic is being compressed.
     */
    public abstract boolean isUsingCompression();

    /**
     * Establishes a connection to the XMPP server and performs an automatic login
     * only if the previous connection state was logged (authenticated). It basically
     * creates and maintains a connection to the server.<p>
     * <p/>
     * Listeners will be preserved from a previous connection if the reconnection
     * occurs after an abrupt termination.
     * 
     * @throws XMPPException if an error occurs while trying to establish the connection.
     */
    public abstract void connect() throws XMPPException;

    /**
     * Logs in to the server using the strongest authentication mode supported by
     * the server, then sets presence to available. If the server supports SASL authentication 
     * then the user will be authenticated using SASL if not Non-SASL authentication will 
     * be tried. If more than five seconds (default timeout) elapses in each step of the 
     * authentication process without a response from the server, or if an error occurs, a 
     * XMPPException will be thrown.<p>
     * 
     * Before logging in (i.e. authenticate) to the server the connection must be connected.
     * 
     * It is possible to log in without sending an initial available presence by using
     * {@link ConnectionConfiguration#setSendPresence(boolean)}. If this connection is
     * not interested in loading its roster upon login then use
     * {@link ConnectionConfiguration#setRosterLoadedAtLogin(boolean)}.
     * Finally, if you want to not pass a password and instead use a more advanced mechanism
     * while using SASL then you may be interested in using
     * {@link ConnectionConfiguration#setCallbackHandler(javax.security.auth.callback.CallbackHandler)}.
     * For more advanced login settings see {@link ConnectionConfiguration}.
     * 
     * @param username the username.
     * @param password the password or <tt>null</tt> if using a CallbackHandler.
     * @throws XMPPException if an error occurs.
     */
    public void login(String username, String password) throws XMPPException {
        login(username, password, "Smack");
    }

    /**
     * Logs in to the server using the strongest authentication mode supported by
     * the server, then sets presence to available. If the server supports SASL authentication 
     * then the user will be authenticated using SASL if not Non-SASL authentication will 
     * be tried. If more than five seconds (default timeout) elapses in each step of the 
     * authentication process without a response from the server, or if an error occurs, a 
     * XMPPException will be thrown.<p>
     * 
     * Before logging in (i.e. authenticate) to the server the connection must be connected.
     * 
     * It is possible to log in without sending an initial available presence by using
     * {@link ConnectionConfiguration#setSendPresence(boolean)}. If this connection is
     * not interested in loading its roster upon login then use
     * {@link ConnectionConfiguration#setRosterLoadedAtLogin(boolean)}.
     * Finally, if you want to not pass a password and instead use a more advanced mechanism
     * while using SASL then you may be interested in using
     * {@link ConnectionConfiguration#setCallbackHandler(javax.security.auth.callback.CallbackHandler)}.
     * For more advanced login settings see {@link ConnectionConfiguration}.
     * 
     * @param username the username.
     * @param password the password or <tt>null</tt> if using a CallbackHandler.
     * @param resource the resource.
     * @throws XMPPException if an error occurs.
     * @throws IllegalStateException if not connected to the server, or already logged in
     *      to the serrver.
     */
    public abstract void login(String username, String password, String resource) throws XMPPException;

    /**
     * Logs in to the server anonymously. Very few servers are configured to support anonymous
     * authentication, so it's fairly likely logging in anonymously will fail. If anonymous login
     * does succeed, your XMPP address will likely be in the form "123ABC@server/789XYZ" or
     * "server/123ABC" (where "123ABC" and "789XYZ" is a random value generated by the server).
     * 
     * @throws XMPPException if an error occurs or anonymous logins are not supported by the server.
     * @throws IllegalStateException if not connected to the server, or already logged in
     *      to the serrver.
     */
    public abstract void loginAnonymously() throws XMPPException;

    /**
     * Sends the specified packet to the server.
     * 
     * @param packet the packet to send.
     */
    public abstract void sendPacket(Packet packet);

    /**
     * Returns an account manager instance for this connection.
     * 
     * @return an account manager for this connection.
     */
    public AccountManager getAccountManager() {
        if (accountManager == null) {
            accountManager = new AccountManager(this);
        }
        return accountManager;
    }

    /**
     * Returns a chat manager instance for this connection. The ChatManager manages all incoming and
     * outgoing chats on the current connection.
     * 
     * @return a chat manager instance for this connection.
     */
    public synchronized ChatManager getChatManager() {
        if (this.chatManager == null) {
            this.chatManager = new ChatManager(this);
        }
        return this.chatManager;
    }

    /**
     * Returns the roster for the user.
     * <p>
     * This method will never return <code>null</code>, instead if the user has not yet logged into
     * the server or is logged in anonymously all modifying methods of the returned roster object
     * like {@link Roster#createEntry(String, String, String[])},
     * {@link Roster#removeEntry(RosterEntry)} , etc. except adding or removing
     * {@link RosterListener}s will throw an IllegalStateException.
     * 
     * @return the user's roster.
     */
    public abstract Roster getRoster();
    
    /**
     * Set the store for the roster of this connection. If you set the roster storage
     * of a connection you enable support for XEP-0237 (RosterVersioning)
     * @param store the store used for roster versioning
     * @throws IllegalStateException if you add a roster store when roster is initializied
     */
    public abstract void setRosterStorage(RosterStorage storage) throws IllegalStateException;
    
    /**
     * Returns the SASLAuthentication manager that is responsible for authenticating with
     * the server.
     * 
     * @return the SASLAuthentication manager that is responsible for authenticating with
     *         the server.
     */
    public SASLAuthentication getSASLAuthentication() {
        return saslAuthentication;
    }

    /**
     * Closes the connection by setting presence to unavailable then closing the connection to
     * the XMPP server. The Connection can still be used for connecting to the server
     * again.<p>
     * <p/>
     * This method cleans up all resources used by the connection. Therefore, the roster,
     * listeners and other stateful objects cannot be re-used by simply calling connect()
     * on this connection again. This is unlike the behavior during unexpected disconnects
     * (and subsequent connections). In that case, all state is preserved to allow for
     * more seamless error recovery.
     */
    public void disconnect() {
        disconnect(new Presence(Presence.Type.unavailable));
    }

    /**
     * Closes the connection. A custom unavailable presence is sent to the server, followed
     * by closing the stream. The Connection can still be used for connecting to the server
     * again. A custom unavilable presence is useful for communicating offline presence
     * information such as "On vacation". Typically, just the status text of the presence
     * packet is set with online information, but most XMPP servers will deliver the full
     * presence packet with whatever data is set.<p>
     * <p/>
     * This method cleans up all resources used by the connection. Therefore, the roster,
     * listeners and other stateful objects cannot be re-used by simply calling connect()
     * on this connection again. This is unlike the behavior during unexpected disconnects
     * (and subsequent connections). In that case, all state is preserved to allow for
     * more seamless error recovery.
     * 
     * @param unavailablePresence the presence packet to send during shutdown.
     */
    public abstract void disconnect(Presence unavailablePresence);

    /**
     * Adds a new listener that will be notified when new Connections are created. Note
     * that newly created connections will not be actually connected to the server.
     * 
     * @param connectionCreationListener a listener interested on new connections.
     */
    public static void addConnectionCreationListener(
            ConnectionCreationListener connectionCreationListener) {
        connectionEstablishedListeners.add(connectionCreationListener);
    }

    /**
     * Removes a listener that was interested in connection creation events.
     * 
     * @param connectionCreationListener a listener interested on new connections.
     */
    public static void removeConnectionCreationListener(
            ConnectionCreationListener connectionCreationListener) {
        connectionEstablishedListeners.remove(connectionCreationListener);
    }

    /**
     * Get the collection of listeners that are interested in connection creation events.
     * 
     * @return a collection of listeners interested on new connections.
     */
    protected static Collection<ConnectionCreationListener> getConnectionCreationListeners() {
        return Collections.unmodifiableCollection(connectionEstablishedListeners);
    }

    /**
     * Adds a connection listener to this connection that will be notified when
     * the connection closes or fails. The connection needs to already be connected
     * or otherwise an IllegalStateException will be thrown.
     * 
     * @param connectionListener a connection listener.
     */
    public void addConnectionListener(ConnectionListener connectionListener) {
        if (!isConnected()) {
            throw new IllegalStateException("Not connected to server.");
        }
        if (connectionListener == null) {
            return;
        }
        if (!connectionListeners.contains(connectionListener)) {
            connectionListeners.add(connectionListener);
        }
    }

    /**
     * Removes a connection listener from this connection.
     * 
     * @param connectionListener a connection listener.
     */
    public void removeConnectionListener(ConnectionListener connectionListener) {
        connectionListeners.remove(connectionListener);
    }

    /**
     * Get the collection of listeners that are interested in connection events.
     * 
     * @return a collection of listeners interested on connection events.
     */
    protected Collection<ConnectionListener> getConnectionListeners() {
        return connectionListeners;
    }

    /**
     * Creates a new packet collector for this connection. A packet filter determines
     * which packets will be accumulated by the collector. A PacketCollector is
     * more suitable to use than a {@link PacketListener} when you need to wait for
     * a specific result.
     * 
     * @param packetFilter the packet filter to use.
     * @return a new packet collector.
     */
    public PacketCollector createPacketCollector(PacketFilter packetFilter) {
        PacketCollector collector = new PacketCollector(this, packetFilter);
        // Add the collector to the list of active collectors.
        collectors.add(collector);
        return collector;
    }

    /**
     * Remove a packet collector of this connection.
     * 
     * @param collector a packet collectors which was created for this connection.
     */
    protected void removePacketCollector(PacketCollector collector) {
        collectors.remove(collector);
    }

    /**
     * Get the collection of all packet collectors for this connection.
     * 
     * @return a collection of packet collectors for this connection.
     */
    protected Collection<PacketCollector> getPacketCollectors() {
        return collectors;
    }

    /**
     * Registers a packet listener with this connection. A packet filter determines
     * which packets will be delivered to the listener. If the same packet listener
     * is added again with a different filter, only the new filter will be used.
     * 
     * @param packetListener the packet listener to notify of new received packets.
     * @param packetFilter   the packet filter to use.
     */
    public void addPacketListener(PacketListener packetListener, PacketFilter packetFilter) {
        if (packetListener == null) {
            throw new NullPointerException("Packet listener is null.");
        }
        ListenerWrapper wrapper = new ListenerWrapper(packetListener, packetFilter);
        recvListeners.put(packetListener, wrapper);
    }

    /**
     * Removes a packet listener for received packets from this connection.
     * 
     * @param packetListener the packet listener to remove.
     */
    public void removePacketListener(PacketListener packetListener) {
        recvListeners.remove(packetListener);
    }

    /**
     * Get a map of all packet listeners for received packets of this connection.
     * 
     * @return a map of all packet listeners for received packets.
     */
    protected Map<PacketListener, ListenerWrapper> getPacketListeners() {
        return recvListeners;
    }

    /**
     * Registers a packet listener with this connection. The listener will be
     * notified of every packet that this connection sends. A packet filter determines
     * which packets will be delivered to the listener. Note that the thread
     * that writes packets will be used to invoke the listeners. Therefore, each
     * packet listener should complete all operations quickly or use a different
     * thread for processing.
     * 
     * @param packetListener the packet listener to notify of sent packets.
     * @param packetFilter   the packet filter to use.
     */
    public void addPacketSendingListener(PacketListener packetListener, PacketFilter packetFilter) {
        if (packetListener == null) {
            throw new NullPointerException("Packet listener is null.");
        }
        ListenerWrapper wrapper = new ListenerWrapper(packetListener, packetFilter);
        sendListeners.put(packetListener, wrapper);
    }

    /**
     * Removes a packet listener for sending packets from this connection.
     * 
     * @param packetListener the packet listener to remove.
     */
    public void removePacketSendingListener(PacketListener packetListener) {
        sendListeners.remove(packetListener);
    }

    /**
     * Get a map of all packet listeners for sending packets of this connection.
     * 
     * @return a map of all packet listeners for sent packets.
     */
    protected Map<PacketListener, ListenerWrapper> getPacketSendingListeners() {
        return sendListeners;
    }


    /**
     * Process all packet listeners for sending packets.
     * 
     * @param packet the packet to process.
     */
    protected void firePacketSendingListeners(Packet packet) {
        // Notify the listeners of the new sent packet
        for (ListenerWrapper listenerWrapper : sendListeners.values()) {
            listenerWrapper.notifyListener(packet);
        }
    }

    /**
     * Registers a packet interceptor with this connection. The interceptor will be
     * invoked every time a packet is about to be sent by this connection. Interceptors
     * may modify the packet to be sent. A packet filter determines which packets
     * will be delivered to the interceptor.
     *
     * @param packetInterceptor the packet interceptor to notify of packets about to be sent.
     * @param packetFilter      the packet filter to use.
     */
    public void addPacketInterceptor(PacketInterceptor packetInterceptor,
            PacketFilter packetFilter) {
        if (packetInterceptor == null) {
            throw new NullPointerException("Packet interceptor is null.");
        }
        interceptors.put(packetInterceptor, new InterceptorWrapper(packetInterceptor, packetFilter));
    }

    /**
     * Removes a packet interceptor.
     *
     * @param packetInterceptor the packet interceptor to remove.
     */
    public void removePacketInterceptor(PacketInterceptor packetInterceptor) {
        interceptors.remove(packetInterceptor);
    }
    
    public boolean isSendPresence() {
        return config.isSendPresence();
    }

    /**
     * Get a map of all packet interceptors for sending packets of this connection.
     * 
     * @return a map of all packet interceptors for sending packets.
     */
    protected Map<PacketInterceptor, InterceptorWrapper> getPacketInterceptors() {
        return interceptors;
    }

    /**
     * Process interceptors. Interceptors may modify the packet that is about to be sent.
     * Since the thread that requested to send the packet will invoke all interceptors, it
     * is important that interceptors perform their work as soon as possible so that the
     * thread does not remain blocked for a long period.
     * 
     * @param packet the packet that is going to be sent to the server
     */
    protected void firePacketInterceptors(Packet packet) {
        if (packet != null) {
            for (InterceptorWrapper interceptorWrapper : interceptors.values()) {
                interceptorWrapper.notifyListener(packet);
            }
        }
    }

    /**
     * Initialize the {@link #debugger}. You can specify a customized {@link SmackDebugger}
     * by setup the system property <code>smack.debuggerClass</code> to the implementation.
     * 
     * @throws IllegalStateException if the reader or writer isn't yet initialized.
     * @throws IllegalArgumentException if the SmackDebugger can't be loaded.
     */
    protected void initDebugger() {
        if (reader == null || writer == null) {
            throw new NullPointerException("Reader or writer isn't initialized.");
        }
        // If debugging is enabled, we open a window and write out all network traffic.
        if (config.isDebuggerEnabled()) {
            if (debugger == null) {
                // Detect the debugger class to use.
                String className = null;
                // Use try block since we may not have permission to get a system
                // property (for example, when an applet).
                try {
                    className = System.getProperty("smack.debuggerClass");
                }
                catch (Throwable t) {
                    // Ignore.
                }
                Class<?> debuggerClass = null;
                if (className != null) {
                    try {
                        debuggerClass = Class.forName(className);
                    }
                    catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (debuggerClass == null) {
                    try {
                        debuggerClass =
                                Class.forName("de.measite.smack.AndroidDebugger");
                    }
                    catch (Exception ex) {
                        try {
                            debuggerClass =
                                    Class.forName("org.jivesoftware.smack.debugger.ConsoleDebugger");
                        }
                        catch (Exception ex2) {
                            ex2.printStackTrace();
                        }
                    }
                }
                // Create a new debugger instance. If an exception occurs then disable the debugging
                // option
                try {
                    Constructor<?> constructor = debuggerClass
                            .getConstructor(Connection.class, Writer.class, Reader.class);
                    debugger = (SmackDebugger) constructor.newInstance(this, writer, reader);
                    reader = debugger.getReader();
                    writer = debugger.getWriter();
                }
                catch (Exception e) {
                    throw new IllegalArgumentException("Can't initialize the configured debugger!", e);
                }
            }
            else {
                // Obtain new reader and writer from the existing debugger
                reader = debugger.newConnectionReader(reader);
                writer = debugger.newConnectionWriter(writer);
            }
        }
        
    }

    /**
     * Set the servers Entity Caps node
     * 
     * Connection holds this information in order to avoid a dependency to
     * smackx where EntityCapsManager lives from smack.
     * 
     * @param node
     */
    protected void setServiceCapsNode(String node) {
        serviceCapsNode = node;
    }

    /**
     * Retrieve the servers Entity Caps node
     * 
     * Connection holds this information in order to avoid a dependency to
     * smackx where EntityCapsManager lives from smack.
     * 
     * @return
     */
    public String getServiceCapsNode() {
        return serviceCapsNode;
    }

    /**
     * A wrapper class to associate a packet filter with a listener.
     */
    protected static class ListenerWrapper {

        private PacketListener packetListener;
        private PacketFilter packetFilter;

        /**
         * Create a class which associates a packet filter with a listener.
         * 
         * @param packetListener the packet listener.
         * @param packetFilter the associated filter or null if it listen for all packets.
         */
        public ListenerWrapper(PacketListener packetListener, PacketFilter packetFilter) {
            this.packetListener = packetListener;
            this.packetFilter = packetFilter;
        }

        /**
         * Notify and process the packet listener if the filter matches the packet.
         * 
         * @param packet the packet which was sent or received.
         */
        public void notifyListener(Packet packet) {
            if (packetFilter == null || packetFilter.accept(packet)) {
                packetListener.processPacket(packet);
            }
        }
    }

    /**
     * A wrapper class to associate a packet filter with an interceptor.
     */
    protected static class InterceptorWrapper {

        private PacketInterceptor packetInterceptor;
        private PacketFilter packetFilter;

        /**
         * Create a class which associates a packet filter with an interceptor.
         * 
         * @param packetInterceptor the interceptor.
         * @param packetFilter the associated filter or null if it intercepts all packets.
         */
        public InterceptorWrapper(PacketInterceptor packetInterceptor, PacketFilter packetFilter) {
            this.packetInterceptor = packetInterceptor;
            this.packetFilter = packetFilter;
        }

        public boolean equals(Object object) {
            if (object == null) {
                return false;
            }
            if (object instanceof InterceptorWrapper) {
                return ((InterceptorWrapper) object).packetInterceptor
                        .equals(this.packetInterceptor);
            }
            else if (object instanceof PacketInterceptor) {
                return object.equals(this.packetInterceptor);
            }
            return false;
        }

        /**
         * Notify and process the packet interceptor if the filter matches the packet.
         * 
         * @param packet the packet which will be sent.
         */
        public void notifyListener(Packet packet) {
            if (packetFilter == null || packetFilter.accept(packet)) {
                packetInterceptor.interceptPacket(packet);
            }
        }
    }
}
