//# 0 errors, 783 messages
//#
/*
    //#DCCSend.java:1:1: class: com.dmdirc.addons.dcc.DCCSend$TransferType
    //#DCCSend.java:1:1: class: com.dmdirc.addons.dcc.DCCSend
 * 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.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

/**
 * This class handles a DCC Send.
 *
 * @author Shane 'Dataforce' McCormack
 */
public class DCCSend extends DCC {
	/** List of active sends. */
	private static final List<DCCSend> SENDS = new ArrayList<DCCSend>();
    //#DCCSend.java:42: method: com.dmdirc.addons.dcc.DCCSend.com.dmdirc.addons.dcc.DCCSend__static_init
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): SENDS
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Descendant_Table[com/dmdirc/addons/dcc/DCCSend]
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.close()V
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.connect()V
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.getFileName()Ljava/lang/String;
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.getFileSize()J
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.getFileStart()I
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.getHost()Ljava/lang/String;
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.getPort()I
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.getShortFileName()Ljava/lang/String;
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.getToken()Ljava/lang/String;
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.getType()Lcom/dmdirc/addons/dcc/DCCSend$TransferType;
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.handleReceive()Z
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.handleSend()Z
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.handleSocket()Z
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.isListenSocket()Z
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.isTurbo()Z
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.isWriteable()Z
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.listen()V
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.listen(II)V
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.makeToken()Ljava/lang/String;
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.removeFromSends()V
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.reset()V
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.run()V
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.setAddress(JI)V
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.setFileName(Ljava/lang/String;)V
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.setFileSize(J)V
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.setFileStart(I)I
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.setHandler(Lcom/dmdirc/addons/dcc/DCCSendInterface;)V
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.setToken(Ljava/lang/String;)V
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.setTurbo(Z)V
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.setType(Lcom/dmdirc/addons/dcc/DCCSend$TransferType;)V
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.socketClosed()V
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.socketOpened()V
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): com/dmdirc/addons/dcc/DCC.__Descendant_Table[com/dmdirc/addons/dcc/DCCSend]
    //#output(com.dmdirc.addons.dcc.DCCSend__static_init): new ArrayList(DCCSend__static_init#1) num objects
    //#new obj(com.dmdirc.addons.dcc.DCCSend__static_init): new ArrayList(DCCSend__static_init#1)
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): SENDS == &new ArrayList(DCCSend__static_init#1)
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Descendant_Table[com/dmdirc/addons/dcc/DCCSend] == &__Dispatch_Table
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): com/dmdirc/addons/dcc/DCC.__Descendant_Table[com/dmdirc/addons/dcc/DCCSend] == &__Dispatch_Table
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.close()V == &com/dmdirc/addons/dcc/DCC.close
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.connect()V == &com/dmdirc/addons/dcc/DCC.connect
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.getFileName()Ljava/lang/String; == &getFileName
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.getFileSize()J == &getFileSize
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.getFileStart()I == &getFileStart
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.getHost()Ljava/lang/String; == &com/dmdirc/addons/dcc/DCC.getHost
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.getPort()I == &com/dmdirc/addons/dcc/DCC.getPort
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.getShortFileName()Ljava/lang/String; == &getShortFileName
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.getToken()Ljava/lang/String; == &getToken
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.getType()Lcom/dmdirc/addons/dcc/DCCSend$TransferType; == &getType
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.handleReceive()Z == &handleReceive
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.handleSend()Z == &handleSend
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.handleSocket()Z == &handleSocket
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.isListenSocket()Z == &com/dmdirc/addons/dcc/DCC.isListenSocket
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.isTurbo()Z == &isTurbo
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.isWriteable()Z == &com/dmdirc/addons/dcc/DCC.isWriteable
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.listen()V == &com/dmdirc/addons/dcc/DCC.listen
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.listen(II)V == &com/dmdirc/addons/dcc/DCC.listen
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.makeToken()Ljava/lang/String; == &makeToken
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.removeFromSends()V == &removeFromSends
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.reset()V == &reset
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.run()V == &com/dmdirc/addons/dcc/DCC.run
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.setAddress(JI)V == &com/dmdirc/addons/dcc/DCC.setAddress
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.setFileName(Ljava/lang/String;)V == &setFileName
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.setFileSize(J)V == &setFileSize
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.setFileStart(I)I == &setFileStart
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.setHandler(Lcom/dmdirc/addons/dcc/DCCSendInterface;)V == &setHandler
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.setToken(Ljava/lang/String;)V == &setToken
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.setTurbo(Z)V == &setTurbo
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.setType(Lcom/dmdirc/addons/dcc/DCCSend$TransferType;)V == &setType
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.socketClosed()V == &socketClosed
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): __Dispatch_Table.socketOpened()V == &socketOpened
    //#post(com.dmdirc.addons.dcc.DCCSend__static_init): new ArrayList(DCCSend__static_init#1) num objects == 1
    //#DCCSend.java:42: end of method: com.dmdirc.addons.dcc.DCCSend.com.dmdirc.addons.dcc.DCCSend__static_init
	
	/** File Transfer Types. */
	public enum TransferType { SEND, RECEIVE; }
    //#DCCSend.java:45: method: DCCSend$TransferType[] com.dmdirc.addons.dcc.DCCSend$TransferType.values()
    //#input(DCCSend$TransferType[] values()): $VALUES
    //#input(DCCSend$TransferType[] values()): $VALUES.length
    //#input(DCCSend$TransferType[] values()): $VALUES[0..2]
    //#output(DCCSend$TransferType[] values()): new DCCSend$TransferType[](values#1) num objects
    //#output(DCCSend$TransferType[] values()): return_value.length
    //#output(DCCSend$TransferType[] values()): return_value[0..2]
    //#output(DCCSend$TransferType[] values()): return_value
    //#new obj(DCCSend$TransferType[] values()): new DCCSend$TransferType[](values#1)
    //#pre[1] (DCCSend$TransferType[] values()): (soft) init'ed($VALUES[0..2])
    //#post(DCCSend$TransferType[] values()): return_value == &new DCCSend$TransferType[](values#1)
    //#post(DCCSend$TransferType[] values()): new DCCSend$TransferType[](values#1) num objects == 1
    //#post(DCCSend$TransferType[] values()): return_value.length == 2
    //#post(DCCSend$TransferType[] values()): return_value[0..2] == One-of{$VALUES[0..2], undefined}
    //#DCCSend.java:45: end of method: DCCSend$TransferType[] com.dmdirc.addons.dcc.DCCSend$TransferType.values()
    //#DCCSend.java:45: method: DCCSend$TransferType com.dmdirc.addons.dcc.DCCSend$TransferType.valueOf(String)
    //#input(DCCSend$TransferType valueOf(String)): __Descendant_Table[com/dmdirc/addons/dcc/DCCSend$TransferType]
    //#input(DCCSend$TransferType valueOf(String)): __Descendant_Table[others]
    //#input(DCCSend$TransferType valueOf(String)): name
    //#output(DCCSend$TransferType valueOf(String)): return_value
    //#presumption(DCCSend$TransferType valueOf(String)): java.lang.Enum:valueOf(...).__Tag@45 == com/dmdirc/addons/dcc/DCCSend$TransferType
    //#post(DCCSend$TransferType valueOf(String)): init'ed(return_value)
    //#DCCSend.java:45: end of method: DCCSend$TransferType com.dmdirc.addons.dcc.DCCSend$TransferType.valueOf(String)
    //#DCCSend.java:45: method: void com.dmdirc.addons.dcc.DCCSend$TransferType.com.dmdirc.addons.dcc.DCCSend$TransferType(String, int)
    //#input(void com.dmdirc.addons.dcc.DCCSend$TransferType(String, int)): Param_1
    //#input(void com.dmdirc.addons.dcc.DCCSend$TransferType(String, int)): Param_2
    //#input(void com.dmdirc.addons.dcc.DCCSend$TransferType(String, int)): this
    //#DCCSend.java:45: end of method: void com.dmdirc.addons.dcc.DCCSend$TransferType.com.dmdirc.addons.dcc.DCCSend$TransferType(String, int)
    //#DCCSend.java:45: method: com.dmdirc.addons.dcc.DCCSend$TransferType.com.dmdirc.addons.dcc.DCCSend$TransferType__static_init
    //#output(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): $VALUES
    //#output(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): RECEIVE
    //#output(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): SEND
    //#output(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): __Descendant_Table[com/dmdirc/addons/dcc/DCCSend$TransferType]
    //#output(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): new DCCSend$TransferType(DCCSend$TransferType__static_init#1) num objects
    //#output(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): SEND.__Tag
    //#output(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): new DCCSend$TransferType(DCCSend$TransferType__static_init#2) num objects
    //#output(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): RECEIVE.__Tag
    //#output(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): new DCCSend$TransferType[](DCCSend$TransferType__static_init#3) num objects
    //#output(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): $VALUES.length
    //#output(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): $VALUES[0]
    //#output(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): $VALUES[1]
    //#new obj(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): new DCCSend$TransferType(DCCSend$TransferType__static_init#1)
    //#new obj(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): new DCCSend$TransferType(DCCSend$TransferType__static_init#2)
    //#new obj(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): new DCCSend$TransferType[](DCCSend$TransferType__static_init#3)
    //#post(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): $VALUES == &new DCCSend$TransferType[](DCCSend$TransferType__static_init#3)
    //#post(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): RECEIVE == &new DCCSend$TransferType(DCCSend$TransferType__static_init#2)
    //#post(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): $VALUES[1] == &new DCCSend$TransferType(DCCSend$TransferType__static_init#2)
    //#post(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): SEND == &new DCCSend$TransferType(DCCSend$TransferType__static_init#1)
    //#post(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): $VALUES[0] == &new DCCSend$TransferType(DCCSend$TransferType__static_init#1)
    //#post(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): __Descendant_Table[com/dmdirc/addons/dcc/DCCSend$TransferType] == &__Dispatch_Table
    //#post(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): new DCCSend$TransferType(DCCSend$TransferType__static_init#1) num objects == 1
    //#post(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): new DCCSend$TransferType(DCCSend$TransferType__static_init#2) num objects == 1
    //#post(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): new DCCSend$TransferType[](DCCSend$TransferType__static_init#3) num objects == 1
    //#post(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): SEND.__Tag == com/dmdirc/addons/dcc/DCCSend$TransferType
    //#post(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): RECEIVE.__Tag == com/dmdirc/addons/dcc/DCCSend$TransferType
    //#post(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): $VALUES.length == 2
    //#unanalyzed(com.dmdirc.addons.dcc.DCCSend$TransferType__static_init): Effects-of-calling:java.lang.Enum
    //#DCCSend.java:45: end of method: com.dmdirc.addons.dcc.DCCSend$TransferType.com.dmdirc.addons.dcc.DCCSend$TransferType__static_init
	/** The File transfer type for this file. */
	private TransferType transferType = TransferType.RECEIVE;
	/** The handler for this DCCSend. */
	private DCCSendInterface handler;
	/** Used to send data out the socket. */
	private DataOutputStream out;
	/** Used to read data from the socket. */
	private DataInputStream in;
	/** File we are using. */
	private File transferFile;
	/** Used to write data to the file. */
	private DataOutputStream fileOut;
	/** Used to read data from the file. */
	private DataInputStream fileIn;
	/** Where are we starting from? */
	private int startpos;
	/** How big is this file? */
	private long size = -1;
	/** How much of this file have we read so far? */
	private long readSize;
	/** What is the name of the file? */
	private String filename = "";
	/** What is the token for this send? */
	private String token = "";
	/** Block Size. */
	private final int blockSize;
	/** Is this a turbo dcc? */
	private boolean turbo = false;
	
	/** Creates a new instance of DCCSend with a default block size. */
	public DCCSend() {
		this(1024);
    //#DCCSend.java:77: method: void com.dmdirc.addons.dcc.DCCSend.com.dmdirc.addons.dcc.DCCSend()
    //#input(void com.dmdirc.addons.dcc.DCCSend()): SENDS
    //#input(void com.dmdirc.addons.dcc.DCCSend()): com/dmdirc/addons/dcc/DCCSend$TransferType.RECEIVE
    //#input(void com.dmdirc.addons.dcc.DCCSend()): this
    //#output(void com.dmdirc.addons.dcc.DCCSend()): new Semaphore(DCC#1) num objects
    //#output(void com.dmdirc.addons.dcc.DCCSend()): new Semaphore(DCC#2) num objects
    //#output(void com.dmdirc.addons.dcc.DCCSend()): this.address
    //#output(void com.dmdirc.addons.dcc.DCCSend()): this.blockSize
    //#output(void com.dmdirc.addons.dcc.DCCSend()): this.filename
    //#output(void com.dmdirc.addons.dcc.DCCSend()): this.listen
    //#output(void com.dmdirc.addons.dcc.DCCSend()): this.port
    //#output(void com.dmdirc.addons.dcc.DCCSend()): this.running
    //#output(void com.dmdirc.addons.dcc.DCCSend()): this.serverListeningSem
    //#output(void com.dmdirc.addons.dcc.DCCSend()): this.serverSocketSem
    //#output(void com.dmdirc.addons.dcc.DCCSend()): this.size
    //#output(void com.dmdirc.addons.dcc.DCCSend()): this.token
    //#output(void com.dmdirc.addons.dcc.DCCSend()): this.transferType
    //#output(void com.dmdirc.addons.dcc.DCCSend()): this.turbo
    //#new obj(void com.dmdirc.addons.dcc.DCCSend()): new Semaphore(DCC#1)
    //#new obj(void com.dmdirc.addons.dcc.DCCSend()): new Semaphore(DCC#2)
    //#post(void com.dmdirc.addons.dcc.DCCSend()): this.address == 0
    //#post(void com.dmdirc.addons.dcc.DCCSend()): this.listen == 0
    //#post(void com.dmdirc.addons.dcc.DCCSend()): this.port == 0
    //#post(void com.dmdirc.addons.dcc.DCCSend()): this.running == 0
    //#post(void com.dmdirc.addons.dcc.DCCSend()): this.turbo == 0
    //#post(void com.dmdirc.addons.dcc.DCCSend()): this.blockSize == 1_024
    //#post(void com.dmdirc.addons.dcc.DCCSend()): this.filename == &""
    //#post(void com.dmdirc.addons.dcc.DCCSend()): this.token == &""
    //#post(void com.dmdirc.addons.dcc.DCCSend()): this.serverListeningSem == &new Semaphore(DCC#2)
    //#post(void com.dmdirc.addons.dcc.DCCSend()): this.serverSocketSem == &new Semaphore(DCC#1)
    //#post(void com.dmdirc.addons.dcc.DCCSend()): this.size == -1
    //#post(void com.dmdirc.addons.dcc.DCCSend()): this.transferType == &com.dmdirc.addons.dcc.DCCSend$TransferType__static_init.new DCCSend$TransferType(DCCSend$TransferType__static_init#2)
    //#post(void com.dmdirc.addons.dcc.DCCSend()): new Semaphore(DCC#1) num objects == 1
    //#post(void com.dmdirc.addons.dcc.DCCSend()): new Semaphore(DCC#2) num objects == 1
    //#unanalyzed(void com.dmdirc.addons.dcc.DCCSend()): Effects-of-calling:java.util.concurrent.Semaphore
    //#unanalyzed(void com.dmdirc.addons.dcc.DCCSend()): Effects-of-calling:java.util.List:add
    //#unanalyzed(void com.dmdirc.addons.dcc.DCCSend()): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
	}
    //#DCCSend.java:78: end of method: void com.dmdirc.addons.dcc.DCCSend.com.dmdirc.addons.dcc.DCCSend()
	
	/**
	 * Creates a new instance of DCCSend.
	 *
	 * @param blockSize Block size to use
	 */
	public DCCSend(final int blockSize) {
		super();
    //#DCCSend.java:86: method: void com.dmdirc.addons.dcc.DCCSend.com.dmdirc.addons.dcc.DCCSend(int)
    //#input(void com.dmdirc.addons.dcc.DCCSend(int)): SENDS
    //#input(void com.dmdirc.addons.dcc.DCCSend(int)): blockSize
    //#input(void com.dmdirc.addons.dcc.DCCSend(int)): com/dmdirc/addons/dcc/DCCSend$TransferType.RECEIVE
    //#input(void com.dmdirc.addons.dcc.DCCSend(int)): SENDS.__Lock
    //#input(void com.dmdirc.addons.dcc.DCCSend(int)): this
    //#output(void com.dmdirc.addons.dcc.DCCSend(int)): new Semaphore(DCC#1) num objects
    //#output(void com.dmdirc.addons.dcc.DCCSend(int)): new Semaphore(DCC#2) num objects
    //#output(void com.dmdirc.addons.dcc.DCCSend(int)): this.address
    //#output(void com.dmdirc.addons.dcc.DCCSend(int)): this.blockSize
    //#output(void com.dmdirc.addons.dcc.DCCSend(int)): this.filename
    //#output(void com.dmdirc.addons.dcc.DCCSend(int)): this.listen
    //#output(void com.dmdirc.addons.dcc.DCCSend(int)): this.port
    //#output(void com.dmdirc.addons.dcc.DCCSend(int)): this.running
    //#output(void com.dmdirc.addons.dcc.DCCSend(int)): this.serverListeningSem
    //#output(void com.dmdirc.addons.dcc.DCCSend(int)): this.serverSocketSem
    //#output(void com.dmdirc.addons.dcc.DCCSend(int)): this.size
    //#output(void com.dmdirc.addons.dcc.DCCSend(int)): this.token
    //#output(void com.dmdirc.addons.dcc.DCCSend(int)): this.transferType
    //#output(void com.dmdirc.addons.dcc.DCCSend(int)): this.turbo
    //#new obj(void com.dmdirc.addons.dcc.DCCSend(int)): new Semaphore(DCC#1)
    //#new obj(void com.dmdirc.addons.dcc.DCCSend(int)): new Semaphore(DCC#2)
    //#post(void com.dmdirc.addons.dcc.DCCSend(int)): this.address == 0
    //#post(void com.dmdirc.addons.dcc.DCCSend(int)): this.listen == 0
    //#post(void com.dmdirc.addons.dcc.DCCSend(int)): this.port == 0
    //#post(void com.dmdirc.addons.dcc.DCCSend(int)): this.running == 0
    //#post(void com.dmdirc.addons.dcc.DCCSend(int)): this.turbo == 0
    //#post(void com.dmdirc.addons.dcc.DCCSend(int)): this.blockSize == blockSize
    //#post(void com.dmdirc.addons.dcc.DCCSend(int)): init'ed(this.blockSize)
    //#post(void com.dmdirc.addons.dcc.DCCSend(int)): this.filename == &""
    //#post(void com.dmdirc.addons.dcc.DCCSend(int)): this.token == &""
    //#post(void com.dmdirc.addons.dcc.DCCSend(int)): this.serverListeningSem == &new Semaphore(DCC#2)
    //#post(void com.dmdirc.addons.dcc.DCCSend(int)): this.serverSocketSem == &new Semaphore(DCC#1)
    //#post(void com.dmdirc.addons.dcc.DCCSend(int)): this.size == -1
    //#post(void com.dmdirc.addons.dcc.DCCSend(int)): this.transferType == &com.dmdirc.addons.dcc.DCCSend$TransferType__static_init.new DCCSend$TransferType(DCCSend$TransferType__static_init#2)
    //#post(void com.dmdirc.addons.dcc.DCCSend(int)): new Semaphore(DCC#1) num objects == 1
    //#post(void com.dmdirc.addons.dcc.DCCSend(int)): new Semaphore(DCC#2) num objects == 1
    //#unanalyzed(void com.dmdirc.addons.dcc.DCCSend(int)): Effects-of-calling:java.util.concurrent.Semaphore
		this.blockSize = blockSize;
		synchronized (SENDS) {
			SENDS.add(this);
		}
	}
    //#DCCSend.java:91: end of method: void com.dmdirc.addons.dcc.DCCSend.com.dmdirc.addons.dcc.DCCSend(int)
	
	/**
	 * Reset this send to be used again (eg a resend).
	 */
	public void reset() {
		close();
    //#DCCSend.java:97: method: void com.dmdirc.addons.dcc.DCCSend.reset()
    //#input(void reset()): SENDS
    //#input(void reset()): __Descendant_Table[com/dmdirc/addons/dcc/DCCSend]
    //#input(void reset()): __Descendant_Table[others]
    //#input(void reset()): __Dispatch_Table.close()V
    //#input(void reset()): __Dispatch_Table.setFileName(Ljava/lang/String;)V
    //#input(void reset()): __Dispatch_Table.setFileStart(I)I
    //#input(void reset()): __Dispatch_Table.socketClosed()V
    //#input(void reset()): com/dmdirc/addons/dcc/DCC.__Descendant_Table[com/dmdirc/addons/dcc/DCCChat]
    //#input(void reset()): com/dmdirc/addons/dcc/DCC.__Descendant_Table[com/dmdirc/addons/dcc/DCCSend]
    //#input(void reset()): com/dmdirc/addons/dcc/DCC.__Descendant_Table[com/dmdirc/addons/dcc/DCC]
    //#input(void reset()): com/dmdirc/addons/dcc/DCC.__Descendant_Table[others]
    //#input(void reset()): com/dmdirc/addons/dcc/DCC.__Dispatch_Table.socketClosed()V
    //#input(void reset()): com/dmdirc/addons/dcc/DCCChat.__Dispatch_Table.socketClosed()V
    //#input(void reset()): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCChatInterface]
    //#input(void reset()): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCChatWindow]
    //#input(void reset()): com/dmdirc/addons/dcc/DCCChatInterface.__Descendant_Table[others]
    //#input(void reset()): com/dmdirc/addons/dcc/DCCChatInterface.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void reset()): com/dmdirc/addons/dcc/DCCChatWindow.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCChat;)V
    //#input(void reset()): com/dmdirc/addons/dcc/DCCSend$TransferType.SEND
    //#input(void reset()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendInterface]
    //#input(void reset()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendWindow]
    //#input(void reset()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[others]
    //#input(void reset()): com/dmdirc/addons/dcc/DCCSendInterface.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void reset()): com/dmdirc/addons/dcc/DCCSendWindow.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void reset()): this
    //#input(void reset()): this.__Tag
    //#input(void reset()): this.fileIn
    //#input(void reset()): this.filename
    //#input(void reset()): this.handler.__Tag
    //#input(void reset()): this.serverListeningSem
    //#input(void reset()): this.serverSocket
    //#input(void reset()): this.serverSocketSem
    //#input(void reset()): this.socket
    //#input(void reset()): this.startpos
    //#input(void reset()): this.transferType
    //#output(void reset()): new DataInputStream(setFileName#2) num objects
    //#output(void reset()): new File(setFileName#1) num objects
    //#output(void reset()): this.fileIn
    //#output(void reset()): this.filename
    //#output(void reset()): this.in
    //#output(void reset()): this.out
    //#output(void reset()): this.readSize
    //#output(void reset()): this.serverSocket
    //#output(void reset()): this.socket
    //#output(void reset()): this.startpos
    //#output(void reset()): this.transferFile
    //#new obj(void reset()): new DataInputStream(setFileName#2)
    //#new obj(void reset()): new File(setFileName#1)
    //#pre[4] (void reset()): init'ed(this.filename)
    //#pre[12] (void reset()): init'ed(this.startpos)
    //#pre[35] (void reset()): this.serverSocketSem != null
    //#pre[37] (void reset()): init'ed(this.transferType)
    //#pre[3] (void reset()): (soft) init'ed(this.fileIn)
    //#pre[10] (void reset()): (soft) init'ed(this.serverSocket)
    //#pre[11] (void reset()): (soft) init'ed(this.socket)
    //#pre[18] (void reset()): (soft) this.__Tag == com/dmdirc/addons/dcc/DCCSend
    //#pre[34] (void reset()): (soft) this.serverListeningSem != null
    //#post(void reset()): this.fileIn == One-of{old this.fileIn, &new DataInputStream(setFileName#2), null}
    //#post(void reset()): init'ed(this.fileIn)
    //#post(void reset()): this.filename == old this.filename
    //#post(void reset()): init'ed(this.filename)
    //#post(void reset()): possibly_updated(this.in)
    //#post(void reset()): possibly_updated(this.out)
    //#post(void reset()): this.readSize == One-of{old this.startpos, old this.readSize}
    //#post(void reset()): this.serverSocket == null
    //#post(void reset()): this.socket == null
    //#post(void reset()): init'ed(this.startpos)
    //#post(void reset()): this.transferFile == One-of{old this.transferFile, &new File(setFileName#1)}
    //#post(void reset()): new DataInputStream(setFileName#2) num objects <= 1
    //#post(void reset()): new File(setFileName#1) num objects <= 1
    //#unanalyzed(void reset()): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void reset()): Effects-of-calling:java.util.List:remove
    //#unanalyzed(void reset()): Effects-of-calling:java.io.File
    //#unanalyzed(void reset()): Effects-of-calling:java.io.DataInputStream:skipBytes
    //#unanalyzed(void reset()): Effects-of-calling:java.io.File:getAbsolutePath
    //#unanalyzed(void reset()): Effects-of-calling:java.io.FileInputStream
    //#unanalyzed(void reset()): Effects-of-calling:java.io.DataInputStream
    //#unanalyzed(void reset()): Effects-of-calling:java.io.DataOutputStream:close
    //#unanalyzed(void reset()): Effects-of-calling:java.io.DataInputStream:close
    //#unanalyzed(void reset()): Effects-of-calling:socketClosed
    //#unanalyzed(void reset()): Effects-of-calling:java.util.concurrent.Semaphore:release
    //#unanalyzed(void reset()): Effects-of-calling:java.util.concurrent.Semaphore:tryAcquire
    //#unanalyzed(void reset()): Effects-of-calling:java.lang.Thread:sleep
    //#unanalyzed(void reset()): Effects-of-calling:java.net.ServerSocket:isClosed
    //#unanalyzed(void reset()): Effects-of-calling:java.net.ServerSocket:close
    //#unanalyzed(void reset()): Effects-of-calling:java.net.Socket:isClosed
    //#unanalyzed(void reset()): Effects-of-calling:java.net.Socket:close
    //#unanalyzed(void reset()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void reset()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void reset()): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void reset()): Effects-of-calling:java.lang.Long:valueOf
    //#unanalyzed(void reset()): Effects-of-calling:java.lang.String:format
    //#unanalyzed(void reset()): Effects-of-calling:javax.swing.JButton:setText
    //#unanalyzed(void reset()): Effects-of-calling:com.dmdirc.logger.Logger:assertTrue
    //#unanalyzed(void reset()): Effects-of-calling:getType
    //#unanalyzed(void reset()): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void reset()): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void reset()): Effects-of-calling:com.dmdirc.util.MapList:containsKey
    //#unanalyzed(void reset()): Effects-of-calling:com.dmdirc.util.MapList:get
    //#unanalyzed(void reset()): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(void reset()): Effects-of-calling:java.util.ArrayList:iterator
    //#unanalyzed(void reset()): Effects-of-calling:trigger
    //#unanalyzed(void reset()): Effects-of-calling:getArity
    //#unanalyzed(void reset()): Effects-of-calling:com.dmdirc.interfaces.ActionListener:processEvent
    //#unanalyzed(void reset()): Effects-of-calling:javax.swing.JLabel:setText
    //#unanalyzed(void reset()): Effects-of-calling:java.lang.System:currentTimeMillis
    //#unanalyzed(void reset()): Effects-of-calling:setIcon
    //#unanalyzed(void reset()): Effects-of-calling:java.lang.Math:floor
    //#unanalyzed(void reset()): Effects-of-calling:javax.swing.JProgressBar:setValue
    //#unanalyzed(void reset()): Effects-of-calling:java.lang.Double:valueOf
    //#unanalyzed(void reset()): Effects-of-calling:isWindowClosing
    //#unanalyzed(void reset()): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(void reset()): Effects-of-calling:addLine
		setFileName(filename);
		setFileStart(startpos);
	}
    //#DCCSend.java:100: end of method: void com.dmdirc.addons.dcc.DCCSend.reset()
	
	/**
	 * Get a copy of the list of active sends.
	 *
	 * @return A copy of the list of active sends.
	 */
	public static List<DCCSend> getSends() {
		synchronized (SENDS) {
    //#DCCSend.java:108: method: List com.dmdirc.addons.dcc.DCCSend.getSends()
    //#input(List getSends()): SENDS
    //#input(List getSends()): SENDS.__Lock
    //#output(List getSends()): new ArrayList(getSends#1) num objects
    //#output(List getSends()): return_value
    //#new obj(List getSends()): new ArrayList(getSends#1)
    //#post(List getSends()): return_value == &new ArrayList(getSends#1)
    //#post(List getSends()): new ArrayList(getSends#1) num objects == 1
			return new ArrayList<DCCSend>(SENDS);
		}
    //#DCCSend.java:110: end of method: List com.dmdirc.addons.dcc.DCCSend.getSends()
	}
	
	/**
	 * Called to remove this object from the sends list.
	 */
	public void removeFromSends() {
		synchronized (SENDS) {
    //#DCCSend.java:117: method: void com.dmdirc.addons.dcc.DCCSend.removeFromSends()
    //#input(void removeFromSends()): SENDS
    //#input(void removeFromSends()): SENDS.__Lock
    //#input(void removeFromSends()): this
			SENDS.remove(this);
		}
	}
    //#DCCSend.java:120: end of method: void com.dmdirc.addons.dcc.DCCSend.removeFromSends()
	
	/**
	 * Set the filename of this file
	 *
	 * @param filename Filename
	 */
	public void setFileName(final String filename) {
		this.filename = filename;
    //#DCCSend.java:128: method: void com.dmdirc.addons.dcc.DCCSend.setFileName(String)
    //#input(void setFileName(String)): com/dmdirc/addons/dcc/DCCSend$TransferType.SEND
    //#input(void setFileName(String)): filename
    //#input(void setFileName(String)): this
    //#input(void setFileName(String)): this.transferType
    //#output(void setFileName(String)): new DataInputStream(setFileName#2) num objects
    //#output(void setFileName(String)): new File(setFileName#1) num objects
    //#output(void setFileName(String)): this.fileIn
    //#output(void setFileName(String)): this.filename
    //#output(void setFileName(String)): this.transferFile
    //#new obj(void setFileName(String)): new DataInputStream(setFileName#2)
    //#new obj(void setFileName(String)): new File(setFileName#1)
    //#pre[5] (void setFileName(String)): init'ed(this.transferType)
    //#post(void setFileName(String)): this.fileIn == One-of{old this.fileIn, &new DataInputStream(setFileName#2), null}
    //#post(void setFileName(String)): this.filename == filename
    //#post(void setFileName(String)): init'ed(this.filename)
    //#post(void setFileName(String)): this.transferFile == One-of{old this.transferFile, &new File(setFileName#1)}
    //#post(void setFileName(String)): new DataInputStream(setFileName#2) num objects <= 1
    //#post(void setFileName(String)): new File(setFileName#1) num objects <= 1
		if (transferType == TransferType.SEND) {
			transferFile = new File(filename);
			try {
				fileIn = new DataInputStream(new FileInputStream(transferFile.getAbsolutePath()));
			} catch (FileNotFoundException e) {
				fileIn = null;
			} catch (SecurityException e) {
				fileIn = null;
			}
		}
	}
    //#DCCSend.java:139: end of method: void com.dmdirc.addons.dcc.DCCSend.setFileName(String)
	
	/**
	 * Get the filename of this file
	 *
	 * @return Filename
	 */
	public String getFileName() {
		return filename;
    //#DCCSend.java:147: method: String com.dmdirc.addons.dcc.DCCSend.getFileName()
    //#input(String getFileName()): this
    //#input(String getFileName()): this.filename
    //#output(String getFileName()): return_value
    //#pre[2] (String getFileName()): init'ed(this.filename)
    //#post(String getFileName()): return_value == this.filename
    //#post(String getFileName()): init'ed(return_value)
    //#DCCSend.java:147: end of method: String com.dmdirc.addons.dcc.DCCSend.getFileName()
	}
	
	/**
	 * Get the filename of this file, without the path
	 *
	 * @return Filename without path
	 */
	public String getShortFileName() {
		return (new File(filename)).getName();
    //#DCCSend.java:156: method: String com.dmdirc.addons.dcc.DCCSend.getShortFileName()
    //#input(String getShortFileName()): this
    //#input(String getShortFileName()): this.filename
    //#output(String getShortFileName()): return_value
    //#pre[2] (String getShortFileName()): init'ed(this.filename)
    //#post(String getShortFileName()): init'ed(return_value)
    //#DCCSend.java:156: end of method: String com.dmdirc.addons.dcc.DCCSend.getShortFileName()
	}
	
	/**
	 * Set dcc Type.
	 *
	 * @param type Type of DCC Send this is.
	 */
	public void setType(final TransferType type) {
		this.transferType = type;
    //#DCCSend.java:165: method: void com.dmdirc.addons.dcc.DCCSend.setType(DCCSend$TransferType)
    //#input(void setType(DCCSend$TransferType)): this
    //#input(void setType(DCCSend$TransferType)): type
    //#output(void setType(DCCSend$TransferType)): this.transferType
    //#post(void setType(DCCSend$TransferType)): this.transferType == type
    //#post(void setType(DCCSend$TransferType)): init'ed(this.transferType)
	}
    //#DCCSend.java:166: end of method: void com.dmdirc.addons.dcc.DCCSend.setType(DCCSend$TransferType)
	
	/**
	 * Get dcc Type.
	 *
	 * @return Type of DCC Send this is.
	 */
	public TransferType getType() {
		return transferType;
    //#DCCSend.java:174: method: DCCSend$TransferType com.dmdirc.addons.dcc.DCCSend.getType()
    //#input(DCCSend$TransferType getType()): this
    //#input(DCCSend$TransferType getType()): this.transferType
    //#output(DCCSend$TransferType getType()): return_value
    //#pre[2] (DCCSend$TransferType getType()): init'ed(this.transferType)
    //#post(DCCSend$TransferType getType()): return_value == this.transferType
    //#post(DCCSend$TransferType getType()): init'ed(return_value)
    //#DCCSend.java:174: end of method: DCCSend$TransferType com.dmdirc.addons.dcc.DCCSend.getType()
	}
	
	/**
	 * Set turbo mode on/off.
	 * Turbo mode doesn't wait for ack packets. Only relevent when sending.
	 *
	 * @param turbo True for turbo dcc, else false
	 */
	public void setTurbo(final boolean turbo) {
		this.turbo = turbo;
    //#DCCSend.java:184: method: void com.dmdirc.addons.dcc.DCCSend.setTurbo(bool)
    //#input(void setTurbo(bool)): this
    //#input(void setTurbo(bool)): turbo
    //#output(void setTurbo(bool)): this.turbo
    //#post(void setTurbo(bool)): this.turbo == turbo
    //#post(void setTurbo(bool)): init'ed(this.turbo)
	}
    //#DCCSend.java:185: end of method: void com.dmdirc.addons.dcc.DCCSend.setTurbo(bool)
	
	/**
	 * Is turbo mode on/off.
	 * Turbo mode doesn't wait for ack packets. Only relevent when sending.
	 *
	 * @return True for turbo dcc, else false
	 */
	public boolean isTurbo() {
		return turbo;
    //#DCCSend.java:194: method: bool com.dmdirc.addons.dcc.DCCSend.isTurbo()
    //#input(bool isTurbo()): this
    //#input(bool isTurbo()): this.turbo
    //#output(bool isTurbo()): return_value
    //#pre[2] (bool isTurbo()): init'ed(this.turbo)
    //#post(bool isTurbo()): return_value == this.turbo
    //#post(bool isTurbo()): init'ed(return_value)
    //#DCCSend.java:194: end of method: bool com.dmdirc.addons.dcc.DCCSend.isTurbo()
	}
	
	/**
	 * Set the Token for this send
	 *
	 * @param token Token for this send
	 */
	public void setToken(final String token) {
		this.token = token;
    //#DCCSend.java:203: method: void com.dmdirc.addons.dcc.DCCSend.setToken(String)
    //#input(void setToken(String)): this
    //#input(void setToken(String)): token
    //#output(void setToken(String)): this.token
    //#post(void setToken(String)): this.token == token
    //#post(void setToken(String)): init'ed(this.token)
	}
    //#DCCSend.java:204: end of method: void com.dmdirc.addons.dcc.DCCSend.setToken(String)
	
	/**
	 * Get the Token for this send
	 *
	 * @return Token for this send
	 */
	public String getToken() {
		return token;
    //#DCCSend.java:212: method: String com.dmdirc.addons.dcc.DCCSend.getToken()
    //#input(String getToken()): this
    //#input(String getToken()): this.token
    //#output(String getToken()): return_value
    //#pre[2] (String getToken()): init'ed(this.token)
    //#post(String getToken()): return_value == this.token
    //#post(String getToken()): init'ed(return_value)
    //#DCCSend.java:212: end of method: String com.dmdirc.addons.dcc.DCCSend.getToken()
	}
	
	/**
	 * Make a Token for this send.
	 * This token will be unique compared to all the other known sends
	 *
	 * @return The Token for this send.
	 */
	public String makeToken() {
		String myToken = "";
    //#DCCSend.java:222: method: String com.dmdirc.addons.dcc.DCCSend.makeToken()
    //#input(String makeToken()): ""._tainted
    //#input(String makeToken()): SENDS
    //#input(String makeToken()): __Descendant_Table[com/dmdirc/addons/dcc/DCCSend]
    //#input(String makeToken()): __Descendant_Table[others]
    //#input(String makeToken()): __Dispatch_Table.getToken()Ljava/lang/String;
    //#input(String makeToken()): __Dispatch_Table.setToken(Ljava/lang/String;)V
    //#input(String makeToken()): this
    //#input(String makeToken()): this.__Tag
    //#input(String makeToken()): this.filename
    //#input(String makeToken()): this.filename._tainted
    //#output(String makeToken()): java.lang.Integer:toString(...)._tainted
    //#output(String makeToken()): return_value
    //#output(String makeToken()): this.token
    //#new obj(String makeToken()): java.lang.Integer:toString(...)
    //#pre[3] (String makeToken()): this.__Tag == com/dmdirc/addons/dcc/DCCSend
    //#pre[4] (String makeToken()): init'ed(this.filename)
    //#post(String makeToken()): java.lang.Integer:toString(...)._tainted == 0
    //#post(String makeToken()): return_value == &java.lang.Integer:toString(...)
    //#post(String makeToken()): this.token == &java.lang.Integer:toString(...)
    //#unanalyzed(String makeToken()): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(String makeToken()): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(String makeToken()): Effects-of-calling:java.lang.String:isEmpty
    //#unanalyzed(String makeToken()): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(String makeToken()): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(String makeToken()): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(String makeToken()): Effects-of-calling:java.lang.String:equals
		boolean unique = true;
    //#DCCSend.java:223: Warning: unused assignment
    //#    Unused assignment into unique
    //#    severity: LOW
    //#    class: com.dmdirc.addons.dcc.DCCSend
    //#    method: String makeToken()
		do {
			myToken = Integer.toString(Math.abs((myToken+filename).hashCode()));
			unique = (findByToken(myToken) == null);
		} while (!unique);
		setToken(myToken);
		return myToken;
    //#DCCSend.java:229: end of method: String com.dmdirc.addons.dcc.DCCSend.makeToken()
	}
	
	/**
	 * Find a send based on a given token.
	 *
	 * @param token Token to look for. (case sensitive)
	 * @return The first DCCSend that matches the given token.
	 *         null if none match, or token is "" or null.
	 */
	public static DCCSend findByToken(final String token) {
		if (token == null || token.isEmpty()) { return null; }
    //#DCCSend.java:240: method: DCCSend com.dmdirc.addons.dcc.DCCSend.findByToken(String)
    //#input(DCCSend findByToken(String)): SENDS
    //#input(DCCSend findByToken(String)): __Descendant_Table[com/dmdirc/addons/dcc/DCCSend]
    //#input(DCCSend findByToken(String)): __Descendant_Table[others]
    //#input(DCCSend findByToken(String)): __Dispatch_Table.getToken()Ljava/lang/String;
    //#input(DCCSend findByToken(String)): token
    //#output(DCCSend findByToken(String)): return_value
    //#presumption(DCCSend findByToken(String)): java.util.Iterator:next(...).__Tag@241 == com/dmdirc/addons/dcc/DCCSend
    //#presumption(DCCSend findByToken(String)): java.util.Iterator:next(...)@241 != null
    //#presumption(DCCSend findByToken(String)): send.token@241 != null
    //#post(DCCSend findByToken(String)): init'ed(return_value)
    //#unanalyzed(DCCSend findByToken(String)): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(DCCSend findByToken(String)): Effects-of-calling:java.util.ArrayList
    //#test_vector(DCCSend findByToken(String)): token: Addr_Set{null}, Inverse{null}
    //#test_vector(DCCSend findByToken(String)): java.lang.String:equals(...)@242: {0}, {1}
    //#test_vector(DCCSend findByToken(String)): java.lang.String:isEmpty(...)@240: {0}, {1}
    //#test_vector(DCCSend findByToken(String)): java.util.Iterator:hasNext(...)@241: {0}, {1}
		for (DCCSend send : getSends()) {
			if (send.getToken().equals(token)) {
				return send;
			}
		}
		return null;
    //#DCCSend.java:246: end of method: DCCSend com.dmdirc.addons.dcc.DCCSend.findByToken(String)
	}
	
	/**
	 * Set the size of the file
	 *
	 * @param size File size
	 */
	public void setFileSize(final long size) {
		this.size = size;
    //#DCCSend.java:255: method: void com.dmdirc.addons.dcc.DCCSend.setFileSize(long)
    //#input(void setFileSize(long)): size
    //#input(void setFileSize(long)): this
    //#output(void setFileSize(long)): this.size
    //#post(void setFileSize(long)): this.size == size
    //#post(void setFileSize(long)): init'ed(this.size)
	}
    //#DCCSend.java:256: end of method: void com.dmdirc.addons.dcc.DCCSend.setFileSize(long)
	
	/**
	 * Get the expected size of the file
	 *
	 * @return The expected File size (-1 if unknown)
	 */
	public long getFileSize() {
		return size;
    //#DCCSend.java:264: method: long com.dmdirc.addons.dcc.DCCSend.getFileSize()
    //#input(long getFileSize()): this
    //#input(long getFileSize()): this.size
    //#output(long getFileSize()): return_value
    //#pre[2] (long getFileSize()): init'ed(this.size)
    //#post(long getFileSize()): return_value == this.size
    //#post(long getFileSize()): init'ed(return_value)
    //#DCCSend.java:264: end of method: long com.dmdirc.addons.dcc.DCCSend.getFileSize()
	}
	
	/**
	 * Set the starting position of the file
	 *
	 * @param startpos Starting position
	 * @return -1 if fileIn is null or if dcc receive, else the result of fileIn.skipBytes()
	 */
	public int setFileStart(final int startpos) {
		this.startpos = startpos;
    //#DCCSend.java:274: method: int com.dmdirc.addons.dcc.DCCSend.setFileStart(int)
    //#input(int setFileStart(int)): com/dmdirc/addons/dcc/DCCSend$TransferType.SEND
    //#input(int setFileStart(int)): startpos
    //#input(int setFileStart(int)): this
    //#input(int setFileStart(int)): this.fileIn
    //#input(int setFileStart(int)): this.transferType
    //#output(int setFileStart(int)): return_value
    //#output(int setFileStart(int)): this.readSize
    //#output(int setFileStart(int)): this.startpos
    //#pre[5] (int setFileStart(int)): init'ed(this.transferType)
    //#pre[4] (int setFileStart(int)): (soft) init'ed(this.fileIn)
    //#post(int setFileStart(int)): init'ed(return_value)
    //#post(int setFileStart(int)): this.readSize == One-of{startpos, old this.readSize}
    //#post(int setFileStart(int)): init'ed(this.startpos)
    //#test_vector(int setFileStart(int)): this.fileIn: Addr_Set{null}, Inverse{null}
		if (transferType == TransferType.SEND && fileIn != null) {
			try {
				this.startpos = fileIn.skipBytes(startpos);
				readSize = startpos;
				return this.startpos;
			} catch (IOException ioe) { }
		}
		return -1;
    //#DCCSend.java:282: end of method: int com.dmdirc.addons.dcc.DCCSend.setFileStart(int)
	}
	
	/**
	 * Get the starting position of the file
	 *
	 * @return starting position of file.
	 */
	public int getFileStart() {
		return this.startpos;
    //#DCCSend.java:291: method: int com.dmdirc.addons.dcc.DCCSend.getFileStart()
    //#input(int getFileStart()): this
    //#input(int getFileStart()): this.startpos
    //#output(int getFileStart()): return_value
    //#pre[2] (int getFileStart()): init'ed(this.startpos)
    //#post(int getFileStart()): return_value == this.startpos
    //#post(int getFileStart()): init'ed(return_value)
    //#DCCSend.java:291: end of method: int com.dmdirc.addons.dcc.DCCSend.getFileStart()
	}
	
	/**
	 * Change the handler for this DCC Send
	 *
	 * @param handler A class implementing DCCSendInterface
	 */
	public void setHandler(final DCCSendInterface handler) {
		this.handler = handler;
    //#DCCSend.java:300: method: void com.dmdirc.addons.dcc.DCCSend.setHandler(DCCSendInterface)
    //#input(void setHandler(DCCSendInterface)): handler
    //#input(void setHandler(DCCSendInterface)): this
    //#output(void setHandler(DCCSendInterface)): this.handler
    //#post(void setHandler(DCCSendInterface)): this.handler == handler
    //#post(void setHandler(DCCSendInterface)): init'ed(this.handler)
	}
    //#DCCSend.java:301: end of method: void com.dmdirc.addons.dcc.DCCSend.setHandler(DCCSendInterface)
	
	/**
	 * Called when the socket is first opened, before any data is handled.
	 */
	@Override
	protected void socketOpened() {
		try {
			transferFile = new File(filename);
    //#DCCSend.java:309: method: void com.dmdirc.addons.dcc.DCCSend.socketOpened()
    //#DCCSend.java:309: Warning: suspicious precondition
    //#    The precondition for this.handler.__Tag is not a contiguous range of values
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.dcc.DCCSend
    //#    method: void socketOpened()
    //#    suspicious precondition index: [11]
    //#    Attribs:  Soft
    //#input(void socketOpened()): SENDS
    //#input(void socketOpened()): __Descendant_Table[com/dmdirc/addons/dcc/DCCSend]
    //#input(void socketOpened()): __Descendant_Table[others]
    //#input(void socketOpened()): __Dispatch_Table.socketClosed()V
    //#input(void socketOpened()): com/dmdirc/addons/dcc/DCCSend$TransferType.RECEIVE
    //#input(void socketOpened()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendInterface]
    //#input(void socketOpened()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendWindow]
    //#input(void socketOpened()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[others]
    //#input(void socketOpened()): com/dmdirc/addons/dcc/DCCSendInterface.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void socketOpened()): com/dmdirc/addons/dcc/DCCSendInterface.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void socketOpened()): com/dmdirc/addons/dcc/DCCSendWindow.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void socketOpened()): com/dmdirc/addons/dcc/DCCSendWindow.__Dispatch_Table.socketOpened(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void socketOpened()): this
    //#input(void socketOpened()): this.__Tag
    //#input(void socketOpened()): this.filename
    //#input(void socketOpened()): this.handler
    //#input(void socketOpened()): this.handler.__Tag
    //#input(void socketOpened()): this.in
    //#input(void socketOpened()): this.out
    //#input(void socketOpened()): this.socket
    //#input(void socketOpened()): this.startpos
    //#input(void socketOpened()): this.transferType
    //#output(void socketOpened()): new DataInputStream(socketOpened#5) num objects
    //#output(void socketOpened()): new DataOutputStream(socketOpened#2) num objects
    //#output(void socketOpened()): new DataOutputStream(socketOpened#4) num objects
    //#output(void socketOpened()): new File(socketOpened#1) num objects
    //#output(void socketOpened()): this.fileOut
    //#output(void socketOpened()): this.handler.timeStarted
    //#output(void socketOpened()): this.in
    //#output(void socketOpened()): this.out
    //#output(void socketOpened()): this.transferFile
    //#new obj(void socketOpened()): new DataInputStream(socketOpened#5)
    //#new obj(void socketOpened()): new DataOutputStream(socketOpened#2)
    //#new obj(void socketOpened()): new DataOutputStream(socketOpened#4)
    //#new obj(void socketOpened()): new File(socketOpened#1)
    //#pre[10] (void socketOpened()): init'ed(this.handler)
    //#pre[4] (void socketOpened()): (soft) init'ed(this.in)
    //#pre[5] (void socketOpened()): (soft) init'ed(this.out)
    //#pre[8] (void socketOpened()): (soft) this.__Tag == com/dmdirc/addons/dcc/DCCSend
    //#pre[9] (void socketOpened()): (soft) init'ed(this.filename)
    //#pre[11] (void socketOpened()): (soft) this.handler.__Tag in {com/dmdirc/addons/dcc/DCCSendInterface, com/dmdirc/addons/dcc/DCCSendWindow}
    //#pre[12] (void socketOpened()): (soft) this.socket != null
    //#pre[13] (void socketOpened()): (soft) init'ed(this.startpos)
    //#pre[14] (void socketOpened()): (soft) init'ed(this.transferType)
    //#post(void socketOpened()): this.fileOut == One-of{old this.fileOut, &new DataOutputStream(socketOpened#2)}
    //#post(void socketOpened()): this.handler.timeStarted == old this.handler.timeStarted
    //#post(void socketOpened()): this.in in Addr_Set{null,&new DataInputStream(socketOpened#5)}
    //#post(void socketOpened()): this.out in Addr_Set{null,&new DataOutputStream(socketOpened#4)}
    //#post(void socketOpened()): this.transferFile == One-of{&new File(socketOpened#1), old this.transferFile}
    //#post(void socketOpened()): new DataInputStream(socketOpened#5) num objects <= 1
    //#post(void socketOpened()): new DataOutputStream(socketOpened#2) num objects <= 1
    //#post(void socketOpened()): new DataOutputStream(socketOpened#4) num objects <= 1
    //#post(void socketOpened()): new File(socketOpened#1) num objects <= 1
    //#unanalyzed(void socketOpened()): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void socketOpened()): Effects-of-calling:java.util.List:remove
    //#unanalyzed(void socketOpened()): Effects-of-calling:java.io.DataOutputStream:close
    //#unanalyzed(void socketOpened()): Effects-of-calling:java.io.DataInputStream:close
    //#unanalyzed(void socketOpened()): Effects-of-calling:socketClosed
    //#unanalyzed(void socketOpened()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void socketOpened()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void socketOpened()): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void socketOpened()): Effects-of-calling:java.lang.Long:valueOf
    //#unanalyzed(void socketOpened()): Effects-of-calling:java.lang.String:format
    //#unanalyzed(void socketOpened()): Effects-of-calling:javax.swing.JButton:setText
    //#unanalyzed(void socketOpened()): Effects-of-calling:com.dmdirc.logger.Logger:assertTrue
    //#unanalyzed(void socketOpened()): Effects-of-calling:getType
    //#unanalyzed(void socketOpened()): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void socketOpened()): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void socketOpened()): Effects-of-calling:com.dmdirc.util.MapList:containsKey
    //#unanalyzed(void socketOpened()): Effects-of-calling:com.dmdirc.util.MapList:get
    //#unanalyzed(void socketOpened()): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(void socketOpened()): Effects-of-calling:java.util.ArrayList:iterator
    //#unanalyzed(void socketOpened()): Effects-of-calling:trigger
    //#unanalyzed(void socketOpened()): Effects-of-calling:getArity
    //#unanalyzed(void socketOpened()): Effects-of-calling:com.dmdirc.interfaces.ActionListener:processEvent
    //#unanalyzed(void socketOpened()): Effects-of-calling:javax.swing.JLabel:setText
    //#unanalyzed(void socketOpened()): Effects-of-calling:java.lang.System:currentTimeMillis
    //#unanalyzed(void socketOpened()): Effects-of-calling:setIcon
    //#unanalyzed(void socketOpened()): Effects-of-calling:java.lang.Math:floor
    //#unanalyzed(void socketOpened()): Effects-of-calling:javax.swing.JProgressBar:setValue
    //#unanalyzed(void socketOpened()): Effects-of-calling:java.lang.Double:valueOf
    //#unanalyzed(void socketOpened()): Effects-of-calling:isWindowClosing
    //#test_vector(void socketOpened()): this.handler: Addr_Set{null}, Inverse{null}
			if (transferType == TransferType.RECEIVE) {
				fileOut = new DataOutputStream(new FileOutputStream(transferFile.getAbsolutePath(), (startpos > 0)));
			}
			out = new DataOutputStream(socket.getOutputStream());
			in = new DataInputStream(socket.getInputStream());
			if (handler != null) {
				handler.socketOpened(this);
    //#DCCSend.java:316: Warning: call too complex - analysis skipped
    //#    call on void socketOpened(DCCSend)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.dcc.DCCSend
    //#    method: void socketOpened()
    //#    unanalyzed callee: void socketOpened(DCCSend)
			}
		} catch (IOException ioe) {
            socketClosed();
        }
	}
    //#DCCSend.java:321: end of method: void com.dmdirc.addons.dcc.DCCSend.socketOpened()
	
	/**
	 * Called when the socket is closed, before the thread terminates.
	 */
	@Override
	protected void socketClosed() {
		// Try to close both, even if one fails.
		if (out != null) { try { out.close(); } catch (IOException e) { } }
    //#DCCSend.java:329: method: void com.dmdirc.addons.dcc.DCCSend.socketClosed()
    //#DCCSend.java:329: Warning: suspicious precondition
    //#    The precondition for this.handler.__Tag is not a contiguous range of values
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.dcc.DCCSend
    //#    method: void socketClosed()
    //#    suspicious precondition index: [10]
    //#    Attribs:  Soft
    //#input(void socketClosed()): SENDS
    //#input(void socketClosed()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendInterface]
    //#input(void socketClosed()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendWindow]
    //#input(void socketClosed()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[others]
    //#input(void socketClosed()): com/dmdirc/addons/dcc/DCCSendInterface.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void socketClosed()): com/dmdirc/addons/dcc/DCCSendWindow.__Dispatch_Table.socketClosed(Lcom/dmdirc/addons/dcc/DCCSend;)V
    //#input(void socketClosed()): SENDS.__Lock
    //#input(void socketClosed()): this
    //#input(void socketClosed()): this.handler
    //#input(void socketClosed()): this.handler.__Tag
    //#input(void socketClosed()): this.in
    //#input(void socketClosed()): this.out
    //#output(void socketClosed()): this.in
    //#output(void socketClosed()): this.out
    //#pre[2] (void socketClosed()): init'ed(this.in)
    //#pre[3] (void socketClosed()): init'ed(this.out)
    //#pre[9] (void socketClosed()): init'ed(this.handler)
    //#pre[10] (void socketClosed()): (soft) this.handler.__Tag in {com/dmdirc/addons/dcc/DCCSendInterface, com/dmdirc/addons/dcc/DCCSendWindow}
    //#post(void socketClosed()): this.in == null
    //#post(void socketClosed()): this.out == null
    //#test_vector(void socketClosed()): this.in: Addr_Set{null}, Inverse{null}
    //#test_vector(void socketClosed()): this.out: Addr_Set{null}, Inverse{null}
    //#test_vector(void socketClosed()): this.handler: Addr_Set{null}, Inverse{null}
		if (in != null) { try { in.close(); } catch (IOException e) { } }
		out = null;
		in = null;
		if (handler != null) {
			handler.socketClosed(this);
    //#DCCSend.java:334: Warning: call too complex - analysis skipped
    //#    call on void socketClosed(DCCSend)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.dcc.DCCSend
    //#    method: void socketClosed()
    //#    unanalyzed callee: void socketClosed(DCCSend)
		}
		synchronized (SENDS) {
			SENDS.remove(this);
		}
	}
    //#DCCSend.java:339: end of method: void com.dmdirc.addons.dcc.DCCSend.socketClosed()
	
	/**
	 * Handle the socket.
	 *
	 * @return false when socket is closed, true will cause the method to be
	 *         called again.
	 */
	@Override
	protected boolean handleSocket() {
		if (out == null || in == null) { return false; }	
    //#DCCSend.java:349: method: bool com.dmdirc.addons.dcc.DCCSend.handleSocket()
    //#DCCSend.java:349: Warning: suspicious precondition
    //#    The precondition for this.handler.__Tag is not a contiguous range of values
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.dcc.DCCSend
    //#    method: bool handleSocket()
    //#    suspicious precondition index: [14]
    //#    Attribs:  Soft
    //#input(bool handleSocket()): __Descendant_Table[com/dmdirc/addons/dcc/DCCSend]
    //#input(bool handleSocket()): __Descendant_Table[others]
    //#input(bool handleSocket()): __Dispatch_Table.handleReceive()Z
    //#input(bool handleSocket()): __Dispatch_Table.handleSend()Z
    //#input(bool handleSocket()): com/dmdirc/addons/dcc/DCCSend$TransferType.RECEIVE
    //#input(bool handleSocket()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendInterface]
    //#input(bool handleSocket()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendWindow]
    //#input(bool handleSocket()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[others]
    //#input(bool handleSocket()): com/dmdirc/addons/dcc/DCCSendInterface.__Dispatch_Table.dataTransfered(Lcom/dmdirc/addons/dcc/DCCSend;I)V
    //#input(bool handleSocket()): com/dmdirc/addons/dcc/DCCSendWindow.__Dispatch_Table.dataTransfered(Lcom/dmdirc/addons/dcc/DCCSend;I)V
    //#input(bool handleSocket()): this
    //#input(bool handleSocket()): this.__Tag
    //#input(bool handleSocket()): this.blockSize
    //#input(bool handleSocket()): this.fileIn
    //#input(bool handleSocket()): this.fileOut
    //#input(bool handleSocket()): this.handler
    //#input(bool handleSocket()): this.handler.__Tag
    //#input(bool handleSocket()): this.in
    //#input(bool handleSocket()): this.out
    //#input(bool handleSocket()): this.readSize
    //#input(bool handleSocket()): this.size
    //#input(bool handleSocket()): this.transferType
    //#input(bool handleSocket()): this.turbo
    //#output(bool handleSocket()): return_value
    //#output(bool handleSocket()): this.handler.transferCount
    //#output(bool handleSocket()): this.readSize
    //#pre[16] (bool handleSocket()): init'ed(this.out)
    //#pre[6] (bool handleSocket()): (soft) this.readSize in {-6_442_450_943..6_442_450_943}
    //#pre[8] (bool handleSocket()): (soft) this.__Tag == com/dmdirc/addons/dcc/DCCSend
    //#pre[9] (bool handleSocket()): (soft) this.blockSize >= 0
    //#pre[10] (bool handleSocket()): (soft) this.fileIn != null
    //#pre[11] (bool handleSocket()): (soft) this.fileOut != null
    //#pre[12] (bool handleSocket()): (soft) init'ed(this.handler)
    //#pre[14] (bool handleSocket()): (soft) this.handler.__Tag in {com/dmdirc/addons/dcc/DCCSendInterface, com/dmdirc/addons/dcc/DCCSendWindow}
    //#pre[15] (bool handleSocket()): (soft) init'ed(this.in)
    //#pre[17] (bool handleSocket()): (soft) init'ed(this.size)
    //#pre[18] (bool handleSocket()): (soft) init'ed(this.transferType)
    //#pre[19] (bool handleSocket()): (soft) init'ed(this.turbo)
    //#post(bool handleSocket()): init'ed(return_value)
    //#post(bool handleSocket()): possibly_updated(this.handler.transferCount)
    //#post(bool handleSocket()): init'ed(this.readSize)
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.io.DataOutputStream:close
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.io.DataInputStream:close
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.io.DataInputStream:read
    //#unanalyzed(bool handleSocket()): Effects-of-calling:dataTransfered
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.io.DataOutputStream:write
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.io.DataOutputStream:flush
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.io.DataInputStream:readInt
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.io.DataOutputStream:writeInt
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.lang.Long:valueOf
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.lang.String:format
    //#unanalyzed(bool handleSocket()): Effects-of-calling:com.dmdirc.logger.Logger:assertTrue
    //#unanalyzed(bool handleSocket()): Effects-of-calling:getType
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(bool handleSocket()): Effects-of-calling:com.dmdirc.util.MapList:containsKey
    //#unanalyzed(bool handleSocket()): Effects-of-calling:com.dmdirc.util.MapList:get
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.util.ArrayList:iterator
    //#unanalyzed(bool handleSocket()): Effects-of-calling:trigger
    //#unanalyzed(bool handleSocket()): Effects-of-calling:getArity
    //#unanalyzed(bool handleSocket()): Effects-of-calling:com.dmdirc.interfaces.ActionListener:processEvent
    //#unanalyzed(bool handleSocket()): Effects-of-calling:javax.swing.JLabel:setText
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.lang.System:currentTimeMillis
    //#unanalyzed(bool handleSocket()): Effects-of-calling:updateSpeedAndTime
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.lang.Math:floor
    //#unanalyzed(bool handleSocket()): Effects-of-calling:javax.swing.JProgressBar:setValue
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.lang.Double:valueOf
    //#unanalyzed(bool handleSocket()): Effects-of-calling:java.lang.Integer:valueOf
    //#test_vector(bool handleSocket()): this.in: Inverse{null}, Addr_Set{null}
    //#test_vector(bool handleSocket()): this.out: Addr_Set{null}, Inverse{null}
		if (transferType == TransferType.RECEIVE) {
			return handleReceive();
		} else {
			return handleSend();
    //#DCCSend.java:353: end of method: bool com.dmdirc.addons.dcc.DCCSend.handleSocket()
		}
	}
	
	
	/**
	 * Handle the socket as a RECEIVE.
	 *
	 * @return false when socket is closed (or should be closed), true will cause the method to be
	 *         called again.
	 */
	protected boolean handleReceive() {
		try {
			final byte[] data = new byte[blockSize];
    //#DCCSend.java:366: method: bool com.dmdirc.addons.dcc.DCCSend.handleReceive()
    //#DCCSend.java:366: Warning: suspicious precondition
    //#    The precondition for this.handler.__Tag is not a contiguous range of values
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.dcc.DCCSend
    //#    method: bool handleReceive()
    //#    suspicious precondition index: [14]
    //#    Attribs:  Soft
    //#input(bool handleReceive()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendInterface]
    //#input(bool handleReceive()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendWindow]
    //#input(bool handleReceive()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[others]
    //#input(bool handleReceive()): com/dmdirc/addons/dcc/DCCSendInterface.__Dispatch_Table.dataTransfered(Lcom/dmdirc/addons/dcc/DCCSend;I)V
    //#input(bool handleReceive()): com/dmdirc/addons/dcc/DCCSendWindow.__Dispatch_Table.dataTransfered(Lcom/dmdirc/addons/dcc/DCCSend;I)V
    //#input(bool handleReceive()): this
    //#input(bool handleReceive()): this.blockSize
    //#input(bool handleReceive()): this.fileOut
    //#input(bool handleReceive()): this.handler
    //#input(bool handleReceive()): this.handler.__Tag
    //#input(bool handleReceive()): this.in
    //#input(bool handleReceive()): this.out
    //#input(bool handleReceive()): this.readSize
    //#input(bool handleReceive()): this.size
    //#output(bool handleReceive()): return_value
    //#output(bool handleReceive()): this.handler.transferCount
    //#output(bool handleReceive()): this.readSize
    //#pre[4] (bool handleReceive()): (soft) this.readSize in {-6_442_450_943..6_442_450_943}
    //#pre[10] (bool handleReceive()): (soft) this.blockSize >= 0
    //#pre[11] (bool handleReceive()): (soft) this.fileOut != null
    //#pre[12] (bool handleReceive()): (soft) init'ed(this.handler)
    //#pre[14] (bool handleReceive()): (soft) this.handler.__Tag in {com/dmdirc/addons/dcc/DCCSendInterface, com/dmdirc/addons/dcc/DCCSendWindow}
    //#pre[22] (bool handleReceive()): (soft) this.in != null
    //#pre[23] (bool handleReceive()): (soft) this.out != null
    //#pre[24] (bool handleReceive()): (soft) init'ed(this.size)
    //#presumption(bool handleReceive()): this.readSize + java.io.DataInputStream:read(...)@367 in {-2_147_483_648..4_294_967_295}
    //#post(bool handleReceive()): init'ed(return_value)
    //#post(bool handleReceive()): this.handler.transferCount == old this.handler.transferCount
    //#post(bool handleReceive()): this.readSize in {-6_442_450_943..6_442_450_943}
    //#test_vector(bool handleReceive()): this.handler: Addr_Set{null}, Inverse{null}
    //#test_vector(bool handleReceive()): java.io.DataInputStream:read(...)@367: {0}, {1..4_294_967_295}, {-2_147_483_648..-1}
			final int bytesRead = in.read(data);
			readSize = readSize + bytesRead;
			
			if (bytesRead > 0) {
				if (handler != null) { handler.dataTransfered(this, bytesRead); }
    //#DCCSend.java:371: Warning: call too complex - analysis skipped
    //#    call on void dataTransfered(DCCSend, int)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.dcc.DCCSend
    //#    method: bool handleReceive()
    //#    unanalyzed callee: void dataTransfered(DCCSend, int)
				fileOut.write(data, 0, bytesRead);
				// Send ack
				out.writeInt((int)readSize);
				out.flush();
				if (readSize == size) {
					fileOut.close();
					return false;
				} else {
					return true;
				}
			} else if (bytesRead < 0) {
				fileOut.close();
				return false;
			}
		} catch (IOException e) {
			return false;
		}
		return false;
    //#DCCSend.java:389: end of method: bool com.dmdirc.addons.dcc.DCCSend.handleReceive()
	}
	
	/**
	 * Handle the socket as a SEND.
	 *
	 * @return false when socket is closed (or should be closed), true will cause the method to be
	 *         called again.
	 */
	protected boolean handleSend() {
		try {
			final byte[] data = new byte[blockSize];
    //#DCCSend.java:400: method: bool com.dmdirc.addons.dcc.DCCSend.handleSend()
    //#DCCSend.java:400: Warning: suspicious precondition
    //#    The precondition for this.handler.__Tag is not a contiguous range of values
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.dcc.DCCSend
    //#    method: bool handleSend()
    //#    suspicious precondition index: [14]
    //#    Attribs:  Soft
    //#input(bool handleSend()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendInterface]
    //#input(bool handleSend()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[com/dmdirc/addons/dcc/DCCSendWindow]
    //#input(bool handleSend()): com/dmdirc/addons/dcc/DCCSendInterface.__Descendant_Table[others]
    //#input(bool handleSend()): com/dmdirc/addons/dcc/DCCSendInterface.__Dispatch_Table.dataTransfered(Lcom/dmdirc/addons/dcc/DCCSend;I)V
    //#input(bool handleSend()): com/dmdirc/addons/dcc/DCCSendWindow.__Dispatch_Table.dataTransfered(Lcom/dmdirc/addons/dcc/DCCSend;I)V
    //#input(bool handleSend()): this
    //#input(bool handleSend()): this.blockSize
    //#input(bool handleSend()): this.fileIn
    //#input(bool handleSend()): this.handler
    //#input(bool handleSend()): this.handler.__Tag
    //#input(bool handleSend()): this.in
    //#input(bool handleSend()): this.out
    //#input(bool handleSend()): this.readSize
    //#input(bool handleSend()): this.size
    //#input(bool handleSend()): this.turbo
    //#output(bool handleSend()): return_value
    //#output(bool handleSend()): this.handler.transferCount
    //#output(bool handleSend()): this.readSize
    //#pre[4] (bool handleSend()): (soft) init'ed(this.readSize)
    //#pre[10] (bool handleSend()): (soft) this.blockSize >= 0
    //#pre[11] (bool handleSend()): (soft) this.fileIn != null
    //#pre[12] (bool handleSend()): (soft) init'ed(this.handler)
    //#pre[14] (bool handleSend()): (soft) this.handler.__Tag in {com/dmdirc/addons/dcc/DCCSendInterface, com/dmdirc/addons/dcc/DCCSendWindow}
    //#pre[22] (bool handleSend()): (soft) this.in != null
    //#pre[23] (bool handleSend()): (soft) this.out != null
    //#pre[24] (bool handleSend()): (soft) init'ed(this.size)
    //#pre[27] (bool handleSend()): (soft) init'ed(this.turbo)
    //#presumption(bool handleSend()): this.readSize + java.io.DataInputStream:read(...)@401 in {-9_223_372_036_854_775_808..18_446_744_073_709_551_615}
    //#post(bool handleSend()): init'ed(return_value)
    //#post(bool handleSend()): this.handler.transferCount == old this.handler.transferCount
    //#post(bool handleSend()): init'ed(this.readSize)
    //#test_vector(bool handleSend()): this.handler: Addr_Set{null}, Inverse{null}
    //#test_vector(bool handleSend()): this.turbo: {1}, {0}
    //#test_vector(bool handleSend()): java.io.DataInputStream:read(...)@401: {0}, {1..4_294_967_295}, {-2_147_483_648..-1}
    //#test_vector(bool handleSend()): java.io.DataInputStream:readInt(...)@429: {-2_147_483_648..0}, {1..4_294_967_295}
			int bytesRead = fileIn.read(data);
			readSize = readSize + bytesRead;
			
			if (bytesRead > 0) {
				if (handler != null) { handler.dataTransfered(this, bytesRead); }
    //#DCCSend.java:405: Warning: call too complex - analysis skipped
    //#    call on void dataTransfered(DCCSend, int)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.dcc.DCCSend
    //#    method: bool handleSend()
    //#    unanalyzed callee: void dataTransfered(DCCSend, int)
				out.write(data, 0, bytesRead);
				out.flush();
				
				// Wait for acknowlegement packet.
				if (!turbo) {
					int bytesRecieved;
					do {
						bytesRecieved = in.readInt();
					} while ((readSize - bytesRecieved) > 0);
				}
				
				if (readSize == size) {
					fileIn.close();
					
					// Process all the ack packets that may have been sent.
					// In true turbo dcc mode, none will have been sent and the socket
					// will just close, in fast-dcc mode all the acks will be here,
					// So keep reading acks untill the socket closes (IOException) or we
					// have recieved all the acks.
					if (turbo) {
						int ack = 0;
    //#DCCSend.java:426: Warning: unused assignment
    //#    Unused assignment into ack
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.dcc.DCCSend
    //#    method: bool handleSend()
    //#    Attribs:  Uncertain
						do {
							try {
								ack = in.readInt();
							} catch (IOException e) {
								break;
							}
						} while (ack > 0 && (readSize - ack) > 0);
					}
					
					return false;
				}
				
				return true;
			} else if (bytesRead < 0) {
				fileIn.close();
				return true;
			}
		} catch (IOException e) {
			return false;
		}
		return false;
    //#DCCSend.java:447: end of method: bool com.dmdirc.addons.dcc.DCCSend.handleSend()
	}
}
    //#DCCSend.java:: end of class: com.dmdirc.addons.dcc.DCCSend$TransferType
    //#DCCSend.java:: end of class: com.dmdirc.addons.dcc.DCCSend
