//# 1 errors, 789 messages
//#
/*
    //#DCC.java:1:1: class: com.dmdirc.addons.dcc.DCC
    //#DCC.java:1:1: method: com.dmdirc.addons.dcc.DCC.com.dmdirc.addons.dcc.DCC__static_init
 * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package com.dmdirc.addons.dcc;

import java.net.Socket;
import java.net.ServerSocket;
import java.io.IOException;
import java.util.concurrent.Semaphore;

/**
 * This class handles the main "grunt work" of DCC, subclasses process the data
 * received by this class.
 *
 * @author Shane 'Dataforce' McCormack
 */
public abstract class DCC implements Runnable {
	/** Address. */
	protected long address = 0;
	/** Port. */
	protected int port = 0;
	/** Socket used to communicate with. */
	protected Socket socket;
	/** The Thread in use for this. */
	private volatile Thread myThread;
	/** Are we already running? */
	protected boolean running = false;
	/** Are we a listen socket? */
	protected boolean listen = false;

	/**
	 * The current socket in use if this is a listen socket.
	 * This reference may be changed if and only if exactly one permit from the
	 * <code>serverSocketSem</code> and <code>serverListenignSem</code>
	 * semaphores is held by the thread doing the modification.
	 */
	private ServerSocket serverSocket;

	/**
	 * Semaphore to control write access to ServerSocket.
	 * If an object acquires a permit from the <code>serverSocketSem</code>, then
	 * <code>serverSocket</code> is <em>guaranteed</em> not to be externally
	 * modified until that permit is released, <em>unless</em> the object also
	 * acquires a permit from the <code>serverListeningSem</code>.
	 */
	private final Semaphore serverSocketSem = new Semaphore(1);

	/**
	 * Semaphore used when we're blocking waiting for connections.
	 * If an object acquires a permit from the <code>serverListeningSem</code>,
	 * then it is <em>guaranteed</em> that the {@link #run()} method is blocking
	 * waiting for incoming connections. In addition, it is <em>guaranteed</em>
	 * that the {@link #run()} method is holding the <code>serverSocketSem</code>
	 * permit, and it will continue holding that permit until it can reaquire
	 * the <code>serverListeningSem</code> permit.
	 */
	private final Semaphore serverListeningSem = new Semaphore(0);

	/**
	 * Creates a new instance of DCC.
	 */
	public DCC() {
		super();
    //#DCC.java:82: method: void com.dmdirc.addons.dcc.DCC.com.dmdirc.addons.dcc.DCC()
    //#input(void com.dmdirc.addons.dcc.DCC()): this
    //#output(void com.dmdirc.addons.dcc.DCC()): new Semaphore(DCC#1) num objects
    //#output(void com.dmdirc.addons.dcc.DCC()): new Semaphore(DCC#2) num objects
    //#output(void com.dmdirc.addons.dcc.DCC()): this.address
    //#output(void com.dmdirc.addons.dcc.DCC()): this.listen
    //#output(void com.dmdirc.addons.dcc.DCC()): this.port
    //#output(void com.dmdirc.addons.dcc.DCC()): this.running
    //#output(void com.dmdirc.addons.dcc.DCC()): this.serverListeningSem
    //#output(void com.dmdirc.addons.dcc.DCC()): this.serverSocketSem
    //#new obj(void com.dmdirc.addons.dcc.DCC()): new Semaphore(DCC#1)
    //#new obj(void com.dmdirc.addons.dcc.DCC()): new Semaphore(DCC#2)
    //#post(void com.dmdirc.addons.dcc.DCC()): this.address == 0
    //#post(void com.dmdirc.addons.dcc.DCC()): this.listen == 0
    //#post(void com.dmdirc.addons.dcc.DCC()): this.port == 0
    //#post(void com.dmdirc.addons.dcc.DCC()): this.running == 0
    //#post(void com.dmdirc.addons.dcc.DCC()): this.serverListeningSem == &new Semaphore(DCC#2)
    //#post(void com.dmdirc.addons.dcc.DCC()): this.serverSocketSem == &new Semaphore(DCC#1)
    //#post(void com.dmdirc.addons.dcc.DCC()): new Semaphore(DCC#1) num objects == 1
    //#post(void com.dmdirc.addons.dcc.DCC()): new Semaphore(DCC#2) num objects == 1
	}
    //#DCC.java:83: end of method: void com.dmdirc.addons.dcc.DCC.com.dmdirc.addons.dcc.DCC()

	/**
	 * Connect this dcc.
	 */
	public void connect() {
		try {
			if (listen) {
    //#DCC.java:90: method: void com.dmdirc.addons.dcc.DCC.connect()
    //#DCC.java:90: Warning: suspicious precondition
    //#    The precondition for this.__Tag is not a contiguous range of values
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.dcc.DCC
    //#    method: void connect()
    //#    suspicious precondition index: [14]
    //#    Attribs:  Soft
    //#input(void connect()): "."._tainted
    //#input(void connect()): __Descendant_Table[com/dmdirc/addons/dcc/DCCChat]
    //#input(void connect()): __Descendant_Table[com/dmdirc/addons/dcc/DCCSend]
    //#input(void connect()): __Descendant_Table[com/dmdirc/addons/dcc/DCC]
    //#input(void connect()): __Descendant_Table[others]
    //#input(void connect()): __Dispatch_Table.socketClosed()V
    //#input(void connect()): __Dispatch_Table.socketOpened()V
    //#input(void connect()): com/dmdirc/addons/dcc/DCCChat.__Descendant_Table[com/dmdirc/addons/dcc/DCCChat]
    //#input(void connect()): com/dmdirc/addons/dcc/DCCChat.__Descendant_Table[others]
    //#input(void connect()): com/dmdirc/addons/dcc/DCCChat.__Dispatch_Table.socketClosed()V
    //#input(void connect()): com/dmdirc/addons/dcc/DCCChat.__Dispatch_Table.socketOpened()V
    //#input(void connect()): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCChatInterface]
    //#input(void connect()): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCChatWindow]
    //#input(void connect()): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[others]
    //#input(void connect()): com/dmdirc/addons/dcc/DCCChatInterface.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void connect()): com/dmdirc/addons/dcc/DCCChatInterface.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void connect()): com/dmdirc/addons/dcc/DCCChatWindow.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void connect()): com/dmdirc/addons/dcc/DCCChatWindow.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void connect()): com/dmdirc/addons/dcc/DCCSend$TransferType.RECEIVE
    //#input(void connect()): com/dmdirc/addons/dcc/DCCSend.SENDS
    //#input(void connect()): com/dmdirc/addons/dcc/DCCSend.__Descendant_Table[com/dmdirc/addons/dcc/DCCSend]
    //#input(void connect()): com/dmdirc/addons/dcc/DCCSend.__Descendant_Table[others]
    //#input(void connect()): com/dmdirc/addons/dcc/DCCSend.__Dispatch_Table.socketClosed()V
    //#input(void connect()): com/dmdirc/addons/dcc/DCCSend.__Dispatch_Table.socketOpened()V
    //#input(void connect()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendInterface]
    //#input(void connect()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendWindow]
    //#input(void connect()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[others]
    //#input(void connect()): com/dmdirc/addons/dcc/DCCSendInterface.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void connect()): com/dmdirc/addons/dcc/DCCSendInterface.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void connect()): com/dmdirc/addons/dcc/DCCSendWindow.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void connect()): com/dmdirc/addons/dcc/DCCSendWindow.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void connect()): this
    //#input(void connect()): this.__Tag
    //#input(void connect()): this.address
    //#input(void connect()): this.handler.__Tag
    //#input(void connect()): this.listen
    //#input(void connect()): this.port
    //#input(void connect()): this.serverSocket
    //#output(void connect()): new BufferedReader(socketOpened#2) num objects
    //#output(void connect()): new DataInputStream(socketOpened#5) num objects
    //#output(void connect()): new DataOutputStream(socketOpened#2) num objects
    //#output(void connect()): new DataOutputStream(socketOpened#4) num objects
    //#output(void connect()): new File(socketOpened#1) num objects
    //#output(void connect()): new PrintWriter(socketOpened#1) num objects
    //#output(void connect()): new Socket(connect#1) num objects
    //#output(void connect()): new Thread(connect#2) num objects
    //#output(void connect()): this.address
    //#output(void connect()): this.fileOut
    //#output(void connect()): this.handler.timeStarted
    //#output(void connect()): this.in
    //#output(void connect()): this.myThread
    //#output(void connect()): this.out
    //#output(void connect()): this.port
    //#output(void connect()): this.socket
    //#output(void connect()): this.transferFile
    //#new obj(void connect()): new BufferedReader(socketOpened#2)
    //#new obj(void connect()): new DataInputStream(socketOpened#5)
    //#new obj(void connect()): new DataOutputStream(socketOpened#2)
    //#new obj(void connect()): new DataOutputStream(socketOpened#4)
    //#new obj(void connect()): new File(socketOpened#1)
    //#new obj(void connect()): new PrintWriter(socketOpened#1)
    //#new obj(void connect()): new Socket(connect#1)
    //#new obj(void connect()): new Thread(connect#2)
    //#pre[2] (void connect()): (soft) init'ed(this.address)
    //#pre[10] (void connect()): (soft) init'ed(this.port)
    //#pre[14] (void connect()): (soft) this.__Tag in {com/dmdirc/addons/dcc/DCC, com/dmdirc/addons/dcc/DCCChat, com/dmdirc/addons/dcc/DCCSend}
    //#pre[22] (void connect()): (soft) init'ed(this.listen)
    //#pre[23] (void connect()): (soft) this.serverSocket != null
    //#post(void connect()): this.address == One-of{old this.address, 0}
    //#post(void connect()): init'ed(this.address)
    //#post(void connect()): possibly_updated(this.fileOut)
    //#post(void connect()): this.handler.timeStarted == old this.handler.timeStarted
    //#post(void connect()): possibly_updated(this.in)
    //#post(void connect()): this.myThread == One-of{old this.myThread, &new Thread(connect#2)}
    //#post(void connect()): possibly_updated(this.out)
    //#post(void connect()): init'ed(this.port)
    //#post(void connect()): this.socket == One-of{old this.socket, &new Socket(connect#1)}
    //#post(void connect()): possibly_updated(this.transferFile)
    //#post(void connect()): new BufferedReader(socketOpened#2) num objects <= 1
    //#post(void connect()): new DataInputStream(socketOpened#5) num objects <= 1
    //#post(void connect()): new DataOutputStream(socketOpened#2) num objects <= 1
    //#post(void connect()): new DataOutputStream(socketOpened#4) num objects <= 1
    //#post(void connect()): new File(socketOpened#1) num objects <= 1
    //#post(void connect()): new PrintWriter(socketOpened#1) num objects <= 1
    //#post(void connect()): new Socket(connect#1) num objects <= 1
    //#post(void connect()): new Thread(connect#2) num objects <= 1
    //#unanalyzed(void connect()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void connect()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void connect()): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void connect()): Effects-of-calling:socketClosed
    //#unanalyzed(void connect()): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void connect()): Effects-of-calling:java.net.Socket:getOutputStream
    //#unanalyzed(void connect()): Effects-of-calling:java.io.PrintWriter
    //#unanalyzed(void connect()): Effects-of-calling:java.net.Socket:getInputStream
    //#unanalyzed(void connect()): Effects-of-calling:java.io.InputStreamReader
    //#unanalyzed(void connect()): Effects-of-calling:java.io.BufferedReader
    //#unanalyzed(void connect()): Effects-of-calling:socketOpened
    //#unanalyzed(void connect()): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(void connect()): Effects-of-calling:com.dmdirc.logger.Logger:assertTrue
    //#unanalyzed(void connect()): Effects-of-calling:getType
    //#unanalyzed(void connect()): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void connect()): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void connect()): Effects-of-calling:com.dmdirc.util.MapList:containsKey
    //#unanalyzed(void connect()): Effects-of-calling:com.dmdirc.util.MapList:get
    //#unanalyzed(void connect()): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(void connect()): Effects-of-calling:java.util.ArrayList:iterator
    //#unanalyzed(void connect()): Effects-of-calling:trigger
    //#unanalyzed(void connect()): Effects-of-calling:getArity
    //#unanalyzed(void connect()): Effects-of-calling:com.dmdirc.interfaces.ActionListener:processEvent
    //#unanalyzed(void connect()): Effects-of-calling:addLine
    //#unanalyzed(void connect()): Effects-of-calling:setIcon
    //#unanalyzed(void connect()): Effects-of-calling:java.util.List:remove
    //#unanalyzed(void connect()): Effects-of-calling:java.io.DataOutputStream:close
    //#unanalyzed(void connect()): Effects-of-calling:java.io.DataInputStream:close
    //#unanalyzed(void connect()): Effects-of-calling:java.io.File
    //#unanalyzed(void connect()): Effects-of-calling:java.io.File:getAbsolutePath
    //#unanalyzed(void connect()): Effects-of-calling:java.io.DataInputStream
    //#unanalyzed(void connect()): Effects-of-calling:java.io.FileOutputStream
    //#unanalyzed(void connect()): Effects-of-calling:java.io.DataOutputStream
    //#unanalyzed(void connect()): Effects-of-calling:java.lang.Long:valueOf
    //#unanalyzed(void connect()): Effects-of-calling:java.lang.String:format
    //#unanalyzed(void connect()): Effects-of-calling:javax.swing.JButton:setText
    //#unanalyzed(void connect()): Effects-of-calling:javax.swing.JLabel:setText
    //#unanalyzed(void connect()): Effects-of-calling:java.lang.System:currentTimeMillis
    //#unanalyzed(void connect()): Effects-of-calling:java.lang.Math:floor
    //#unanalyzed(void connect()): Effects-of-calling:javax.swing.JProgressBar:setValue
    //#unanalyzed(void connect()): Effects-of-calling:java.lang.Double:valueOf
    //#unanalyzed(void connect()): Effects-of-calling:isWindowClosing
    //#test_vector(void connect()): this.listen: {0}, {1}
				address = 0;
				port = serverSocket.getLocalPort();
			} else {
				// socket = new Socket(longToIP(address), port, bindIP, 0);
				socket = new Socket(longToIP(address), port);
				socketOpened();
			}
		} catch (IOException ioe) {
            socketClosed();
			return;
		}

		myThread = new Thread(this);
		myThread.start();
	}
    //#DCC.java:105: end of method: void com.dmdirc.addons.dcc.DCC.connect()

	/**
	 * Start a listen socket rather than a connect socket.
	 *
	 * @throws IOException If the listen socket can't be created
	 */
	public void listen() throws IOException {
		serverSocketSem.acquireUninterruptibly();
    //#DCC.java:113: method: void com.dmdirc.addons.dcc.DCC.listen()
    //#DCC.java:113: Warning: suspicious precondition
    //#    The precondition for this.__Tag is not a contiguous range of values
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.dcc.DCC
    //#    method: void listen()
    //#    suspicious precondition index: [18]
    //#input(void listen()): "."._tainted
    //#input(void listen()): __Descendant_Table[com/dmdirc/addons/dcc/DCCChat]
    //#input(void listen()): __Descendant_Table[com/dmdirc/addons/dcc/DCCSend]
    //#input(void listen()): __Descendant_Table[com/dmdirc/addons/dcc/DCC]
    //#input(void listen()): __Descendant_Table[others]
    //#input(void listen()): __Dispatch_Table.connect()V
    //#input(void listen()): __Dispatch_Table.socketClosed()V
    //#input(void listen()): __Dispatch_Table.socketOpened()V
    //#input(void listen()): com/dmdirc/addons/dcc/DCCChat.__Descendant_Table[com/dmdirc/addons/dcc/DCCChat]
    //#input(void listen()): com/dmdirc/addons/dcc/DCCChat.__Descendant_Table[others]
    //#input(void listen()): com/dmdirc/addons/dcc/DCCChat.__Dispatch_Table.connect()V
    //#input(void listen()): com/dmdirc/addons/dcc/DCCChat.__Dispatch_Table.socketClosed()V
    //#input(void listen()): com/dmdirc/addons/dcc/DCCChat.__Dispatch_Table.socketOpened()V
    //#input(void listen()): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCChatInterface]
    //#input(void listen()): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCChatWindow]
    //#input(void listen()): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[others]
    //#input(void listen()): com/dmdirc/addons/dcc/DCCChatInterface.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void listen()): com/dmdirc/addons/dcc/DCCChatInterface.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void listen()): com/dmdirc/addons/dcc/DCCChatWindow.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void listen()): com/dmdirc/addons/dcc/DCCChatWindow.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void listen()): com/dmdirc/addons/dcc/DCCSend$TransferType.RECEIVE
    //#input(void listen()): com/dmdirc/addons/dcc/DCCSend.SENDS
    //#input(void listen()): com/dmdirc/addons/dcc/DCCSend.__Descendant_Table[com/dmdirc/addons/dcc/DCCSend]
    //#input(void listen()): com/dmdirc/addons/dcc/DCCSend.__Descendant_Table[others]
    //#input(void listen()): com/dmdirc/addons/dcc/DCCSend.__Dispatch_Table.connect()V
    //#input(void listen()): com/dmdirc/addons/dcc/DCCSend.__Dispatch_Table.socketClosed()V
    //#input(void listen()): com/dmdirc/addons/dcc/DCCSend.__Dispatch_Table.socketOpened()V
    //#input(void listen()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendInterface]
    //#input(void listen()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendWindow]
    //#input(void listen()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[others]
    //#input(void listen()): com/dmdirc/addons/dcc/DCCSendInterface.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void listen()): com/dmdirc/addons/dcc/DCCSendInterface.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void listen()): com/dmdirc/addons/dcc/DCCSendWindow.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void listen()): com/dmdirc/addons/dcc/DCCSendWindow.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void listen()): this
    //#input(void listen()): this.__Tag
    //#input(void listen()): this.address
    //#input(void listen()): this.handler.__Tag
    //#input(void listen()): this.port
    //#input(void listen()): this.serverSocketSem
    //#output(void listen()): new BufferedReader(socketOpened#2) num objects
    //#output(void listen()): new DataInputStream(socketOpened#5) num objects
    //#output(void listen()): new DataOutputStream(socketOpened#2) num objects
    //#output(void listen()): new DataOutputStream(socketOpened#4) num objects
    //#output(void listen()): new File(socketOpened#1) num objects
    //#output(void listen()): new PrintWriter(socketOpened#1) num objects
    //#output(void listen()): new ServerSocket(listen#1) num objects
    //#output(void listen()): new Socket(connect#1) num objects
    //#output(void listen()): new Thread(connect#2) num objects
    //#output(void listen()): this.address
    //#output(void listen()): this.fileOut
    //#output(void listen()): this.handler.timeStarted
    //#output(void listen()): this.in
    //#output(void listen()): this.listen
    //#output(void listen()): this.myThread
    //#output(void listen()): this.out
    //#output(void listen()): this.port
    //#output(void listen()): this.serverSocket
    //#output(void listen()): this.socket
    //#output(void listen()): this.transferFile
    //#new obj(void listen()): new BufferedReader(socketOpened#2)
    //#new obj(void listen()): new DataInputStream(socketOpened#5)
    //#new obj(void listen()): new DataOutputStream(socketOpened#2)
    //#new obj(void listen()): new DataOutputStream(socketOpened#4)
    //#new obj(void listen()): new File(socketOpened#1)
    //#new obj(void listen()): new PrintWriter(socketOpened#1)
    //#new obj(void listen()): new ServerSocket(listen#1)
    //#new obj(void listen()): new Socket(connect#1)
    //#new obj(void listen()): new Thread(connect#2)
    //#pre[18] (void listen()): this.__Tag in {com/dmdirc/addons/dcc/DCC, com/dmdirc/addons/dcc/DCCChat, com/dmdirc/addons/dcc/DCCSend}
    //#pre[34] (void listen()): this.serverSocketSem != null
    //#pre[3] (void listen()): (soft) init'ed(this.address)
    //#pre[11] (void listen()): (soft) init'ed(this.port)
    //#post(void listen()): this.address == One-of{old this.address, 0}
    //#post(void listen()): init'ed(this.address)
    //#post(void listen()): possibly_updated(this.fileOut)
    //#post(void listen()): this.handler.timeStarted == old this.handler.timeStarted
    //#post(void listen()): possibly_updated(this.in)
    //#post(void listen()): this.listen == 1
    //#post(void listen()): new ServerSocket(listen#1) num objects == 1
    //#post(void listen()): this.myThread == One-of{old this.myThread, &new Thread(connect#2)}
    //#post(void listen()): possibly_updated(this.out)
    //#post(void listen()): init'ed(this.port)
    //#post(void listen()): this.serverSocket == &new ServerSocket(listen#1)
    //#post(void listen()): this.socket == old this.socket
    //#post(void listen()): possibly_updated(this.transferFile)
    //#post(void listen()): new BufferedReader(socketOpened#2) num objects == 0
    //#post(void listen()): new DataInputStream(socketOpened#5) num objects == 0
    //#post(void listen()): new DataOutputStream(socketOpened#2) num objects == 0
    //#post(void listen()): new DataOutputStream(socketOpened#4) num objects == 0
    //#post(void listen()): new File(socketOpened#1) num objects == 0
    //#post(void listen()): new PrintWriter(socketOpened#1) num objects == 0
    //#post(void listen()): new Socket(connect#1) num objects == 0
    //#post(void listen()): new Thread(connect#2) num objects <= 1
    //#unanalyzed(void listen()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void listen()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void listen()): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void listen()): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void listen()): Effects-of-calling:socketClosed
    //#unanalyzed(void listen()): Effects-of-calling:java.net.Socket:getOutputStream
    //#unanalyzed(void listen()): Effects-of-calling:java.io.PrintWriter
    //#unanalyzed(void listen()): Effects-of-calling:java.net.Socket:getInputStream
    //#unanalyzed(void listen()): Effects-of-calling:java.io.InputStreamReader
    //#unanalyzed(void listen()): Effects-of-calling:java.io.BufferedReader
    //#unanalyzed(void listen()): Effects-of-calling:socketOpened
    //#unanalyzed(void listen()): Effects-of-calling:java.net.ServerSocket:getLocalPort
    //#unanalyzed(void listen()): Effects-of-calling:java.net.Socket
    //#unanalyzed(void listen()): Effects-of-calling:java.lang.Thread
    //#unanalyzed(void listen()): Effects-of-calling:java.lang.Thread:start
    //#unanalyzed(void listen()): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(void listen()): Effects-of-calling:com.dmdirc.logger.Logger:assertTrue
    //#unanalyzed(void listen()): Effects-of-calling:getType
    //#unanalyzed(void listen()): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void listen()): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void listen()): Effects-of-calling:com.dmdirc.util.MapList:containsKey
    //#unanalyzed(void listen()): Effects-of-calling:com.dmdirc.util.MapList:get
    //#unanalyzed(void listen()): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(void listen()): Effects-of-calling:java.util.ArrayList:iterator
    //#unanalyzed(void listen()): Effects-of-calling:trigger
    //#unanalyzed(void listen()): Effects-of-calling:getArity
    //#unanalyzed(void listen()): Effects-of-calling:com.dmdirc.interfaces.ActionListener:processEvent
    //#unanalyzed(void listen()): Effects-of-calling:addLine
    //#unanalyzed(void listen()): Effects-of-calling:setIcon
    //#unanalyzed(void listen()): Effects-of-calling:java.util.List:remove
    //#unanalyzed(void listen()): Effects-of-calling:java.io.DataOutputStream:close
    //#unanalyzed(void listen()): Effects-of-calling:java.io.DataInputStream:close
    //#unanalyzed(void listen()): Effects-of-calling:java.io.File
    //#unanalyzed(void listen()): Effects-of-calling:java.io.File:getAbsolutePath
    //#unanalyzed(void listen()): Effects-of-calling:java.io.DataInputStream
    //#unanalyzed(void listen()): Effects-of-calling:java.io.FileOutputStream
    //#unanalyzed(void listen()): Effects-of-calling:java.io.DataOutputStream
    //#unanalyzed(void listen()): Effects-of-calling:java.lang.Long:valueOf
    //#unanalyzed(void listen()): Effects-of-calling:java.lang.String:format
    //#unanalyzed(void listen()): Effects-of-calling:javax.swing.JButton:setText
    //#unanalyzed(void listen()): Effects-of-calling:javax.swing.JLabel:setText
    //#unanalyzed(void listen()): Effects-of-calling:java.lang.System:currentTimeMillis
    //#unanalyzed(void listen()): Effects-of-calling:java.lang.Math:floor
    //#unanalyzed(void listen()): Effects-of-calling:javax.swing.JProgressBar:setValue
    //#unanalyzed(void listen()): Effects-of-calling:java.lang.Double:valueOf
    //#unanalyzed(void listen()): Effects-of-calling:isWindowClosing
		serverSocket = new ServerSocket(0, 1);
		serverSocketSem.release();

		listen = true;
		connect();
	}
    //#DCC.java:119: end of method: void com.dmdirc.addons.dcc.DCC.listen()

	/**
	 * Start a listen socket rather than a connect socket, use a port from the
	 * given range.
	 *
	 * @param startPort Port to try first
	 * @param endPort Last port to try.
	 * @throws IOException If no sockets were available in the given range
	 */
	public void listen(final int startPort, final int endPort) throws IOException {
		listen = true;
    //#DCC.java:130: method: void com.dmdirc.addons.dcc.DCC.listen(int, int)
    //#DCC.java:130: Warning: suspicious precondition
    //#    The precondition for this.__Tag is not a contiguous range of values
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.dcc.DCC
    //#    method: void listen(int, int)
    //#    suspicious precondition index: [21]
    //#input(void listen(int, int)): "."._tainted
    //#input(void listen(int, int)): ":"._tainted
    //#input(void listen(int, int)): "No available sockets in range "._tainted
    //#input(void listen(int, int)): __Descendant_Table[com/dmdirc/addons/dcc/DCCChat]
    //#input(void listen(int, int)): __Descendant_Table[com/dmdirc/addons/dcc/DCCSend]
    //#input(void listen(int, int)): __Descendant_Table[com/dmdirc/addons/dcc/DCC]
    //#input(void listen(int, int)): __Descendant_Table[others]
    //#input(void listen(int, int)): __Dispatch_Table.connect()V
    //#input(void listen(int, int)): __Dispatch_Table.socketClosed()V
    //#input(void listen(int, int)): __Dispatch_Table.socketOpened()V
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCChat.__Descendant_Table[com/dmdirc/addons/dcc/DCCChat]
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCChat.__Descendant_Table[others]
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCChat.__Dispatch_Table.connect()V
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCChat.__Dispatch_Table.socketClosed()V
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCChat.__Dispatch_Table.socketOpened()V
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCChatInterface]
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCChatWindow]
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[others]
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCChatInterface.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCChatInterface.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCChatWindow.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCChatWindow.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCSend$TransferType.RECEIVE
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCSend.SENDS
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCSend.__Descendant_Table[com/dmdirc/addons/dcc/DCCSend]
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCSend.__Descendant_Table[others]
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCSend.__Dispatch_Table.connect()V
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCSend.__Dispatch_Table.socketClosed()V
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCSend.__Dispatch_Table.socketOpened()V
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendInterface]
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendWindow]
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[others]
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCSendInterface.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCSendInterface.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCSendWindow.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void listen(int, int)): com/dmdirc/addons/dcc/DCCSendWindow.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void listen(int, int)): endPort
    //#input(void listen(int, int)): startPort
    //#input(void listen(int, int)): this
    //#input(void listen(int, int)): this.__Tag
    //#input(void listen(int, int)): this.address
    //#input(void listen(int, int)): this.handler.__Tag
    //#input(void listen(int, int)): this.port
    //#input(void listen(int, int)): this.serverSocket
    //#input(void listen(int, int)): this.serverSocketSem
    //#output(void listen(int, int)): new BufferedReader(socketOpened#2) num objects
    //#output(void listen(int, int)): new DataInputStream(socketOpened#5) num objects
    //#output(void listen(int, int)): new DataOutputStream(socketOpened#2) num objects
    //#output(void listen(int, int)): new DataOutputStream(socketOpened#4) num objects
    //#output(void listen(int, int)): new File(socketOpened#1) num objects
    //#output(void listen(int, int)): new PrintWriter(socketOpened#1) num objects
    //#output(void listen(int, int)): new ServerSocket(listen#1) num objects
    //#output(void listen(int, int)): new Socket(connect#1) num objects
    //#output(void listen(int, int)): new Thread(connect#2) num objects
    //#output(void listen(int, int)): this.address
    //#output(void listen(int, int)): this.fileOut
    //#output(void listen(int, int)): this.handler.timeStarted
    //#output(void listen(int, int)): this.in
    //#output(void listen(int, int)): this.listen
    //#output(void listen(int, int)): this.myThread
    //#output(void listen(int, int)): this.out
    //#output(void listen(int, int)): this.port
    //#output(void listen(int, int)): this.serverSocket
    //#output(void listen(int, int)): this.socket
    //#output(void listen(int, int)): this.transferFile
    //#new obj(void listen(int, int)): new BufferedReader(socketOpened#2)
    //#new obj(void listen(int, int)): new DataInputStream(socketOpened#5)
    //#new obj(void listen(int, int)): new DataOutputStream(socketOpened#2)
    //#new obj(void listen(int, int)): new DataOutputStream(socketOpened#4)
    //#new obj(void listen(int, int)): new File(socketOpened#1)
    //#new obj(void listen(int, int)): new PrintWriter(socketOpened#1)
    //#new obj(void listen(int, int)): new ServerSocket(listen#1)
    //#new obj(void listen(int, int)): new Socket(connect#1)
    //#new obj(void listen(int, int)): new Thread(connect#2)
    //#pre[21] (void listen(int, int)): this.__Tag in {com/dmdirc/addons/dcc/DCC, com/dmdirc/addons/dcc/DCCChat, com/dmdirc/addons/dcc/DCCSend}
    //#pre[3] (void listen(int, int)): (soft) endPort <= 4_294_967_294
    //#pre[4] (void listen(int, int)): (soft) init'ed(this.address)
    //#pre[12] (void listen(int, int)): (soft) init'ed(this.port)
    //#pre[13] (void listen(int, int)): (soft) this.serverSocket != null
    //#pre[16] (void listen(int, int)): (soft) startPort <= 4_294_967_294
    //#pre[37] (void listen(int, int)): (soft) this.serverSocketSem != null
    //#post(void listen(int, int)): this.address == One-of{old this.address, 0}
    //#post(void listen(int, int)): init'ed(this.address)
    //#post(void listen(int, int)): possibly_updated(this.fileOut)
    //#post(void listen(int, int)): this.handler.timeStarted == old this.handler.timeStarted
    //#post(void listen(int, int)): possibly_updated(this.in)
    //#post(void listen(int, int)): this.listen == 1
    //#post(void listen(int, int)): this.myThread == One-of{old this.myThread, &new Thread(connect#2)}
    //#post(void listen(int, int)): possibly_updated(this.out)
    //#post(void listen(int, int)): init'ed(this.port)
    //#post(void listen(int, int)): this.serverSocket == One-of{old this.serverSocket, &new ServerSocket(listen#1)}
    //#post(void listen(int, int)): this.serverSocket != null
    //#post(void listen(int, int)): this.socket == old this.socket
    //#post(void listen(int, int)): possibly_updated(this.transferFile)
    //#post(void listen(int, int)): new BufferedReader(socketOpened#2) num objects == 0
    //#post(void listen(int, int)): new DataInputStream(socketOpened#5) num objects == 0
    //#post(void listen(int, int)): new DataOutputStream(socketOpened#2) num objects == 0
    //#post(void listen(int, int)): new DataOutputStream(socketOpened#4) num objects == 0
    //#post(void listen(int, int)): new File(socketOpened#1) num objects == 0
    //#post(void listen(int, int)): new PrintWriter(socketOpened#1) num objects == 0
    //#post(void listen(int, int)): new ServerSocket(listen#1) num objects <= 1
    //#post(void listen(int, int)): new Socket(connect#1) num objects == 0
    //#post(void listen(int, int)): new Thread(connect#2) num objects <= 1
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void listen(int, int)): Effects-of-calling:socketClosed
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.net.Socket:getOutputStream
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.io.PrintWriter
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.net.Socket:getInputStream
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.io.InputStreamReader
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.io.BufferedReader
    //#unanalyzed(void listen(int, int)): Effects-of-calling:socketOpened
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.net.ServerSocket:getLocalPort
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.net.Socket
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.lang.Thread
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.lang.Thread:start
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(void listen(int, int)): Effects-of-calling:com.dmdirc.logger.Logger:assertTrue
    //#unanalyzed(void listen(int, int)): Effects-of-calling:getType
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void listen(int, int)): Effects-of-calling:com.dmdirc.util.MapList:containsKey
    //#unanalyzed(void listen(int, int)): Effects-of-calling:com.dmdirc.util.MapList:get
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.util.ArrayList:iterator
    //#unanalyzed(void listen(int, int)): Effects-of-calling:trigger
    //#unanalyzed(void listen(int, int)): Effects-of-calling:getArity
    //#unanalyzed(void listen(int, int)): Effects-of-calling:com.dmdirc.interfaces.ActionListener:processEvent
    //#unanalyzed(void listen(int, int)): Effects-of-calling:addLine
    //#unanalyzed(void listen(int, int)): Effects-of-calling:setIcon
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.util.List:remove
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.io.DataOutputStream:close
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.io.DataInputStream:close
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.io.File
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.io.File:getAbsolutePath
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.io.DataInputStream
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.io.FileOutputStream
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.io.DataOutputStream
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.lang.Long:valueOf
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.lang.String:format
    //#unanalyzed(void listen(int, int)): Effects-of-calling:javax.swing.JButton:setText
    //#unanalyzed(void listen(int, int)): Effects-of-calling:javax.swing.JLabel:setText
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.lang.System:currentTimeMillis
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.lang.Math:floor
    //#unanalyzed(void listen(int, int)): Effects-of-calling:javax.swing.JProgressBar:setValue
    //#unanalyzed(void listen(int, int)): Effects-of-calling:java.lang.Double:valueOf
    //#unanalyzed(void listen(int, int)): Effects-of-calling:isWindowClosing

		for (int i = startPort; i <= endPort; ++i) {
			try {
				serverSocketSem.acquireUninterruptibly();
				serverSocket = new ServerSocket(i, 1);
				serverSocketSem.release();
				// Found a socket we can use!
				break;
			} catch (IOException ioe) {
				// Try next socket.
			} catch (SecurityException se) {
				// Try next socket.
			}
		}

		if (serverSocket == null) {
			throw new IOException("No available sockets in range "+startPort+":"+endPort);
		} else {
			connect();
		}
	}
    //#DCC.java:151: end of method: void com.dmdirc.addons.dcc.DCC.listen(int, int)

	/**
	 * This handles the socket to keep it out of the main thread
	 */
	@Override
	public void run() {
		if (running) { return; }
    //#DCC.java:158: method: void com.dmdirc.addons.dcc.DCC.run()
    //#DCC.java:158: Warning: suspicious precondition
    //#    The precondition for this.__Tag is not a contiguous range of values
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.dcc.DCC
    //#    method: void run()
    //#    suspicious precondition index: [16]
    //#    Attribs:  Soft
    //#input(void run()): __Descendant_Table[com/dmdirc/addons/dcc/DCCChat]
    //#input(void run()): __Descendant_Table[com/dmdirc/addons/dcc/DCCSend]
    //#input(void run()): __Descendant_Table[com/dmdirc/addons/dcc/DCC]
    //#input(void run()): __Descendant_Table[others]
    //#input(void run()): __Dispatch_Table.close()V
    //#input(void run()): __Dispatch_Table.handleSocket()Z
    //#input(void run()): __Dispatch_Table.socketClosed()V
    //#input(void run()): __Dispatch_Table.socketOpened()V
    //#input(void run()): com/dmdirc/addons/dcc/DCCChat.__Descendant_Table[com/dmdirc/addons/dcc/DCCChat]
    //#input(void run()): com/dmdirc/addons/dcc/DCCChat.__Descendant_Table[others]
    //#input(void run()): com/dmdirc/addons/dcc/DCCChat.__Dispatch_Table.close()V
    //#input(void run()): com/dmdirc/addons/dcc/DCCChat.__Dispatch_Table.handleSocket()Z
    //#input(void run()): com/dmdirc/addons/dcc/DCCChat.__Dispatch_Table.socketClosed()V
    //#input(void run()): com/dmdirc/addons/dcc/DCCChat.__Dispatch_Table.socketOpened()V
    //#input(void run()): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCChatInterface]
    //#input(void run()): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCChatWindow]
    //#input(void run()): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[others]
    //#input(void run()): com/dmdirc/addons/dcc/DCCChatInterface.__Dispatch_Table.handleChatMessage(Lcom/dmdirc/addons/dcc/DCCChat;Ljava/lang/String;)V
    //#input(void run()): com/dmdirc/addons/dcc/DCCChatInterface.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void run()): com/dmdirc/addons/dcc/DCCChatInterface.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void run()): com/dmdirc/addons/dcc/DCCChatWindow.__Dispatch_Table.handleChatMessage(Lcom/dmdirc/addons/dcc/DCCChat;Ljava/lang/String;)V
    //#input(void run()): com/dmdirc/addons/dcc/DCCChatWindow.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void run()): com/dmdirc/addons/dcc/DCCChatWindow.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void run()): com/dmdirc/addons/dcc/DCCSend$TransferType.RECEIVE
    //#input(void run()): com/dmdirc/addons/dcc/DCCSend.SENDS
    //#input(void run()): com/dmdirc/addons/dcc/DCCSend.__Descendant_Table[com/dmdirc/addons/dcc/DCCSend]
    //#input(void run()): com/dmdirc/addons/dcc/DCCSend.__Descendant_Table[others]
    //#input(void run()): com/dmdirc/addons/dcc/DCCSend.__Dispatch_Table.close()V
    //#input(void run()): com/dmdirc/addons/dcc/DCCSend.__Dispatch_Table.handleReceive()Z
    //#input(void run()): com/dmdirc/addons/dcc/DCCSend.__Dispatch_Table.handleSend()Z
    //#input(void run()): com/dmdirc/addons/dcc/DCCSend.__Dispatch_Table.handleSocket()Z
    //#input(void run()): com/dmdirc/addons/dcc/DCCSend.__Dispatch_Table.socketClosed()V
    //#input(void run()): com/dmdirc/addons/dcc/DCCSend.__Dispatch_Table.socketOpened()V
    //#input(void run()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendInterface]
    //#input(void run()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendWindow]
    //#input(void run()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[others]
    //#input(void run()): com/dmdirc/addons/dcc/DCCSendInterface.__Dispatch_Table.dataTransfered(Lcom/dmdirc/addons/dcc/DCCSend;I)V
    //#input(void run()): com/dmdirc/addons/dcc/DCCSendInterface.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void run()): com/dmdirc/addons/dcc/DCCSendInterface.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void run()): com/dmdirc/addons/dcc/DCCSendWindow.__Dispatch_Table.dataTransfered(Lcom/dmdirc/addons/dcc/DCCSend;I)V
    //#input(void run()): com/dmdirc/addons/dcc/DCCSendWindow.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void run()): com/dmdirc/addons/dcc/DCCSendWindow.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void run()): this
    //#input(void run()): this.__Tag
    //#input(void run()): this.blockSize
    //#input(void run()): this.handler.__Tag
    //#input(void run()): this.myThread
    //#input(void run()): this.running
    //#input(void run()): this.serverListeningSem
    //#input(void run()): this.serverSocket
    //#input(void run()): this.serverSocketSem
    //#input(void run()): this.socket
    //#output(void run()): new BufferedReader(socketOpened#2) num objects
    //#output(void run()): new DataInputStream(socketOpened#5) num objects
    //#output(void run()): new DataOutputStream(socketOpened#2) num objects
    //#output(void run()): new DataOutputStream(socketOpened#4) num objects
    //#output(void run()): new File(socketOpened#1) num objects
    //#output(void run()): new PrintWriter(socketOpened#1) num objects
    //#output(void run()): this.fileOut
    //#output(void run()): this.handler.timeStarted
    //#output(void run()): this.handler.transferCount
    //#output(void run()): this.in
    //#output(void run()): this.out
    //#output(void run()): this.readSize
    //#output(void run()): this.running
    //#output(void run()): this.serverSocket
    //#output(void run()): this.socket
    //#output(void run()): this.transferFile
    //#new obj(void run()): new BufferedReader(socketOpened#2)
    //#new obj(void run()): new DataInputStream(socketOpened#5)
    //#new obj(void run()): new DataOutputStream(socketOpened#2)
    //#new obj(void run()): new DataOutputStream(socketOpened#4)
    //#new obj(void run()): new File(socketOpened#1)
    //#new obj(void run()): new PrintWriter(socketOpened#1)
    //#pre[11] (void run()): init'ed(this.running)
    //#pre[12] (void run()): (soft) init'ed(this.serverSocket)
    //#pre[13] (void run()): (soft) init'ed(this.socket)
    //#pre[16] (void run()): (soft) this.__Tag in {com/dmdirc/addons/dcc/DCC, com/dmdirc/addons/dcc/DCCChat, com/dmdirc/addons/dcc/DCCSend}
    //#pre[26] (void run()): (soft) init'ed(this.myThread)
    //#pre[27] (void run()): (soft) this.serverListeningSem != null
    //#pre[28] (void run()): (soft) this.serverSocketSem != null
    //#presumption(void run()): this.serverSocket@177 != null
    //#post(void run()): possibly_updated(this.fileOut)
    //#post(void run()): possibly_updated(this.handler.timeStarted)
    //#post(void run()): possibly_updated(this.handler.transferCount)
    //#post(void run()): possibly_updated(this.in)
    //#post(void run()): possibly_updated(this.out)
    //#post(void run()): possibly_updated(this.readSize)
    //#post(void run()): init'ed(this.running)
    //#post(void run()): init'ed(this.serverSocket)
    //#post(void run()): init'ed(this.socket)
    //#post(void run()): possibly_updated(this.transferFile)
    //#post(void run()): init'ed(new BufferedReader(socketOpened#2) num objects)
    //#post(void run()): init'ed(new DataInputStream(socketOpened#5) num objects)
    //#post(void run()): init'ed(new DataOutputStream(socketOpened#2) num objects)
    //#post(void run()): init'ed(new DataOutputStream(socketOpened#4) num objects)
    //#post(void run()): init'ed(new File(socketOpened#1) num objects)
    //#post(void run()): init'ed(new PrintWriter(socketOpened#1) num objects)
    //#unanalyzed(void run()): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void run()): Effects-of-calling:java.util.concurrent.Semaphore:release
    //#unanalyzed(void run()): Effects-of-calling:java.util.concurrent.Semaphore:tryAcquire
    //#unanalyzed(void run()): Effects-of-calling:java.lang.Thread:sleep
    //#unanalyzed(void run()): Effects-of-calling:java.net.ServerSocket:isClosed
    //#unanalyzed(void run()): Effects-of-calling:java.net.ServerSocket:close
    //#unanalyzed(void run()): Effects-of-calling:java.net.Socket:isClosed
    //#unanalyzed(void run()): Effects-of-calling:java.net.Socket:close
    //#unanalyzed(void run()): Effects-of-calling:socketClosed
    //#unanalyzed(void run()): Effects-of-calling:java.io.BufferedReader:readLine
    //#unanalyzed(void run()): Effects-of-calling:handleChatMessage
    //#unanalyzed(void run()): Effects-of-calling:java.net.Socket:getOutputStream
    //#unanalyzed(void run()): Effects-of-calling:java.io.PrintWriter
    //#unanalyzed(void run()): Effects-of-calling:java.net.Socket:getInputStream
    //#unanalyzed(void run()): Effects-of-calling:java.io.InputStreamReader
    //#unanalyzed(void run()): Effects-of-calling:java.io.BufferedReader
    //#unanalyzed(void run()): Effects-of-calling:socketOpened
    //#unanalyzed(void run()): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(void run()): Effects-of-calling:com.dmdirc.logger.Logger:assertTrue
    //#unanalyzed(void run()): Effects-of-calling:getType
    //#unanalyzed(void run()): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void run()): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void run()): Effects-of-calling:com.dmdirc.util.MapList:containsKey
    //#unanalyzed(void run()): Effects-of-calling:com.dmdirc.util.MapList:get
    //#unanalyzed(void run()): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(void run()): Effects-of-calling:java.util.ArrayList:iterator
    //#unanalyzed(void run()): Effects-of-calling:trigger
    //#unanalyzed(void run()): Effects-of-calling:getArity
    //#unanalyzed(void run()): Effects-of-calling:com.dmdirc.interfaces.ActionListener:processEvent
    //#unanalyzed(void run()): Effects-of-calling:addLine
    //#unanalyzed(void run()): Effects-of-calling:setIcon
    //#unanalyzed(void run()): Effects-of-calling:java.util.List:remove
    //#unanalyzed(void run()): Effects-of-calling:java.io.DataOutputStream:close
    //#unanalyzed(void run()): Effects-of-calling:java.io.DataInputStream:close
    //#unanalyzed(void run()): Effects-of-calling:com.dmdirc.ui.interfaces.InputWindow:getTranscoder
    //#unanalyzed(void run()): Effects-of-calling:com.dmdirc.util.StringTranscoder:encode
    //#unanalyzed(void run()): Effects-of-calling:java.io.DataInputStream:read
    //#unanalyzed(void run()): Effects-of-calling:dataTransfered
    //#unanalyzed(void run()): Effects-of-calling:java.io.DataOutputStream:write
    //#unanalyzed(void run()): Effects-of-calling:java.io.DataOutputStream:flush
    //#unanalyzed(void run()): Effects-of-calling:java.io.DataInputStream:readInt
    //#unanalyzed(void run()): Effects-of-calling:handleReceive
    //#unanalyzed(void run()): Effects-of-calling:java.io.DataOutputStream:writeInt
    //#unanalyzed(void run()): Effects-of-calling:java.io.File
    //#unanalyzed(void run()): Effects-of-calling:java.io.File:getAbsolutePath
    //#unanalyzed(void run()): Effects-of-calling:java.io.DataInputStream
    //#unanalyzed(void run()): Effects-of-calling:java.io.FileOutputStream
    //#unanalyzed(void run()): Effects-of-calling:java.io.DataOutputStream
    //#unanalyzed(void run()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void run()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void run()): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void run()): Effects-of-calling:java.lang.Long:valueOf
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:format
    //#unanalyzed(void run()): Effects-of-calling:javax.swing.JButton:setText
    //#unanalyzed(void run()): Effects-of-calling:javax.swing.JLabel:setText
    //#unanalyzed(void run()): Effects-of-calling:java.lang.System:currentTimeMillis
    //#unanalyzed(void run()): Effects-of-calling:updateSpeedAndTime
    //#unanalyzed(void run()): Effects-of-calling:java.lang.Math:floor
    //#unanalyzed(void run()): Effects-of-calling:javax.swing.JProgressBar:setValue
    //#unanalyzed(void run()): Effects-of-calling:java.lang.Double:valueOf
    //#unanalyzed(void run()): Effects-of-calling:isWindowClosing
    //#unanalyzed(void run()): Effects-of-calling:java.lang.Integer:valueOf
    //#test_vector(void run()): this.running: {0}, {1}
		running = true;
		// handleSocket is implemented by sub classes, and should return false
		// when the socket is closed.
		Thread thisThread = Thread.currentThread();

		while (myThread == thisThread) {
			serverSocketSem.acquireUninterruptibly();

			if (serverSocket == null) {
				serverSocketSem.release();
				
				if (!handleSocket()) {
					close();
					break;
				}
			} else {
				try {
					serverListeningSem.release();
					socket = serverSocket.accept();
					serverSocket.close();
					socketOpened();
				} catch (IOException ioe) {
    //#DCC.java:180: Warning: unused assignment
    //#    Unused assignment into ioe
    //#    severity: LOW
    //#    class: com.dmdirc.addons.dcc.DCC
    //#    method: void run()
                    socketClosed();
					break;
				} finally {
					serverListeningSem.acquireUninterruptibly();
					serverSocket = null;
					serverSocketSem.release();
				}
			}
		}
		// Socket closed

		thisThread = null;
    //#DCC.java:192: Warning: unused assignment
    //#    Unused assignment into thisThread
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.dcc.DCC
    //#    method: void run()
    //#    Attribs:  Uncertain
		running = false;
	}
    //#DCC.java:194: end of method: void com.dmdirc.addons.dcc.DCC.run()

	/**
	 * Called to close the socket
	 */
	protected void close() {
		boolean haveSLS = false;
    //#DCC.java:200: method: void com.dmdirc.addons.dcc.DCC.close()
    //#DCC.java:200: Warning: suspicious precondition
    //#    The precondition for this.__Tag is not a contiguous range of values
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.dcc.DCC
    //#    method: void close()
    //#    suspicious precondition index: [9]
    //#    Attribs:  Soft
    //#input(void close()): __Descendant_Table[com/dmdirc/addons/dcc/DCCChat]
    //#input(void close()): __Descendant_Table[com/dmdirc/addons/dcc/DCCSend]
    //#input(void close()): __Descendant_Table[com/dmdirc/addons/dcc/DCC]
    //#input(void close()): __Descendant_Table[others]
    //#input(void close()): __Dispatch_Table.socketClosed()V
    //#input(void close()): com/dmdirc/addons/dcc/DCCChat.__Dispatch_Table.socketClosed()V
    //#input(void close()): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCChatInterface]
    //#input(void close()): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCChatWindow]
    //#input(void close()): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[others]
    //#input(void close()): com/dmdirc/addons/dcc/DCCChatInterface.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void close()): com/dmdirc/addons/dcc/DCCChatWindow.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void close()): com/dmdirc/addons/dcc/DCCSend.SENDS
    //#input(void close()): com/dmdirc/addons/dcc/DCCSend.__Dispatch_Table.socketClosed()V
    //#input(void close()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendInterface]
    //#input(void close()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendWindow]
    //#input(void close()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[others]
    //#input(void close()): com/dmdirc/addons/dcc/DCCSendInterface.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void close()): com/dmdirc/addons/dcc/DCCSendWindow.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void close()): this
    //#input(void close()): this.__Tag
    //#input(void close()): this.handler.__Tag
    //#input(void close()): this.serverListeningSem
    //#input(void close()): this.serverSocket
    //#input(void close()): this.serverSocketSem
    //#input(void close()): this.socket
    //#output(void close()): this.in
    //#output(void close()): this.out
    //#output(void close()): this.serverSocket
    //#output(void close()): this.socket
    //#pre[15] (void close()): this.serverSocketSem != null
    //#pre[6] (void close()): (soft) init'ed(this.serverSocket)
    //#pre[7] (void close()): (soft) init'ed(this.socket)
    //#pre[9] (void close()): (soft) this.__Tag in {com/dmdirc/addons/dcc/DCC, com/dmdirc/addons/dcc/DCCChat, com/dmdirc/addons/dcc/DCCSend}
    //#pre[14] (void close()): (soft) this.serverListeningSem != null
    //#post(void close()): possibly_updated(this.in)
    //#post(void close()): possibly_updated(this.out)
    //#post(void close()): this.serverSocket == null
    //#post(void close()): this.socket == null
    //#unanalyzed(void close()): Effects-of-calling:socketClosed
    //#unanalyzed(void close()): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(void close()): Effects-of-calling:com.dmdirc.logger.Logger:assertTrue
    //#unanalyzed(void close()): Effects-of-calling:getType
    //#unanalyzed(void close()): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void close()): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void close()): Effects-of-calling:com.dmdirc.util.MapList:containsKey
    //#unanalyzed(void close()): Effects-of-calling:com.dmdirc.util.MapList:get
    //#unanalyzed(void close()): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(void close()): Effects-of-calling:java.util.ArrayList:iterator
    //#unanalyzed(void close()): Effects-of-calling:trigger
    //#unanalyzed(void close()): Effects-of-calling:getArity
    //#unanalyzed(void close()): Effects-of-calling:com.dmdirc.interfaces.ActionListener:processEvent
    //#unanalyzed(void close()): Effects-of-calling:addLine
    //#unanalyzed(void close()): Effects-of-calling:setIcon
    //#unanalyzed(void close()): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void close()): Effects-of-calling:java.util.List:remove
    //#unanalyzed(void close()): Effects-of-calling:java.io.DataOutputStream:close
    //#unanalyzed(void close()): Effects-of-calling:java.io.DataInputStream:close
    //#unanalyzed(void close()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void close()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void close()): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void close()): Effects-of-calling:java.lang.Long:valueOf
    //#unanalyzed(void close()): Effects-of-calling:java.lang.String:format
    //#unanalyzed(void close()): Effects-of-calling:javax.swing.JButton:setText
    //#unanalyzed(void close()): Effects-of-calling:javax.swing.JLabel:setText
    //#unanalyzed(void close()): Effects-of-calling:java.lang.System:currentTimeMillis
    //#unanalyzed(void close()): Effects-of-calling:java.lang.Math:floor
    //#unanalyzed(void close()): Effects-of-calling:javax.swing.JProgressBar:setValue
    //#unanalyzed(void close()): Effects-of-calling:java.lang.Double:valueOf
    //#unanalyzed(void close()): Effects-of-calling:isWindowClosing
    //#test_vector(void close()): java.net.ServerSocket:isClosed(...)@212: {1}, {0}
    //#test_vector(void close()): java.net.Socket:isClosed(...)@227: {1}, {0}
    //#test_vector(void close()): java.util.concurrent.Semaphore:tryAcquire(...)@202: {1}, {0}

		while (!serverSocketSem.tryAcquire() && !(haveSLS = serverListeningSem.tryAcquire())) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException ex) {
				// Do we care? I doubt we do! Should be unchecked damnit.
			}
		}

		if (serverSocket != null) {
			try {
				if (!serverSocket.isClosed()) {
					serverSocket.close();
				}
			} catch (IOException ioe) { }
			serverSocket = null;
		}

		if (haveSLS) {
			serverListeningSem.release();
		} else {
			serverSocketSem.release();
		}

		if (socket != null) {
			try {
				if (!socket.isClosed()) {
					socket.close();
				}
			} catch (IOException ioe) { }
			socketClosed();
			socket = null;
		}
	}
    //#DCC.java:234: end of method: void com.dmdirc.addons.dcc.DCC.close()

	/**
	 * Called when the socket is first opened, before any data is handled.
	 */
	protected void socketOpened() { }
    //#DCC.java:239: method: void com.dmdirc.addons.dcc.DCC.socketOpened()
    //#DCC.java:239: end of method: void com.dmdirc.addons.dcc.DCC.socketOpened()

	/**
	 * Called when the socket is closed, before the thread terminates.
	 */
	protected void socketClosed() { }
    //#DCC.java:244: method: void com.dmdirc.addons.dcc.DCC.socketClosed()
    //#DCC.java:244: end of method: void com.dmdirc.addons.dcc.DCC.socketClosed()

	/**
	 * Check if this socket can be written to.
	 *
	 * @return True if the socket is writable, false otehrwise
	 */
	public boolean isWriteable() {
		return false;
    //#DCC.java:252: method: bool com.dmdirc.addons.dcc.DCC.isWriteable()
    //#output(bool isWriteable()): return_value
    //#post(bool isWriteable()): return_value == 0
    //#DCC.java:252: end of method: bool com.dmdirc.addons.dcc.DCC.isWriteable()
	}

	/**
	 * Handle the socket.
	 *
	 * @return false when socket is closed, true will cause the method to be
	 *         called again.
	 */
	protected abstract boolean handleSocket();

	/**
	 * Set the address to connect to for this DCC
	 *
	 * @param address Address as an int (Network Byte Order, as specified in the DCC CTCP)
	 * @param port Port to connect to
	 */
	public void setAddress(final long address, final int port) {
		this.address = address;
    //#DCC.java:270: method: void com.dmdirc.addons.dcc.DCC.setAddress(long, int)
    //#input(void setAddress(long, int)): address
    //#input(void setAddress(long, int)): port
    //#input(void setAddress(long, int)): this
    //#output(void setAddress(long, int)): this.address
    //#output(void setAddress(long, int)): this.port
    //#post(void setAddress(long, int)): this.address == address
    //#post(void setAddress(long, int)): init'ed(this.address)
    //#post(void setAddress(long, int)): this.port == port
    //#post(void setAddress(long, int)): init'ed(this.port)
		this.port = port;
	}
    //#DCC.java:272: end of method: void com.dmdirc.addons.dcc.DCC.setAddress(long, int)

	/**
	 * Is this a listening socket
	 *
	 * @return True if this is a listening socket
	 */
	public boolean isListenSocket() {
		return listen;
    //#DCC.java:280: method: bool com.dmdirc.addons.dcc.DCC.isListenSocket()
    //#input(bool isListenSocket()): this
    //#input(bool isListenSocket()): this.listen
    //#output(bool isListenSocket()): return_value
    //#pre[2] (bool isListenSocket()): init'ed(this.listen)
    //#post(bool isListenSocket()): return_value == this.listen
    //#post(bool isListenSocket()): init'ed(return_value)
    //#DCC.java:280: end of method: bool com.dmdirc.addons.dcc.DCC.isListenSocket()
	}

	/**
	 * Get the host this socket is listening on/connecting to
	 *
	 * @return The IP that this socket is listening on/connecting to.
	 */
	public String getHost() {
		return longToIP(address);
    //#DCC.java:289: method: String com.dmdirc.addons.dcc.DCC.getHost()
    //#input(String getHost()): "."._tainted
    //#input(String getHost()): this
    //#input(String getHost()): this.address
    //#output(String getHost()): java.lang.StringBuilder:toString(...)._tainted
    //#output(String getHost()): return_value
    //#new obj(String getHost()): java.lang.StringBuilder:toString(...)
    //#pre[2] (String getHost()): init'ed(this.address)
    //#post(String getHost()): java.lang.StringBuilder:toString(...)._tainted == 0
    //#post(String getHost()): return_value == &java.lang.StringBuilder:toString(...)
    //#unanalyzed(String getHost()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(String getHost()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(String getHost()): Effects-of-calling:java.lang.StringBuilder:toString
    //#DCC.java:289: end of method: String com.dmdirc.addons.dcc.DCC.getHost()
	}

	/**
	 * Get the port this socket is listening on/connecting to
	 *
	 * @return The port that this socket is listening on/connecting to.
	 */
	public int getPort() {
		return port;
    //#DCC.java:298: method: int com.dmdirc.addons.dcc.DCC.getPort()
    //#input(int getPort()): this
    //#input(int getPort()): this.port
    //#output(int getPort()): return_value
    //#pre[2] (int getPort()): init'ed(this.port)
    //#post(int getPort()): return_value == this.port
    //#post(int getPort()): init'ed(return_value)
    //#DCC.java:298: end of method: int com.dmdirc.addons.dcc.DCC.getPort()
	}

	/**
	 * Convert the given IP Address to a long
	 *
	 * @param ip Input IP Address
	 * @return ip as a long
	 */
	public static long ipToLong(final String ip) {
		final String bits[] = ip.split("\\.");
    //#DCC.java:308: method: long com.dmdirc.addons.dcc.DCC.ipToLong(String)
    //#input(long ipToLong(String)): ip
    //#input(long ipToLong(String)): ip._tainted
    //#output(long ipToLong(String)): return_value
    //#pre[1] (long ipToLong(String)): ip != null
    //#post(long ipToLong(String)): return_value == 0
		if (bits.length > 3) {
    //#DCC.java:309: ?use of default init
    //#    init'ed(bits.length)
    //#    severity: LOW
    //#    class: com.dmdirc.addons.dcc.DCC
    //#    method: long ipToLong(String)
    //#    basic block: Entry_BB_1
    //#    assertion: init'ed(bits.length)
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
    //#DCC.java:309: Warning: test always goes same way
    //#    Test predetermined because bits.length == 0
    //#    severity: LOW
    //#    class: com.dmdirc.addons.dcc.DCC
    //#    method: long ipToLong(String)
    //#    from bb: Entry_BB_1
    //#    live edge: Entry_BB_1-->bb_3
    //#    tested vn: undefined - 3
    //#    tested vn values: {-3}
			return (Long.parseLong(bits[0]) << 24) + (Long.parseLong(bits[1]) << 16) + (Long.parseLong(bits[2]) << 8) + Long.parseLong(bits[3]);
    //#DCC.java:310: Warning: dead code
    //#    Dead code here because bits.length == 0
    //#    severity: LOW
    //#    class: com.dmdirc.addons.dcc.DCC
    //#    method: long ipToLong(String)
    //#    dead bb: bb_2
		}
		return 0;
    //#DCC.java:312: end of method: long com.dmdirc.addons.dcc.DCC.ipToLong(String)
	}

	/**
	 * Convert the given long to an IP Address
	 *
	 * @param in Input long
	 * @return long as an IP
	 */
	public static String longToIP(final long in) {
		return ((in & 0xff000000) >> 24)+"."+((in & 0x00ff0000) >> 16)+"."+((in & 0x0000ff00) >> 8)+"."+(in & 0x000000ff);
    //#DCC.java:322: method: String com.dmdirc.addons.dcc.DCC.longToIP(long)
    //#input(String longToIP(long)): "."._tainted
    //#input(String longToIP(long)): in
    //#output(String longToIP(long)): java.lang.StringBuilder:toString(...)._tainted
    //#output(String longToIP(long)): return_value
    //#new obj(String longToIP(long)): java.lang.StringBuilder:toString(...)
    //#post(String longToIP(long)): java.lang.StringBuilder:toString(...)._tainted == 0
    //#post(String longToIP(long)): return_value == &java.lang.StringBuilder:toString(...)
    //#DCC.java:322: end of method: String com.dmdirc.addons.dcc.DCC.longToIP(long)
	}
}
    //#output(com.dmdirc.addons.dcc.DCC__static_init): __Descendant_Table[com/dmdirc/addons/dcc/DCC]
    //#output(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.close()V
    //#output(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.connect()V
    //#output(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.getHost()Ljava/lang/String;
    //#output(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.getPort()I
    //#output(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.handleSocket()Z
    //#output(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.isListenSocket()Z
    //#output(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.isWriteable()Z
    //#output(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.listen()V
    //#output(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.listen(II)V
    //#output(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.run()V
    //#output(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.setAddress(JI)V
    //#output(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.socketClosed()V
    //#output(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.socketOpened()V
    //#post(com.dmdirc.addons.dcc.DCC__static_init): __Descendant_Table[com/dmdirc/addons/dcc/DCC] == &__Dispatch_Table
    //#post(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.close()V == &close
    //#post(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.connect()V == &connect
    //#post(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.getHost()Ljava/lang/String; == &getHost
    //#post(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.getPort()I == &getPort
    //#post(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.handleSocket()Z == &handleSocket
    //#post(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.isListenSocket()Z == &isListenSocket
    //#post(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.isWriteable()Z == &isWriteable
    //#post(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.listen()V == &listen
    //#post(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.listen(II)V == &listen
    //#post(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.run()V == &run
    //#post(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.setAddress(JI)V == &setAddress
    //#post(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.socketClosed()V == &socketClosed
    //#post(com.dmdirc.addons.dcc.DCC__static_init): __Dispatch_Table.socketOpened()V == &socketOpened
    //#DCC.java:: end of method: com.dmdirc.addons.dcc.DCC.com.dmdirc.addons.dcc.DCC__static_init
    //#DCC.java:: end of class: com.dmdirc.addons.dcc.DCC
