//# 25 errors, 865 messages
//#
/*
    //#ClientInfo.java:1:1: class: com.dmdirc.parser.irc.ClientInfo
    //#ClientInfo.java:1:1: method: com.dmdirc.parser.irc.ClientInfo.com.dmdirc.parser.irc.ClientInfo__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.parser.irc;

import java.util.ArrayList;
import java.util.List;
import java.util.LinkedList;
import java.util.Hashtable;
import java.util.HashMap;
import java.util.Map;

/**
 * Contains information about known users.
 * 
 * @author Shane Mc Cormack
 * @author Chris Smith
 * @see IRCParser
 */
public final class ClientInfo {
	/** Known nickname of client. */
	private String sNickname = "";
	/** Known ident of client. */
	private String sIdent = "";	
	/** Known host of client. */
	private String sHost = "";
	/** Known user modes of client. */
	private long nModes;
	/** Known Away Reason of client. */
	private String myAwayReason = "";
	/** Known RealName of client. */
	private String sRealName = "";
	/** Known away state for client. */
	private boolean bIsAway;
	/** Is this a fake client created just for a callback? */
	private boolean bIsFake;
	/** Reference to the parser object that owns this channel, Used for modes. */
	private final IRCParser myParser;
	/** A Map to allow applications to attach misc data to this object */
	private Map myMap;
	/** List of ChannelClientInfos that point to this */
	private final Map<String, ChannelClientInfo> myChannelClientInfos = new Hashtable<String, ChannelClientInfo>();
	/** Modes waiting to be sent to the server. */
	private final List<String> lModeQueue = new LinkedList<String>();

	/**
	 * Create a new client object from a hostmask.
	 *
 	 * @param tParser Refernce to parser that owns this channelclient (used for modes)	 
	 * @param sHostmask Hostmask parsed by parseHost to get nickname
	 * @see ClientInfo#parseHost
	 */
	public ClientInfo(final IRCParser tParser, final String sHostmask) { 
    //#ClientInfo.java:72: method: void com.dmdirc.parser.irc.ClientInfo.com.dmdirc.parser.irc.ClientInfo(IRCParser, String)
    //#input(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): sHostmask
    //#input(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): sHostmask._tainted
    //#input(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): tParser
    //#input(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this
    //#output(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): new HashMap(ClientInfo#3) num objects
    //#output(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): new Hashtable(ClientInfo#1) num objects
    //#output(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): new LinkedList(ClientInfo#2) num objects
    //#output(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.lModeQueue
    //#output(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.myAwayReason
    //#output(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.myChannelClientInfos
    //#output(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.myMap
    //#output(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.myParser
    //#output(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.sHost
    //#output(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.sIdent
    //#output(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.sNickname
    //#output(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.sRealName
    //#new obj(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): new HashMap(ClientInfo#3)
    //#new obj(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): new Hashtable(ClientInfo#1)
    //#new obj(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): new LinkedList(ClientInfo#2)
    //#pre[1] (void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): sHostmask != null
    //#post(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.lModeQueue == &new LinkedList(ClientInfo#2)
    //#post(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.myAwayReason == &""
    //#post(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.sRealName == &""
    //#post(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.myChannelClientInfos == &new Hashtable(ClientInfo#1)
    //#post(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.myMap == &new HashMap(ClientInfo#3)
    //#post(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.myParser == tParser
    //#post(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): init'ed(this.myParser)
    //#post(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.sHost == One-of{this.myAwayReason, undefined}
    //#post(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.sHost in Addr_Set{null,&""}
    //#post(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.sIdent == One-of{this.myAwayReason, undefined}
    //#post(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.sIdent in Addr_Set{null,&""}
    //#post(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.sNickname == undefined
    //#post(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): this.sNickname == null
    //#post(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): new HashMap(ClientInfo#3) num objects == 1
    //#post(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): new Hashtable(ClientInfo#1) num objects == 1
    //#post(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): new LinkedList(ClientInfo#2) num objects == 1
    //#unanalyzed(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): Effects-of-calling:java.lang.String:isEmpty
    //#unanalyzed(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): Effects-of-calling:java.lang.String:charAt
    //#unanalyzed(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(void com.dmdirc.parser.irc.ClientInfo(IRCParser, String)): Effects-of-calling:java.lang.String:split
		myMap = new HashMap<Object, Object>();
		setUserBits(sHostmask, true);
		myParser = tParser;
	}
    //#ClientInfo.java:76: end of method: void com.dmdirc.parser.irc.ClientInfo.com.dmdirc.parser.irc.ClientInfo(IRCParser, String)

	/**
	 * Set the Map object attatched to this object.
	 *
	 * @param newMap New Map to attatch.
	 */
	public void setMap(final Map newMap) {
		myMap = newMap;
    //#ClientInfo.java:84: method: void com.dmdirc.parser.irc.ClientInfo.setMap(Map)
    //#input(void setMap(Map)): newMap
    //#input(void setMap(Map)): this
    //#output(void setMap(Map)): this.myMap
    //#post(void setMap(Map)): this.myMap == newMap
    //#post(void setMap(Map)): init'ed(this.myMap)
	}
    //#ClientInfo.java:85: end of method: void com.dmdirc.parser.irc.ClientInfo.setMap(Map)
	
	/**
	 * Get the Map object attatched to this object.
	 *
	 * @return Map to attatched to this.
	 */
	public Map getMap() {
		return myMap;
    //#ClientInfo.java:93: method: Map com.dmdirc.parser.irc.ClientInfo.getMap()
    //#input(Map getMap()): this
    //#input(Map getMap()): this.myMap
    //#output(Map getMap()): return_value
    //#pre[2] (Map getMap()): init'ed(this.myMap)
    //#post(Map getMap()): return_value == this.myMap
    //#post(Map getMap()): init'ed(return_value)
    //#ClientInfo.java:93: end of method: Map com.dmdirc.parser.irc.ClientInfo.getMap()
	}

	/**
	 * Check if this is a fake client.
	 *
	 * @return True if this is a fake client, else false
	 */
	public boolean isFake() { return bIsFake; }
    //#ClientInfo.java:101: method: bool com.dmdirc.parser.irc.ClientInfo.isFake()
    //#input(bool isFake()): this
    //#input(bool isFake()): this.bIsFake
    //#output(bool isFake()): return_value
    //#pre[2] (bool isFake()): init'ed(this.bIsFake)
    //#post(bool isFake()): return_value == this.bIsFake
    //#post(bool isFake()): init'ed(return_value)
    //#ClientInfo.java:101: end of method: bool com.dmdirc.parser.irc.ClientInfo.isFake()
	/**
	 * Check if this client is actually a server.
	 *
	 * @return True if this client is actually a server.
	 */
	public boolean isServer() { return !(sNickname.indexOf(':') == -1); }
    //#ClientInfo.java:107: method: bool com.dmdirc.parser.irc.ClientInfo.isServer()
    //#input(bool isServer()): this
    //#input(bool isServer()): this.sNickname
    //#output(bool isServer()): return_value
    //#pre[2] (bool isServer()): this.sNickname != null
    //#post(bool isServer()): init'ed(return_value)
    //#ClientInfo.java:107: end of method: bool com.dmdirc.parser.irc.ClientInfo.isServer()
	/**
	 * Set if this is a fake client.
	 * This returns "this" and thus can be used in the construction line.
	 *
	 * @param newValue new value for isFake - True if this is a fake client, else false
	 * @return this Object
	 */
	public ClientInfo setFake(final boolean newValue) { bIsFake = newValue; return this; }
    //#ClientInfo.java:115: method: ClientInfo com.dmdirc.parser.irc.ClientInfo.setFake(bool)
    //#input(ClientInfo setFake(bool)): newValue
    //#input(ClientInfo setFake(bool)): this
    //#output(ClientInfo setFake(bool)): return_value
    //#output(ClientInfo setFake(bool)): this.bIsFake
    //#post(ClientInfo setFake(bool)): return_value == this
    //#post(ClientInfo setFake(bool)): return_value != null
    //#post(ClientInfo setFake(bool)): this.bIsFake == newValue
    //#post(ClientInfo setFake(bool)): init'ed(this.bIsFake)
    //#ClientInfo.java:115: end of method: ClientInfo com.dmdirc.parser.irc.ClientInfo.setFake(bool)

	/**
	 * Get a nickname of a user from a hostmask.
	 * Hostmask must match (?:)nick(?!ident)(?@host)
	 *
	 * @param sWho Hostname to parse
	 * @return nickname of user
	 */
	public static String parseHost(final String sWho) {
		// Get the nickname from the string.
		return parseHostFull(sWho)[0];
    //#ClientInfo.java:126: method: String com.dmdirc.parser.irc.ClientInfo.parseHost(String)
    //#ClientInfo.java:126: ?use of default init
    //#    init'ed(parseHostFull(...)[0])
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String parseHost(String)
    //#    basic block: Entry_BB_1
    //#    assertion: init'ed(parseHostFull(...)[0])
    //#    VN: undefined
    //#    Expected: Univ-VN-Set
    //#    Bad: {Invalid}
    //#    Attribs:  Ptr  Bad only invalid
    //#input(String parseHost(String)): sWho
    //#input(String parseHost(String)): sWho._tainted
    //#output(String parseHost(String)): return_value
    //#pre[1] (String parseHost(String)): sWho != null
    //#post(String parseHost(String)): return_value == undefined
    //#post(String parseHost(String)): return_value == null
    //#unanalyzed(String parseHost(String)): Effects-of-calling:java.lang.String:isEmpty
    //#unanalyzed(String parseHost(String)): Effects-of-calling:java.lang.String:charAt
    //#unanalyzed(String parseHost(String)): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(String parseHost(String)): Effects-of-calling:java.lang.String:split
    //#ClientInfo.java:126: end of method: String com.dmdirc.parser.irc.ClientInfo.parseHost(String)
	}
	
	/**
	 * Get a nick ident and host of a user from a hostmask.
	 * Hostmask must match (?:)nick(?!ident)(?@host)
	 *
	 * @param sWho Hostname to parse
	 * @return Array containing details. (result[0] -> Nick | result[1] -> Ident | result[2] -> Host)
	 */
	public static String[] parseHostFull(String sWho) {
		String[] sTemp = null;
    //#ClientInfo.java:137: method: String[] com.dmdirc.parser.irc.ClientInfo.parseHostFull(String)
    //#ClientInfo.java:137: Warning: unused assignment
    //#    Unused assignment into sTemp
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    Attribs:  Uncertain
    //#input(String[] parseHostFull(String)): sWho
    //#input(String[] parseHostFull(String)): sWho._tainted
    //#output(String[] parseHostFull(String)): new String[](parseHostFull#1) num objects
    //#output(String[] parseHostFull(String)): return_value.length
    //#output(String[] parseHostFull(String)): return_value[0]
    //#output(String[] parseHostFull(String)): return_value[1]
    //#output(String[] parseHostFull(String)): return_value[2]
    //#output(String[] parseHostFull(String)): return_value
    //#new obj(String[] parseHostFull(String)): new String[](parseHostFull#1)
    //#pre[1] (String[] parseHostFull(String)): sWho != null
    //#post(String[] parseHostFull(String)): return_value == &new String[](parseHostFull#1)
    //#post(String[] parseHostFull(String)): new String[](parseHostFull#1) num objects == 1
    //#post(String[] parseHostFull(String)): return_value.length == 3
    //#post(String[] parseHostFull(String)): return_value[0] == undefined
    //#post(String[] parseHostFull(String)): return_value[0] == null
    //#post(String[] parseHostFull(String)): return_value[1] == null
    //#post(String[] parseHostFull(String)): return_value[2] == null
    //#test_vector(String[] parseHostFull(String)): java.lang.String:charAt(...)@139: {0..57, 59..65_535}, {58}
    //#test_vector(String[] parseHostFull(String)): java.lang.String:isEmpty(...)@139: {1}, {0}
		final String[] result = new String[3];
    //#ClientInfo.java:138: ?check always fails: method fails for all possible inputs: String[] parseHostFull(String).
		if (!sWho.isEmpty() && sWho.charAt(0) == ':') { sWho = sWho.substring(1); }
		sTemp = sWho.split("@", 2);
		if (sTemp.length == 1) { result[2] = ""; } else { result[2] = sTemp[1]; }
    //#ClientInfo.java:141: ?use of default init
    //#    init'ed(sTemp.length)
    //#    severity: LOW
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    basic block: bb_4
    //#    assertion: init'ed(sTemp.length)
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
    //#ClientInfo.java:141: Warning: test always goes same way
    //#    Test predetermined because sTemp.length == 0
    //#    severity: LOW
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    from bb: bb_4
    //#    live edge: bb_4-->bb_6
    //#    tested vn: undefined - 1
    //#    tested vn values: {-1}
    //#ClientInfo.java:141: ?use of default init
    //#    init'ed(sTemp.length)
    //#    severity: LOW
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    basic block: bb_6
    //#    assertion: init'ed(sTemp.length)
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
    //#ClientInfo.java:141: ?!array index out of bounds
    //#    sTemp.length >= 2
    //#    severity: HIGH
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    basic block: bb_6
    //#    assertion: sTemp.length >= 2
    //#    VN: undefined - 1
    //#    Expected: {1..+Inf}
    //#    Bad: {-1}
    //#    Attribs:  Int  Bad singleton  Bad overlaps +/-1000  Bad < Exp
    //#ClientInfo.java:141: ?use of default init
    //#    init'ed(sTemp[1])
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    basic block: bb_6
    //#    assertion: init'ed(sTemp[1])
    //#    VN: undefined
    //#    Expected: Univ-VN-Set
    //#    Bad: {Invalid}
    //#    Attribs:  Ptr  Bad only invalid
    //#ClientInfo.java:141: Warning: dead code
    //#    Dead code here because sTemp.length == 0
    //#    severity: LOW
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    dead bb: bb_5
		sTemp = sTemp[0].split("!", 2);
    //#ClientInfo.java:142: ?use of default init
    //#    init'ed(sTemp.length)
    //#    severity: LOW
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    basic block: bb_7
    //#    assertion: init'ed(sTemp.length)
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
    //#ClientInfo.java:142: ?use of default init
    //#    init'ed(sTemp[0])
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    basic block: bb_7
    //#    assertion: init'ed(sTemp[0])
    //#    VN: undefined
    //#    Expected: Univ-VN-Set
    //#    Bad: {Invalid}
    //#    Attribs:  Ptr  Bad only invalid
    //#ClientInfo.java:142: ?null dereference
    //#    not_init'ed(sTemp[0])
    //#    severity: MEDIUM
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    basic block: bb_7
    //#    assertion: not_init'ed(sTemp[0])
    //#    VN: undefined
    //#    Expected: Inverse{null} or Invalid
    //#    Bad: Addr_Set{null}
    //#    Attribs:  Ptr  null in Bad
		if (sTemp.length == 1) { result[1] = ""; } else { result[1] = sTemp[1]; }
    //#ClientInfo.java:143: ?use of default init
    //#    init'ed(sTemp.length)
    //#    severity: LOW
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    basic block: bb_7
    //#    assertion: init'ed(sTemp.length)
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
    //#ClientInfo.java:143: Warning: test always goes same way
    //#    Test predetermined because sTemp.length == 0
    //#    severity: LOW
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    from bb: bb_7
    //#    live edge: bb_7-->bb_9
    //#    tested vn: undefined - 1
    //#    tested vn values: {-1}
    //#ClientInfo.java:143: ?use of default init
    //#    init'ed(sTemp.length)
    //#    severity: LOW
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    basic block: bb_9
    //#    assertion: init'ed(sTemp.length)
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
    //#ClientInfo.java:143: ?!array index out of bounds
    //#    sTemp.length >= 2
    //#    severity: HIGH
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    basic block: bb_9
    //#    assertion: sTemp.length >= 2
    //#    VN: undefined - 1
    //#    Expected: {1..+Inf}
    //#    Bad: {-1}
    //#    Attribs:  Int  Bad singleton  Bad overlaps +/-1000  Bad < Exp
    //#ClientInfo.java:143: ?use of default init
    //#    init'ed(sTemp[1])
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    basic block: bb_9
    //#    assertion: init'ed(sTemp[1])
    //#    VN: undefined
    //#    Expected: Univ-VN-Set
    //#    Bad: {Invalid}
    //#    Attribs:  Ptr  Bad only invalid
    //#ClientInfo.java:143: Warning: dead code
    //#    Dead code here because sTemp.length == 0
    //#    severity: LOW
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    dead bb: bb_8
		result[0] = sTemp[0];
    //#ClientInfo.java:144: ?use of default init
    //#    init'ed(sTemp.length)
    //#    severity: LOW
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    basic block: bb_10
    //#    assertion: init'ed(sTemp.length)
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
    //#ClientInfo.java:144: ?use of default init
    //#    init'ed(sTemp[0])
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String[] parseHostFull(String)
    //#    basic block: bb_10
    //#    assertion: init'ed(sTemp[0])
    //#    VN: undefined
    //#    Expected: Univ-VN-Set
    //#    Bad: {Invalid}
    //#    Attribs:  Ptr  Bad only invalid
		
		return result;
    //#ClientInfo.java:146: end of method: String[] com.dmdirc.parser.irc.ClientInfo.parseHostFull(String)
	}

	/**
	 * Set the nick/ident/host of this client.
	 *
	 * @param sHostmask takes a host (?:)nick(?!ident)(?@host) and sets nick/host/ident variables
	 * @param bUpdateNick if this is false, only host/ident will be updated.
	 */	
	public void setUserBits(final String sHostmask, final boolean bUpdateNick) {
		setUserBits(sHostmask, bUpdateNick, false);
    //#ClientInfo.java:156: method: void com.dmdirc.parser.irc.ClientInfo.setUserBits(String, bool)
    //#input(void setUserBits(String, bool)): bUpdateNick
    //#input(void setUserBits(String, bool)): sHostmask
    //#input(void setUserBits(String, bool)): sHostmask._tainted
    //#input(void setUserBits(String, bool)): this
    //#output(void setUserBits(String, bool)): this.sHost
    //#output(void setUserBits(String, bool)): this.sIdent
    //#output(void setUserBits(String, bool)): this.sNickname
    //#pre[5] (void setUserBits(String, bool)): sHostmask != null
    //#post(void setUserBits(String, bool)): this.sHost == One-of{old this.sHost, &"", undefined}
    //#post(void setUserBits(String, bool)): this.sIdent == One-of{old this.sIdent, &"", undefined}
    //#post(void setUserBits(String, bool)): this.sNickname == One-of{old this.sNickname, undefined}
    //#unanalyzed(void setUserBits(String, bool)): Effects-of-calling:java.lang.String:isEmpty
    //#unanalyzed(void setUserBits(String, bool)): Effects-of-calling:java.lang.String:charAt
    //#unanalyzed(void setUserBits(String, bool)): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(void setUserBits(String, bool)): Effects-of-calling:java.lang.String:split
	}
    //#ClientInfo.java:157: end of method: void com.dmdirc.parser.irc.ClientInfo.setUserBits(String, bool)
	
	/**
	 * Set the nick/ident/host of this client.
	 *
	 * @param sHostmask takes a host (?:)nick(?!ident)(?@host) and sets nick/host/ident variables
	 * @param bUpdateNick if this is false, only host/ident will be updated.
	 * @param allowBlank if this is true, ident/host will be set even if
	 *                   parseHostFull returns empty values for them
	 */	
	public void setUserBits(final String sHostmask, final boolean bUpdateNick, final boolean allowBlank) {
		final String[] sTemp = parseHostFull(sHostmask);
    //#ClientInfo.java:168: method: void com.dmdirc.parser.irc.ClientInfo.setUserBits(String, bool, bool)
    //#ClientInfo.java:168: ?check always fails: method fails for all possible inputs: void setUserBits(String, bool, bool).
    //#input(void setUserBits(String, bool, bool)): allowBlank
    //#input(void setUserBits(String, bool, bool)): bUpdateNick
    //#input(void setUserBits(String, bool, bool)): sHostmask
    //#input(void setUserBits(String, bool, bool)): sHostmask._tainted
    //#input(void setUserBits(String, bool, bool)): this
    //#output(void setUserBits(String, bool, bool)): this.sHost
    //#output(void setUserBits(String, bool, bool)): this.sIdent
    //#output(void setUserBits(String, bool, bool)): this.sNickname
    //#pre[6] (void setUserBits(String, bool, bool)): sHostmask != null
    //#post(void setUserBits(String, bool, bool)): this.sHost == One-of{old this.sHost, &"", undefined}
    //#post(void setUserBits(String, bool, bool)): this.sIdent == One-of{old this.sIdent, &"", undefined}
    //#post(void setUserBits(String, bool, bool)): this.sNickname == One-of{old this.sNickname, undefined}
    //#unanalyzed(void setUserBits(String, bool, bool)): Effects-of-calling:java.lang.String:isEmpty
    //#unanalyzed(void setUserBits(String, bool, bool)): Effects-of-calling:java.lang.String:charAt
    //#unanalyzed(void setUserBits(String, bool, bool)): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(void setUserBits(String, bool, bool)): Effects-of-calling:java.lang.String:split
    //#test_vector(void setUserBits(String, bool, bool)): allowBlank: {0}, {1}
    //#test_vector(void setUserBits(String, bool, bool)): bUpdateNick: {0}, {1}
		if (!sTemp[2].isEmpty() || allowBlank) { sHost = sTemp[2]; }
    //#ClientInfo.java:169: ?use of default init
    //#    init'ed(sTemp[2])
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: void setUserBits(String, bool, bool)
    //#    basic block: Entry_BB_1
    //#    assertion: init'ed(sTemp[2])
    //#    VN: new String[](parseHostFull#1)[2]
    //#    Expected: Univ-VN-Set
    //#    Bad: {Invalid}
    //#    Attribs:  Ptr  Bad only invalid
    //#ClientInfo.java:169: ?!null dereference
    //#    sTemp[2] != null
    //#    severity: HIGH
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: void setUserBits(String, bool, bool)
    //#    basic block: Entry_BB_1
    //#    assertion: sTemp[2] != null
    //#    VN: new String[](parseHostFull#1)[2]
    //#    Expected: Inverse{null} or Invalid
    //#    Bad: Addr_Set{null}
    //#    Attribs:  Ptr  null in Bad
    //#ClientInfo.java:169: ?use of default init
    //#    init'ed(sTemp[2])
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: void setUserBits(String, bool, bool)
    //#    basic block: bb_3
    //#    assertion: init'ed(sTemp[2])
    //#    VN: new String[](parseHostFull#1)[2]
    //#    Expected: Univ-VN-Set
    //#    Bad: {Invalid}
    //#    Attribs:  Ptr  Bad only invalid
		if (!sTemp[1].isEmpty() || allowBlank) { sIdent = sTemp[1]; }
    //#ClientInfo.java:170: ?use of default init
    //#    init'ed(sTemp[1])
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: void setUserBits(String, bool, bool)
    //#    basic block: bb_4
    //#    assertion: init'ed(sTemp[1])
    //#    VN: new String[](parseHostFull#1)[2]
    //#    Expected: Univ-VN-Set
    //#    Bad: {Invalid}
    //#    Attribs:  Ptr  Bad only invalid
    //#ClientInfo.java:170: ?!null dereference
    //#    sTemp[1] != null
    //#    severity: HIGH
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: void setUserBits(String, bool, bool)
    //#    basic block: bb_4
    //#    assertion: sTemp[1] != null
    //#    VN: new String[](parseHostFull#1)[2]
    //#    Expected: Inverse{null} or Invalid
    //#    Bad: Addr_Set{null}
    //#    Attribs:  Ptr  null in Bad
    //#ClientInfo.java:170: ?use of default init
    //#    init'ed(sTemp[1])
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: void setUserBits(String, bool, bool)
    //#    basic block: bb_6
    //#    assertion: init'ed(sTemp[1])
    //#    VN: new String[](parseHostFull#1)[2]
    //#    Expected: Univ-VN-Set
    //#    Bad: {Invalid}
    //#    Attribs:  Ptr  Bad only invalid
		if (bUpdateNick) { sNickname = sTemp[0]; }
    //#ClientInfo.java:171: ?use of default init
    //#    init'ed(sTemp[0])
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: void setUserBits(String, bool, bool)
    //#    basic block: bb_8
    //#    assertion: init'ed(sTemp[0])
    //#    VN: undefined
    //#    Expected: Univ-VN-Set
    //#    Bad: {Invalid}
    //#    Attribs:  Ptr  Bad only invalid
	}
    //#ClientInfo.java:172: end of method: void com.dmdirc.parser.irc.ClientInfo.setUserBits(String, bool, bool)
	
	/**
	 * Get a string representation of the user.
	 *
	 * @return String representation of the user.
	 */
	@Override
	public String toString() { return sNickname + "!" + sIdent + "@" + sHost; }
    //#ClientInfo.java:180: method: String com.dmdirc.parser.irc.ClientInfo.toString()
    //#input(String toString()): "!"._tainted
    //#input(String toString()): "@"._tainted
    //#input(String toString()): this
    //#input(String toString()): this.sHost
    //#input(String toString()): this.sHost._tainted
    //#input(String toString()): this.sIdent
    //#input(String toString()): this.sIdent._tainted
    //#input(String toString()): this.sNickname
    //#input(String toString()): this.sNickname._tainted
    //#output(String toString()): java.lang.StringBuilder:toString(...)._tainted
    //#output(String toString()): return_value
    //#new obj(String toString()): java.lang.StringBuilder:toString(...)
    //#pre[2] (String toString()): init'ed(this.sHost)
    //#pre[5] (String toString()): init'ed(this.sIdent)
    //#pre[7] (String toString()): init'ed(this.sNickname)
    //#post(String toString()): java.lang.StringBuilder:toString(...)._tainted == this.sHost._tainted | this.sNickname._tainted | this.sIdent._tainted
    //#post(String toString()): init'ed(java.lang.StringBuilder:toString(...)._tainted)
    //#post(String toString()): return_value == &java.lang.StringBuilder:toString(...)
    //#ClientInfo.java:180: end of method: String com.dmdirc.parser.irc.ClientInfo.toString()
	
	/**
	 * Get the nickname for this user.
	 *
	 * @return Known nickname for user.
	 */
	public String getNickname() { return sNickname; }
    //#ClientInfo.java:187: method: String com.dmdirc.parser.irc.ClientInfo.getNickname()
    //#input(String getNickname()): this
    //#input(String getNickname()): this.sNickname
    //#output(String getNickname()): return_value
    //#pre[2] (String getNickname()): init'ed(this.sNickname)
    //#post(String getNickname()): return_value == this.sNickname
    //#post(String getNickname()): init'ed(return_value)
    //#ClientInfo.java:187: end of method: String com.dmdirc.parser.irc.ClientInfo.getNickname()
	
	/**
	 * Get the ident for this user.
	 *
	 * @return Known ident for user. (May be "")
	 */		
	public String getIdent() { return sIdent; }
    //#ClientInfo.java:194: method: String com.dmdirc.parser.irc.ClientInfo.getIdent()
    //#input(String getIdent()): this
    //#input(String getIdent()): this.sIdent
    //#output(String getIdent()): return_value
    //#pre[2] (String getIdent()): init'ed(this.sIdent)
    //#post(String getIdent()): return_value == this.sIdent
    //#post(String getIdent()): init'ed(return_value)
    //#ClientInfo.java:194: end of method: String com.dmdirc.parser.irc.ClientInfo.getIdent()
	
	/**
	 * Get the hostname for this user.
	 *
	 * @return Known host for user. (May be "")
	 */		
	public String getHost() { return sHost; }
    //#ClientInfo.java:201: method: String com.dmdirc.parser.irc.ClientInfo.getHost()
    //#input(String getHost()): this
    //#input(String getHost()): this.sHost
    //#output(String getHost()): return_value
    //#pre[2] (String getHost()): init'ed(this.sHost)
    //#post(String getHost()): return_value == this.sHost
    //#post(String getHost()): init'ed(return_value)
    //#ClientInfo.java:201: end of method: String com.dmdirc.parser.irc.ClientInfo.getHost()
	
	/**
	 * Set the away state of a user.
	 * Automatically sets away reason to "" if set to false
	 *
	 * @param bNewState Boolean representing state. true = away, false = here
	 */	
	protected void setAwayState(final boolean bNewState) {
		bIsAway = bNewState;
    //#ClientInfo.java:210: method: void com.dmdirc.parser.irc.ClientInfo.setAwayState(bool)
    //#input(void setAwayState(bool)): bNewState
    //#input(void setAwayState(bool)): this
    //#output(void setAwayState(bool)): this.bIsAway
    //#output(void setAwayState(bool)): this.myAwayReason
    //#post(void setAwayState(bool)): this.bIsAway == bNewState
    //#post(void setAwayState(bool)): init'ed(this.bIsAway)
    //#post(void setAwayState(bool)): this.myAwayReason == One-of{old this.myAwayReason, &""}
    //#test_vector(void setAwayState(bool)): bNewState: {1}, {0}
		if (!bIsAway) { myAwayReason = ""; }
	}
    //#ClientInfo.java:212: end of method: void com.dmdirc.parser.irc.ClientInfo.setAwayState(bool)
	
	/**
	 * Get the away state of a user.
	 *
	 * @return Boolean representing state. true = away, false = here
	 */	
	public boolean getAwayState() { return bIsAway; }
    //#ClientInfo.java:219: method: bool com.dmdirc.parser.irc.ClientInfo.getAwayState()
    //#input(bool getAwayState()): this
    //#input(bool getAwayState()): this.bIsAway
    //#output(bool getAwayState()): return_value
    //#pre[2] (bool getAwayState()): init'ed(this.bIsAway)
    //#post(bool getAwayState()): return_value == this.bIsAway
    //#post(bool getAwayState()): init'ed(return_value)
    //#ClientInfo.java:219: end of method: bool com.dmdirc.parser.irc.ClientInfo.getAwayState()
	
	/**
	 * Get the Away Reason for this user.
	 *
	 * @return Known away reason for user.
	 */
	public String getAwayReason() { return myAwayReason; }
    //#ClientInfo.java:226: method: String com.dmdirc.parser.irc.ClientInfo.getAwayReason()
    //#input(String getAwayReason()): this
    //#input(String getAwayReason()): this.myAwayReason
    //#output(String getAwayReason()): return_value
    //#pre[2] (String getAwayReason()): init'ed(this.myAwayReason)
    //#post(String getAwayReason()): return_value == this.myAwayReason
    //#post(String getAwayReason()): init'ed(return_value)
    //#ClientInfo.java:226: end of method: String com.dmdirc.parser.irc.ClientInfo.getAwayReason()
	
	/**
	 * Set the Away Reason for this user.
	 * Automatically set to "" if awaystate is set to false
	 *
	 * @param newValue new away reason for user.
	 */
	protected void setAwayReason(final String newValue) { myAwayReason = newValue; }
    //#ClientInfo.java:234: method: void com.dmdirc.parser.irc.ClientInfo.setAwayReason(String)
    //#input(void setAwayReason(String)): newValue
    //#input(void setAwayReason(String)): this
    //#output(void setAwayReason(String)): this.myAwayReason
    //#post(void setAwayReason(String)): this.myAwayReason == newValue
    //#post(void setAwayReason(String)): init'ed(this.myAwayReason)
    //#ClientInfo.java:234: end of method: void com.dmdirc.parser.irc.ClientInfo.setAwayReason(String)
	
	/**
	 * Get the RealName for this user.
	 *
	 * @return Known RealName for user.
	 */
	public String getRealName() { return sRealName; }
    //#ClientInfo.java:241: method: String com.dmdirc.parser.irc.ClientInfo.getRealName()
    //#input(String getRealName()): this
    //#input(String getRealName()): this.sRealName
    //#output(String getRealName()): return_value
    //#pre[2] (String getRealName()): init'ed(this.sRealName)
    //#post(String getRealName()): return_value == this.sRealName
    //#post(String getRealName()): init'ed(return_value)
    //#ClientInfo.java:241: end of method: String com.dmdirc.parser.irc.ClientInfo.getRealName()
	
	/**
	 * Set the RealName for this user.
	 *
	 * @param newValue new RealName for user.
	 */
	protected void setRealName(final String newValue) { sRealName = newValue; }
    //#ClientInfo.java:248: method: void com.dmdirc.parser.irc.ClientInfo.setRealName(String)
    //#input(void setRealName(String)): newValue
    //#input(void setRealName(String)): this
    //#output(void setRealName(String)): this.sRealName
    //#post(void setRealName(String)): this.sRealName == newValue
    //#post(void setRealName(String)): init'ed(this.sRealName)
    //#ClientInfo.java:248: end of method: void com.dmdirc.parser.irc.ClientInfo.setRealName(String)
	
	/**
	 * Set the user modes (as an integer).
	 *
	 * @param nNewMode new long representing channel modes. (Boolean only)
	 */	
	protected void setUserMode(final long nNewMode) { nModes = nNewMode; }
    //#ClientInfo.java:255: method: void com.dmdirc.parser.irc.ClientInfo.setUserMode(long)
    //#input(void setUserMode(long)): nNewMode
    //#input(void setUserMode(long)): this
    //#output(void setUserMode(long)): this.nModes
    //#post(void setUserMode(long)): this.nModes == nNewMode
    //#post(void setUserMode(long)): init'ed(this.nModes)
    //#ClientInfo.java:255: end of method: void com.dmdirc.parser.irc.ClientInfo.setUserMode(long)
	
	/**
	 * Get the user modes (as an integer).
	 *
	 * @return long representing channel modes. (Boolean only)
	 */	
	public long getUserMode() { return nModes; }	
    //#ClientInfo.java:262: method: long com.dmdirc.parser.irc.ClientInfo.getUserMode()
    //#input(long getUserMode()): this
    //#input(long getUserMode()): this.nModes
    //#output(long getUserMode()): return_value
    //#pre[2] (long getUserMode()): init'ed(this.nModes)
    //#post(long getUserMode()): return_value == this.nModes
    //#post(long getUserMode()): init'ed(return_value)
    //#ClientInfo.java:262: end of method: long com.dmdirc.parser.irc.ClientInfo.getUserMode()
	
	/**
	 * Get the user modes (as a string representation).
	 *
	 * @return string representing modes. (boolean and non-list)
	 */	
	public String getUserModeStr() { 
		final StringBuilder sModes = new StringBuilder("+");
    //#ClientInfo.java:270: method: String com.dmdirc.parser.irc.ClientInfo.getUserModeStr()
    //#input(String getUserModeStr()): "+"._tainted
    //#input(String getUserModeStr()): this
    //#input(String getUserModeStr()): this.myParser
    //#input(String getUserModeStr()): this.myParser.hUserModes
    //#input(String getUserModeStr()): this.nModes
    //#output(String getUserModeStr()): java.lang.StringBuilder:toString(...)._tainted
    //#output(String getUserModeStr()): return_value
    //#new obj(String getUserModeStr()): java.lang.StringBuilder:toString(...)
    //#pre[2] (String getUserModeStr()): this.myParser != null
    //#pre[3] (String getUserModeStr()): this.myParser.hUserModes != null
    //#pre[4] (String getUserModeStr()): init'ed(this.nModes)
    //#presumption(String getUserModeStr()): java.util.Iterator:next(...)@274 != null
    //#presumption(String getUserModeStr()): java.util.Map:get(...)@275 != null
    //#presumption(String getUserModeStr()): java.util.Map:keySet(...)@274 != null
    //#post(String getUserModeStr()): java.lang.StringBuilder:toString(...)._tainted == 0
    //#post(String getUserModeStr()): return_value == &java.lang.StringBuilder:toString(...)
    //#test_vector(String getUserModeStr()): java.util.Iterator:hasNext(...)@274: {0}, {1}
		long nTemp = 0;
    //#ClientInfo.java:271: Warning: unused assignment
    //#    Unused assignment into nTemp
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: String getUserModeStr()
    //#    Attribs:  Uncertain
		final long nChanModes = this.getUserMode();
		
		for (char cTemp : myParser.hUserModes.keySet()) {
			nTemp = myParser.hUserModes.get(cTemp);
			if ((nChanModes & nTemp) == nTemp) { sModes.append(cTemp); }
		}
		
		return sModes.toString();
    //#ClientInfo.java:279: end of method: String com.dmdirc.parser.irc.ClientInfo.getUserModeStr()
	}
	
	/**
	 * Is this client an oper?
	 * This is a guess currently based on user-modes and thus only works on the
	 * parsers own client.
	 *
	 * @return True/False if this client appears to be an oper
	 */
	public boolean isOper() {
		final String modestr = getUserModeStr();
    //#ClientInfo.java:290: method: bool com.dmdirc.parser.irc.ClientInfo.isOper()
    //#ClientInfo.java:290: Warning: unused assignment in callee
    //#    Unused assignment to (java.lang.StringBuilder:toString(...)._tainted) in getUserModeStr
    //#    severity: LOW
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: bool isOper()
    //#input(bool isOper()): "+"._tainted
    //#input(bool isOper()): this
    //#input(bool isOper()): this.myParser
    //#input(bool isOper()): this.myParser.hUserModes
    //#input(bool isOper()): this.nModes
    //#output(bool isOper()): return_value
    //#pre[2] (bool isOper()): this.myParser != null
    //#pre[3] (bool isOper()): this.myParser.hUserModes != null
    //#pre[4] (bool isOper()): init'ed(this.nModes)
    //#post(bool isOper()): init'ed(return_value)
    //#unanalyzed(bool isOper()): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(bool isOper()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(bool isOper()): Effects-of-calling:java.util.Map:keySet
    //#unanalyzed(bool isOper()): Effects-of-calling:java.util.Set:iterator
    //#unanalyzed(bool isOper()): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(bool isOper()): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(bool isOper()): Effects-of-calling:java.lang.Character:charValue
    //#unanalyzed(bool isOper()): Effects-of-calling:java.lang.Character:valueOf
    //#unanalyzed(bool isOper()): Effects-of-calling:java.util.Map:get
    //#unanalyzed(bool isOper()): Effects-of-calling:java.lang.Long:longValue
    //#unanalyzed(bool isOper()): Effects-of-calling:java.lang.StringBuilder:append
		return (modestr.indexOf('o') > -1) || (modestr.indexOf('O') > -1);
    //#ClientInfo.java:291: end of method: bool com.dmdirc.parser.irc.ClientInfo.isOper()
	}
	
	/**
	 * Add a ChannelClientInfo as a known reference to this client.
	 *
	 * @param cci ChannelClientInfo to add as a known reference
	 */	
	public void addChannelClientInfo(final ChannelClientInfo cci) {
		final String key = myParser.getIRCStringConverter().toLowerCase(cci.getChannel().getName());
    //#ClientInfo.java:300: method: void com.dmdirc.parser.irc.ClientInfo.addChannelClientInfo(ChannelClientInfo)
    //#ClientInfo.java:300: ?precondition failure
    //#    com/dmdirc/parser/irc/IRCStringConverter.toLowerCase: (soft) init'ed(this.lowercase[0..65_535])
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: void addChannelClientInfo(ChannelClientInfo)
    //#    basic block: Entry_BB_1
    //#    assertion: (soft) init'ed(getIRCStringConverter(...).lowercase[0..65_535])
    //#    callee: String com/dmdirc/parser/irc/IRCStringConverter.toLowerCase(String)
    //#    callee assertion: (soft) init'ed(this.lowercase[0..65_535])
    //#    callee file: IRCStringConverter.java
    //#    callee precondition index: [5]
    //#    callee srcpos: 86
    //#    VN: getIRCStringConverter(...).lowercase[0..65_535]
    //#    Expected: {0..65_535}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Soft  Bad only invalid
    //#input(void addChannelClientInfo(ChannelClientInfo)): cci
    //#input(void addChannelClientInfo(ChannelClientInfo)): cci.__Tag
    //#input(void addChannelClientInfo(ChannelClientInfo)): cci.myChannel
    //#input(void addChannelClientInfo(ChannelClientInfo)): cci.myChannel.__Tag
    //#input(void addChannelClientInfo(ChannelClientInfo)): cci.myChannel.sName
    //#input(void addChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/ChannelClientInfo.__Descendant_Table[com/dmdirc/parser/irc/ChannelClientInfo]
    //#input(void addChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/ChannelClientInfo.__Descendant_Table[others]
    //#input(void addChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/ChannelClientInfo.__Dispatch_Table.getChannel()Lcom/dmdirc/parser/irc/ChannelInfo;
    //#input(void addChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/ChannelInfo.__Descendant_Table[com/dmdirc/parser/irc/ChannelInfo]
    //#input(void addChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/ChannelInfo.__Descendant_Table[others]
    //#input(void addChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/ChannelInfo.__Dispatch_Table.getName()Ljava/lang/String;
    //#input(void addChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/IRCParser.__Descendant_Table[com/dmdirc/parser/irc/IRCParser]
    //#input(void addChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/IRCParser.__Descendant_Table[others]
    //#input(void addChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.getIRCStringConverter()Lcom/dmdirc/parser/irc/IRCStringConverter;
    //#input(void addChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/IRCStringConverter.__Descendant_Table[com/dmdirc/parser/irc/IRCStringConverter]
    //#input(void addChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/IRCStringConverter.__Descendant_Table[others]
    //#input(void addChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/IRCStringConverter.__Dispatch_Table.toLowerCase(Ljava/lang/String;)Ljava/lang/String;
    //#input(void addChannelClientInfo(ChannelClientInfo)): this
    //#input(void addChannelClientInfo(ChannelClientInfo)): this.myChannelClientInfos
    //#input(void addChannelClientInfo(ChannelClientInfo)): this.myParser
    //#input(void addChannelClientInfo(ChannelClientInfo)): this.myParser.__Tag
    //#input(void addChannelClientInfo(ChannelClientInfo)): this.myParser.stringConverter
    //#input(void addChannelClientInfo(ChannelClientInfo)): this.myParser.stringConverter.__Tag
    //#input(void addChannelClientInfo(ChannelClientInfo)): this.myParser.stringConverter.lowercase
    //#input(void addChannelClientInfo(ChannelClientInfo)): this.myParser.stringConverter.lowercase.length
    //#input(void addChannelClientInfo(ChannelClientInfo)): this.myParser.stringConverter.lowercase[0..65_535]
    //#output(void addChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1) num objects
    //#output(void addChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1).__Tag
    //#output(void addChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1).limit
    //#output(void addChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1).lowercase
    //#output(void addChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1).uppercase
    //#output(void addChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#1) num objects
    //#output(void addChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#1).length
    //#output(void addChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#1)[0..65_535]
    //#output(void addChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#2) num objects
    //#output(void addChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#2).length
    //#output(void addChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#2)[0..65_567]
    //#output(void addChannelClientInfo(ChannelClientInfo)): this.myParser.stringConverter
    //#new obj(void addChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1)
    //#new obj(void addChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#1)
    //#new obj(void addChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#2)
    //#pre[1] (void addChannelClientInfo(ChannelClientInfo)): cci != null
    //#pre[2] (void addChannelClientInfo(ChannelClientInfo)): cci.__Tag == com/dmdirc/parser/irc/ChannelClientInfo
    //#pre[3] (void addChannelClientInfo(ChannelClientInfo)): cci.myChannel != null
    //#pre[4] (void addChannelClientInfo(ChannelClientInfo)): cci.myChannel.__Tag == com/dmdirc/parser/irc/ChannelInfo
    //#pre[5] (void addChannelClientInfo(ChannelClientInfo)): cci.myChannel.sName != null
    //#pre[6] (void addChannelClientInfo(ChannelClientInfo)): init'ed(this.myParser.stringConverter)
    //#pre[8] (void addChannelClientInfo(ChannelClientInfo)): this.myChannelClientInfos != null
    //#pre[9] (void addChannelClientInfo(ChannelClientInfo)): this.myParser != null
    //#pre[10] (void addChannelClientInfo(ChannelClientInfo)): this.myParser.__Tag == com/dmdirc/parser/irc/IRCParser
    //#pre[11] (void addChannelClientInfo(ChannelClientInfo)): (soft) this.myParser.stringConverter.__Tag == com/dmdirc/parser/irc/IRCStringConverter
    //#pre[12] (void addChannelClientInfo(ChannelClientInfo)): (soft) this.myParser.stringConverter.lowercase != null
    //#pre[14] (void addChannelClientInfo(ChannelClientInfo)): (soft) init'ed(this.myParser.stringConverter.lowercase[0..65_535])
    //#post(void addChannelClientInfo(ChannelClientInfo)): this.myParser.stringConverter == One-of{old this.myParser.stringConverter, &new IRCStringConverter(getIRCStringConverter#1)}
    //#post(void addChannelClientInfo(ChannelClientInfo)): this.myParser.stringConverter != null
    //#post(void addChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1) num objects <= 1
    //#post(void addChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#1) num objects == new IRCStringConverter(getIRCStringConverter#1) num objects
    //#post(void addChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#2) num objects == new IRCStringConverter(getIRCStringConverter#1) num objects
    //#post(void addChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1).__Tag == com/dmdirc/parser/irc/IRCStringConverter
    //#post(void addChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1).limit == 4
    //#post(void addChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1).lowercase == &new char[](IRCStringConverter#1)
    //#post(void addChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1).uppercase == &new char[](IRCStringConverter#2)
    //#post(void addChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#1).length == 127
    //#post(void addChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#2).length == 127
    //#post(void addChannelClientInfo(ChannelClientInfo)): possibly_updated(new char[](IRCStringConverter#1)[0..65_535])
    //#post(void addChannelClientInfo(ChannelClientInfo)): possibly_updated(new char[](IRCStringConverter#2)[0..65_567])
    //#unanalyzed(void addChannelClientInfo(ChannelClientInfo)): Effects-of-calling:java.lang.String:toCharArray
    //#unanalyzed(void addChannelClientInfo(ChannelClientInfo)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(void addChannelClientInfo(ChannelClientInfo)): Effects-of-calling:java.lang.String
    //#test_vector(void addChannelClientInfo(ChannelClientInfo)): java.util.Map:containsKey(...)@301: {1}, {0}
		if (!myChannelClientInfos.containsKey(key)) {
			myChannelClientInfos.put(key, cci);
		}
	}
    //#ClientInfo.java:304: end of method: void com.dmdirc.parser.irc.ClientInfo.addChannelClientInfo(ChannelClientInfo)
	
	/**
	 * Remove a ChannelClientInfo as a known reference to this client.
	 *
	 * @param cci ChannelClientInfo to remove as a known reference
	 */	
	public void delChannelClientInfo(final ChannelClientInfo cci) {
		final String key = myParser.getIRCStringConverter().toLowerCase(cci.getChannel().getName());
    //#ClientInfo.java:312: method: void com.dmdirc.parser.irc.ClientInfo.delChannelClientInfo(ChannelClientInfo)
    //#ClientInfo.java:312: ?precondition failure
    //#    com/dmdirc/parser/irc/IRCStringConverter.toLowerCase: (soft) init'ed(this.lowercase[0..65_535])
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: void delChannelClientInfo(ChannelClientInfo)
    //#    basic block: Entry_BB_1
    //#    assertion: (soft) init'ed(getIRCStringConverter(...).lowercase[0..65_535])
    //#    callee: String com/dmdirc/parser/irc/IRCStringConverter.toLowerCase(String)
    //#    callee assertion: (soft) init'ed(this.lowercase[0..65_535])
    //#    callee file: IRCStringConverter.java
    //#    callee precondition index: [5]
    //#    callee srcpos: 86
    //#    VN: getIRCStringConverter(...).lowercase[0..65_535]
    //#    Expected: {0..65_535}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Soft  Bad only invalid
    //#input(void delChannelClientInfo(ChannelClientInfo)): cci
    //#input(void delChannelClientInfo(ChannelClientInfo)): cci.__Tag
    //#input(void delChannelClientInfo(ChannelClientInfo)): cci.myChannel
    //#input(void delChannelClientInfo(ChannelClientInfo)): cci.myChannel.__Tag
    //#input(void delChannelClientInfo(ChannelClientInfo)): cci.myChannel.sName
    //#input(void delChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/ChannelClientInfo.__Descendant_Table[com/dmdirc/parser/irc/ChannelClientInfo]
    //#input(void delChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/ChannelClientInfo.__Descendant_Table[others]
    //#input(void delChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/ChannelClientInfo.__Dispatch_Table.getChannel()Lcom/dmdirc/parser/irc/ChannelInfo;
    //#input(void delChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/ChannelInfo.__Descendant_Table[com/dmdirc/parser/irc/ChannelInfo]
    //#input(void delChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/ChannelInfo.__Descendant_Table[others]
    //#input(void delChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/ChannelInfo.__Dispatch_Table.getName()Ljava/lang/String;
    //#input(void delChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/IRCParser.__Descendant_Table[com/dmdirc/parser/irc/IRCParser]
    //#input(void delChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/IRCParser.__Descendant_Table[others]
    //#input(void delChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.getIRCStringConverter()Lcom/dmdirc/parser/irc/IRCStringConverter;
    //#input(void delChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/IRCStringConverter.__Descendant_Table[com/dmdirc/parser/irc/IRCStringConverter]
    //#input(void delChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/IRCStringConverter.__Descendant_Table[others]
    //#input(void delChannelClientInfo(ChannelClientInfo)): com/dmdirc/parser/irc/IRCStringConverter.__Dispatch_Table.toLowerCase(Ljava/lang/String;)Ljava/lang/String;
    //#input(void delChannelClientInfo(ChannelClientInfo)): this
    //#input(void delChannelClientInfo(ChannelClientInfo)): this.myChannelClientInfos
    //#input(void delChannelClientInfo(ChannelClientInfo)): this.myParser
    //#input(void delChannelClientInfo(ChannelClientInfo)): this.myParser.__Tag
    //#input(void delChannelClientInfo(ChannelClientInfo)): this.myParser.stringConverter
    //#input(void delChannelClientInfo(ChannelClientInfo)): this.myParser.stringConverter.__Tag
    //#input(void delChannelClientInfo(ChannelClientInfo)): this.myParser.stringConverter.lowercase
    //#input(void delChannelClientInfo(ChannelClientInfo)): this.myParser.stringConverter.lowercase.length
    //#input(void delChannelClientInfo(ChannelClientInfo)): this.myParser.stringConverter.lowercase[0..65_535]
    //#output(void delChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1) num objects
    //#output(void delChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1).__Tag
    //#output(void delChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1).limit
    //#output(void delChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1).lowercase
    //#output(void delChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1).uppercase
    //#output(void delChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#1) num objects
    //#output(void delChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#1).length
    //#output(void delChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#1)[0..65_535]
    //#output(void delChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#2) num objects
    //#output(void delChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#2).length
    //#output(void delChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#2)[0..65_567]
    //#output(void delChannelClientInfo(ChannelClientInfo)): this.myParser.stringConverter
    //#new obj(void delChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1)
    //#new obj(void delChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#1)
    //#new obj(void delChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#2)
    //#pre[1] (void delChannelClientInfo(ChannelClientInfo)): cci != null
    //#pre[2] (void delChannelClientInfo(ChannelClientInfo)): cci.__Tag == com/dmdirc/parser/irc/ChannelClientInfo
    //#pre[3] (void delChannelClientInfo(ChannelClientInfo)): cci.myChannel != null
    //#pre[4] (void delChannelClientInfo(ChannelClientInfo)): cci.myChannel.__Tag == com/dmdirc/parser/irc/ChannelInfo
    //#pre[5] (void delChannelClientInfo(ChannelClientInfo)): cci.myChannel.sName != null
    //#pre[6] (void delChannelClientInfo(ChannelClientInfo)): init'ed(this.myParser.stringConverter)
    //#pre[8] (void delChannelClientInfo(ChannelClientInfo)): this.myChannelClientInfos != null
    //#pre[9] (void delChannelClientInfo(ChannelClientInfo)): this.myParser != null
    //#pre[10] (void delChannelClientInfo(ChannelClientInfo)): this.myParser.__Tag == com/dmdirc/parser/irc/IRCParser
    //#pre[11] (void delChannelClientInfo(ChannelClientInfo)): (soft) this.myParser.stringConverter.__Tag == com/dmdirc/parser/irc/IRCStringConverter
    //#pre[12] (void delChannelClientInfo(ChannelClientInfo)): (soft) this.myParser.stringConverter.lowercase != null
    //#pre[14] (void delChannelClientInfo(ChannelClientInfo)): (soft) init'ed(this.myParser.stringConverter.lowercase[0..65_535])
    //#post(void delChannelClientInfo(ChannelClientInfo)): this.myParser.stringConverter == One-of{old this.myParser.stringConverter, &new IRCStringConverter(getIRCStringConverter#1)}
    //#post(void delChannelClientInfo(ChannelClientInfo)): this.myParser.stringConverter != null
    //#post(void delChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1) num objects <= 1
    //#post(void delChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#1) num objects == new IRCStringConverter(getIRCStringConverter#1) num objects
    //#post(void delChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#2) num objects == new IRCStringConverter(getIRCStringConverter#1) num objects
    //#post(void delChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1).__Tag == com/dmdirc/parser/irc/IRCStringConverter
    //#post(void delChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1).limit == 4
    //#post(void delChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1).lowercase == &new char[](IRCStringConverter#1)
    //#post(void delChannelClientInfo(ChannelClientInfo)): new IRCStringConverter(getIRCStringConverter#1).uppercase == &new char[](IRCStringConverter#2)
    //#post(void delChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#1).length == 127
    //#post(void delChannelClientInfo(ChannelClientInfo)): new char[](IRCStringConverter#2).length == 127
    //#post(void delChannelClientInfo(ChannelClientInfo)): possibly_updated(new char[](IRCStringConverter#1)[0..65_535])
    //#post(void delChannelClientInfo(ChannelClientInfo)): possibly_updated(new char[](IRCStringConverter#2)[0..65_567])
    //#unanalyzed(void delChannelClientInfo(ChannelClientInfo)): Effects-of-calling:java.lang.String:toCharArray
    //#unanalyzed(void delChannelClientInfo(ChannelClientInfo)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(void delChannelClientInfo(ChannelClientInfo)): Effects-of-calling:java.lang.String
    //#test_vector(void delChannelClientInfo(ChannelClientInfo)): java.util.Map:containsKey(...)@313: {0}, {1}
		if (myChannelClientInfos.containsKey(key)) {
			myChannelClientInfos.remove(key);
		}
	}
    //#ClientInfo.java:316: end of method: void com.dmdirc.parser.irc.ClientInfo.delChannelClientInfo(ChannelClientInfo)
	
	/**
	 * Check to see if a client is still known on any of the channels we are on.
	 *
	 * @return Boolean to see if client is still visable.
	 */
	public boolean checkVisibility() {
		return !myChannelClientInfos.isEmpty();
    //#ClientInfo.java:324: method: bool com.dmdirc.parser.irc.ClientInfo.checkVisibility()
    //#input(bool checkVisibility()): this
    //#input(bool checkVisibility()): this.myChannelClientInfos
    //#output(bool checkVisibility()): return_value
    //#pre[2] (bool checkVisibility()): this.myChannelClientInfos != null
    //#post(bool checkVisibility()): init'ed(return_value)
    //#ClientInfo.java:324: end of method: bool com.dmdirc.parser.irc.ClientInfo.checkVisibility()
	}
	
	/**
	 * Check how many channels this client is known on.
	 *
	 * @return int with the count of known channels
	 */	
	public int channelCount() {
		return myChannelClientInfos.size();
    //#ClientInfo.java:333: method: int com.dmdirc.parser.irc.ClientInfo.channelCount()
    //#input(int channelCount()): this
    //#input(int channelCount()): this.myChannelClientInfos
    //#output(int channelCount()): return_value
    //#pre[2] (int channelCount()): this.myChannelClientInfos != null
    //#post(int channelCount()): init'ed(return_value)
    //#ClientInfo.java:333: end of method: int com.dmdirc.parser.irc.ClientInfo.channelCount()
	}
	
	/**
	 * Get a list of channelClients that point to this object.
	 *
	 * @return int with the count of known channels
	 */	
	public List<ChannelClientInfo> getChannelClients() {
		final List<ChannelClientInfo> result = new ArrayList<ChannelClientInfo>();
    //#ClientInfo.java:342: method: List com.dmdirc.parser.irc.ClientInfo.getChannelClients()
    //#input(List getChannelClients()): com/dmdirc/parser/irc/ChannelClientInfo.__Descendant_Table[com/dmdirc/parser/irc/ChannelClientInfo]
    //#input(List getChannelClients()): com/dmdirc/parser/irc/ChannelClientInfo.__Descendant_Table[others]
    //#input(List getChannelClients()): this
    //#input(List getChannelClients()): this.myChannelClientInfos
    //#output(List getChannelClients()): new ArrayList(getChannelClients#1) num objects
    //#output(List getChannelClients()): return_value
    //#new obj(List getChannelClients()): new ArrayList(getChannelClients#1)
    //#pre[2] (List getChannelClients()): this.myChannelClientInfos != null
    //#presumption(List getChannelClients()): java.util.Iterator:next(...).__Tag@343 == com/dmdirc/parser/irc/ChannelClientInfo
    //#presumption(List getChannelClients()): java.util.Map:values(...)@343 != null
    //#post(List getChannelClients()): return_value == &new ArrayList(getChannelClients#1)
    //#post(List getChannelClients()): new ArrayList(getChannelClients#1) num objects == 1
    //#test_vector(List getChannelClients()): java.util.Iterator:hasNext(...)@343: {0}, {1}
		for (ChannelClientInfo cci : myChannelClientInfos.values()) {
			result.add(cci);
		}
		return result;
    //#ClientInfo.java:346: end of method: List com.dmdirc.parser.irc.ClientInfo.getChannelClients()
	}
	
	/**
	 * Adjust the channel modes on a channel.
	 * This function will queue modes up to be sent in one go, according to 005 params.
	 * If less modes are altered than the queue accepts, sendModes() must be called.<br><br>
	 * sendModes is automatically called if you attempt to add more modes than is allowed
	 * to be queued
	 *
	 * @param positive Is this a positive mode change, or a negative mode change
	 * @param mode Character representing the mode to change
	 */
	public void alterMode(final boolean positive, final Character mode) {
		if (isFake()) { return; }
    //#ClientInfo.java:360: method: void com.dmdirc.parser.irc.ClientInfo.alterMode(bool, Character)
    //#input(void alterMode(bool, Character)): " "._tainted
    //#input(void alterMode(bool, Character)): " for mode "._tainted
    //#input(void alterMode(bool, Character)): "+"._tainted
    //#input(void alterMode(bool, Character)): "-"._tainted
    //#input(void alterMode(bool, Character)): "Callback not found: "._tainted
    //#input(void alterMode(bool, Character)): "Intercepted mode request for "._tainted
    //#input(void alterMode(bool, Character)): "MODE "._tainted
    //#input(void alterMode(bool, Character)): "OnDataOut"._tainted
    //#input(void alterMode(bool, Character)): "OnDebugInfo"._tainted
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/ChannelInfo.__Descendant_Table[com/dmdirc/parser/irc/ChannelInfo]
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/ChannelInfo.__Descendant_Table[others]
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/ChannelInfo.__Dispatch_Table.getListModeQueue()Ljava/util/Queue;
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/IRCParser.__Descendant_Table[com/dmdirc/parser/irc/IRCParser]
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/IRCParser.__Descendant_Table[others]
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.callDataOut(Ljava/lang/String;Z)Z
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.callDebugInfo(ILjava/lang/String;)Z
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.callDebugInfo(ILjava/lang/String;[Ljava/lang/Object;)Z
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.doSendString(Ljava/lang/String;Z)V
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.getChannelInfo(Ljava/lang/String;)Lcom/dmdirc/parser/irc/ChannelInfo;
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.getIRCStringConverter()Lcom/dmdirc/parser/irc/IRCStringConverter;
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.getSocketState()Lcom/dmdirc/parser/irc/SocketState;
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.sendLine(Ljava/lang/String;)V
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/IRCStringConverter.__Descendant_Table[com/dmdirc/parser/irc/IRCStringConverter]
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/IRCStringConverter.__Descendant_Table[others]
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/IRCStringConverter.__Dispatch_Table.toLowerCase(Ljava/lang/String;)Ljava/lang/String;
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/SocketState.OPEN
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/callbacks/CallbackObject.__Descendant_Table[com/dmdirc/parser/irc/callbacks/CallbackObjectSpecific]
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/callbacks/CallbackObject.__Descendant_Table[com/dmdirc/parser/irc/callbacks/CallbackObject]
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/callbacks/CallbackObject.__Descendant_Table[others]
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/callbacks/CallbackObject.__Dispatch_Table.call([Ljava/lang/Object;)Z
    //#input(void alterMode(bool, Character)): com/dmdirc/parser/irc/callbacks/CallbackObjectSpecific.__Dispatch_Table.call([Ljava/lang/Object;)Z
    //#input(void alterMode(bool, Character)): mode
    //#input(void alterMode(bool, Character)): mode._tainted
    //#input(void alterMode(bool, Character)): positive
    //#input(void alterMode(bool, Character)): this
    //#input(void alterMode(bool, Character)): this.bIsFake
    //#input(void alterMode(bool, Character)): this.lModeQueue
    //#input(void alterMode(bool, Character)): this.myParser
    //#input(void alterMode(bool, Character)): this.myParser.__Tag
    //#input(void alterMode(bool, Character)): this.myParser.cMyself
    //#input(void alterMode(bool, Character)): this.myParser.currentSocketState
    //#input(void alterMode(bool, Character)): this.myParser.h005Info
    //#input(void alterMode(bool, Character)): this.myParser.hChanModesOther
    //#input(void alterMode(bool, Character)): this.myParser.hChannelList
    //#input(void alterMode(bool, Character)): this.myParser.hUserModes
    //#input(void alterMode(bool, Character)): this.myParser.myCallbackManager
    //#input(void alterMode(bool, Character)): this.myParser.myCallbackManager.callbackHash
    //#input(void alterMode(bool, Character)): this.myParser.out
    //#input(void alterMode(bool, Character)): this.myParser.stringConverter
    //#input(void alterMode(bool, Character)): this.myParser.stringConverter.__Tag
    //#input(void alterMode(bool, Character)): this.myParser.stringConverter.lowercase
    //#input(void alterMode(bool, Character)): this.myParser.stringConverter.lowercase.length
    //#input(void alterMode(bool, Character)): this.sNickname
    //#input(void alterMode(bool, Character)): this.sNickname._tainted
    //#output(void alterMode(bool, Character)): java.lang.String:substring(...)._tainted
    //#output(void alterMode(bool, Character)): new IRCStringConverter(getIRCStringConverter#1) num objects
    //#output(void alterMode(bool, Character)): new IRCStringConverter(getIRCStringConverter#1).__Tag
    //#output(void alterMode(bool, Character)): new IRCStringConverter(getIRCStringConverter#1).limit
    //#output(void alterMode(bool, Character)): new IRCStringConverter(getIRCStringConverter#1).lowercase
    //#output(void alterMode(bool, Character)): new IRCStringConverter(getIRCStringConverter#1).uppercase
    //#output(void alterMode(bool, Character)): new char[](IRCStringConverter#1) num objects
    //#output(void alterMode(bool, Character)): new char[](IRCStringConverter#1).length
    //#output(void alterMode(bool, Character)): new char[](IRCStringConverter#1)[0..65_535]
    //#output(void alterMode(bool, Character)): new char[](IRCStringConverter#2) num objects
    //#output(void alterMode(bool, Character)): new char[](IRCStringConverter#2).length
    //#output(void alterMode(bool, Character)): new char[](IRCStringConverter#2)[0..65_567]
    //#output(void alterMode(bool, Character)): this...myAwayReason
    //#output(void alterMode(bool, Character)): this.myParser.stringConverter
    //#new obj(void alterMode(bool, Character)): java.lang.String:substring(...)
    //#new obj(void alterMode(bool, Character)): new IRCStringConverter(getIRCStringConverter#1)
    //#new obj(void alterMode(bool, Character)): new char[](IRCStringConverter#1)
    //#new obj(void alterMode(bool, Character)): new char[](IRCStringConverter#2)
    //#pre[7] (void alterMode(bool, Character)): init'ed(this.bIsFake)
    //#pre[4] (void alterMode(bool, Character)): (soft) init'ed(this.myParser.stringConverter)
    //#pre[10] (void alterMode(bool, Character)): (soft) this.lModeQueue != null
    //#pre[11] (void alterMode(bool, Character)): (soft) this.myParser != null
    //#pre[12] (void alterMode(bool, Character)): (soft) this.myParser.__Tag == com/dmdirc/parser/irc/IRCParser
    //#pre[13] (void alterMode(bool, Character)): (soft) this.myParser.cMyself != null
    //#pre[14] (void alterMode(bool, Character)): (soft) init'ed(this.myParser.currentSocketState)
    //#pre[15] (void alterMode(bool, Character)): (soft) this.myParser.h005Info != null
    //#pre[16] (void alterMode(bool, Character)): (soft) this.myParser.hChanModesOther != null
    //#pre[17] (void alterMode(bool, Character)): (soft) this.myParser.hChannelList != null
    //#pre[19] (void alterMode(bool, Character)): (soft) this.myParser.hUserModes != null
    //#pre[20] (void alterMode(bool, Character)): (soft) this.myParser.myCallbackManager != null
    //#pre[21] (void alterMode(bool, Character)): (soft) this.myParser.myCallbackManager.callbackHash != null
    //#pre[22] (void alterMode(bool, Character)): (soft) init'ed(this.myParser.out)
    //#pre[27] (void alterMode(bool, Character)): (soft) init'ed(this.sNickname)
    //#post(void alterMode(bool, Character)): init'ed(java.lang.String:substring(...)._tainted)
    //#post(void alterMode(bool, Character)): possibly_updated(this...myAwayReason)
    //#post(void alterMode(bool, Character)): this.myParser.stringConverter == One-of{old this.myParser.stringConverter, &new IRCStringConverter(getIRCStringConverter#1)}
    //#post(void alterMode(bool, Character)): init'ed(this.myParser.stringConverter)
    //#post(void alterMode(bool, Character)): new IRCStringConverter(getIRCStringConverter#1) num objects <= 1
    //#post(void alterMode(bool, Character)): init'ed(new IRCStringConverter(getIRCStringConverter#1).__Tag)
    //#post(void alterMode(bool, Character)): init'ed(new IRCStringConverter(getIRCStringConverter#1).limit)
    //#post(void alterMode(bool, Character)): init'ed(new IRCStringConverter(getIRCStringConverter#1).lowercase)
    //#post(void alterMode(bool, Character)): init'ed(new IRCStringConverter(getIRCStringConverter#1).uppercase)
    //#post(void alterMode(bool, Character)): new char[](IRCStringConverter#1) num objects <= 1
    //#post(void alterMode(bool, Character)): init'ed(new char[](IRCStringConverter#1).length)
    //#post(void alterMode(bool, Character)): possibly_updated(new char[](IRCStringConverter#1)[0..65_535])
    //#post(void alterMode(bool, Character)): new char[](IRCStringConverter#2) num objects <= 1
    //#post(void alterMode(bool, Character)): init'ed(new char[](IRCStringConverter#2).length)
    //#post(void alterMode(bool, Character)): possibly_updated(new char[](IRCStringConverter#2)[0..65_567])
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.String:charAt
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.util.List:clear
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.util.Map:containsKey
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.String:toLowerCase
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.RuntimeException
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.util.Map:get
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:call
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:callDebugInfo
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.String:format
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.Integer:valueOf
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.util.List:size
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.String:toCharArray
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.String
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.util.List:isEmpty
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.util.List:get
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.StringBuilder:length
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.String:indexOf
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.String:split
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.String:equalsIgnoreCase
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.Character:valueOf
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.Byte:byteValue
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:doSendString
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.Boolean:valueOf
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.io.PrintWriter:printf
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:setAwayReason
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.util.LinkedList
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:getListModeQueue
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.util.LinkedList:contains
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.util.Queue:offer
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.util.LinkedList:offer
    //#unanalyzed(void alterMode(bool, Character)): Effects-of-calling:java.lang.System:currentTimeMillis
    //#test_vector(void alterMode(bool, Character)): this.bIsFake: {0}, {1}
    //#test_vector(void alterMode(bool, Character)): java.util.List:contains(...)@373: {0}, {1}
    //#test_vector(void alterMode(bool, Character)): java.util.List:contains(...)@376: {0}, {1}
    //#test_vector(void alterMode(bool, Character)): java.util.Map:containsKey(...)@363: {0}, {1}
    //#test_vector(void alterMode(bool, Character)): java.util.Map:containsKey(...)@371: {1}, {0}
		int modecount = 1;
		String modestr = "";
    //#ClientInfo.java:362: Warning: unused assignment
    //#    Unused assignment into modestr
    //#    severity: LOW
    //#    class: com.dmdirc.parser.irc.ClientInfo
    //#    method: void alterMode(bool, Character)
		if (myParser.h005Info.containsKey("MODES")) {
			try { 
				modecount = Integer.parseInt(myParser.h005Info.get("MODES")); 
			} catch (NumberFormatException e) { 
				modecount = 1;
			}
		}
		modestr = ((positive) ? "+" : "-") + mode;
		if (!myParser.hUserModes.containsKey(mode)) { return; }
		final String teststr = ((positive) ? "-" : "+") + mode;
		if (lModeQueue.contains(teststr)) {
			lModeQueue.remove(teststr);
			return;
		} else if (lModeQueue.contains(modestr)) {
			return;
		}
		myParser.callDebugInfo(myParser.DEBUG_INFO, "Queueing user mode: %s", modestr);
		lModeQueue.add(modestr);
		if (lModeQueue.size() == modecount) { sendModes(); }
	}
    //#ClientInfo.java:382: end of method: void com.dmdirc.parser.irc.ClientInfo.alterMode(bool, Character)
	
	/**
	 * This function will send modes that are currently queued up to send.
	 * This assumes that the queue only contains the amount that are alowed to be sent
	 * and thus will try to send the entire queue in one go.<br><br>
	 * Modes are always sent negative then positive and not mixed.
	 */
	public void sendModes() {
		if (lModeQueue.isEmpty()) { return; }
    //#ClientInfo.java:391: method: void com.dmdirc.parser.irc.ClientInfo.sendModes()
    //#input(void sendModes()): " "._tainted
    //#input(void sendModes()): " for mode "._tainted
    //#input(void sendModes()): "+"._tainted
    //#input(void sendModes()): "-"._tainted
    //#input(void sendModes()): "Callback not found: "._tainted
    //#input(void sendModes()): "Intercepted mode request for "._tainted
    //#input(void sendModes()): "MODE "._tainted
    //#input(void sendModes()): "OnDataOut"._tainted
    //#input(void sendModes()): "OnDebugInfo"._tainted
    //#input(void sendModes()): com/dmdirc/parser/irc/ChannelInfo.__Descendant_Table[com/dmdirc/parser/irc/ChannelInfo]
    //#input(void sendModes()): com/dmdirc/parser/irc/ChannelInfo.__Descendant_Table[others]
    //#input(void sendModes()): com/dmdirc/parser/irc/ChannelInfo.__Dispatch_Table.getListModeQueue()Ljava/util/Queue;
    //#input(void sendModes()): com/dmdirc/parser/irc/IRCParser.__Descendant_Table[com/dmdirc/parser/irc/IRCParser]
    //#input(void sendModes()): com/dmdirc/parser/irc/IRCParser.__Descendant_Table[others]
    //#input(void sendModes()): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.callDataOut(Ljava/lang/String;Z)Z
    //#input(void sendModes()): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.callDebugInfo(ILjava/lang/String;)Z
    //#input(void sendModes()): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.callDebugInfo(ILjava/lang/String;[Ljava/lang/Object;)Z
    //#input(void sendModes()): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.doSendString(Ljava/lang/String;Z)V
    //#input(void sendModes()): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.getChannelInfo(Ljava/lang/String;)Lcom/dmdirc/parser/irc/ChannelInfo;
    //#input(void sendModes()): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.getIRCStringConverter()Lcom/dmdirc/parser/irc/IRCStringConverter;
    //#input(void sendModes()): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.getSocketState()Lcom/dmdirc/parser/irc/SocketState;
    //#input(void sendModes()): com/dmdirc/parser/irc/IRCParser.__Dispatch_Table.sendLine(Ljava/lang/String;)V
    //#input(void sendModes()): com/dmdirc/parser/irc/IRCStringConverter.__Descendant_Table[com/dmdirc/parser/irc/IRCStringConverter]
    //#input(void sendModes()): com/dmdirc/parser/irc/IRCStringConverter.__Descendant_Table[others]
    //#input(void sendModes()): com/dmdirc/parser/irc/IRCStringConverter.__Dispatch_Table.toLowerCase(Ljava/lang/String;)Ljava/lang/String;
    //#input(void sendModes()): com/dmdirc/parser/irc/SocketState.OPEN
    //#input(void sendModes()): com/dmdirc/parser/irc/callbacks/CallbackObject.__Descendant_Table[com/dmdirc/parser/irc/callbacks/CallbackObjectSpecific]
    //#input(void sendModes()): com/dmdirc/parser/irc/callbacks/CallbackObject.__Descendant_Table[com/dmdirc/parser/irc/callbacks/CallbackObject]
    //#input(void sendModes()): com/dmdirc/parser/irc/callbacks/CallbackObject.__Descendant_Table[others]
    //#input(void sendModes()): com/dmdirc/parser/irc/callbacks/CallbackObject.__Dispatch_Table.call([Ljava/lang/Object;)Z
    //#input(void sendModes()): com/dmdirc/parser/irc/callbacks/CallbackObjectSpecific.__Dispatch_Table.call([Ljava/lang/Object;)Z
    //#input(void sendModes()): this
    //#input(void sendModes()): this.lModeQueue
    //#input(void sendModes()): this.myParser
    //#input(void sendModes()): this.myParser.__Tag
    //#input(void sendModes()): this.myParser.cMyself
    //#input(void sendModes()): this.myParser.currentSocketState
    //#input(void sendModes()): this.myParser.hChanModesOther
    //#input(void sendModes()): this.myParser.hChannelList
    //#input(void sendModes()): this.myParser.myCallbackManager
    //#input(void sendModes()): this.myParser.myCallbackManager.callbackHash
    //#input(void sendModes()): this.myParser.out
    //#input(void sendModes()): this.myParser.stringConverter
    //#input(void sendModes()): this.myParser.stringConverter.__Tag
    //#input(void sendModes()): this.myParser.stringConverter.lowercase
    //#input(void sendModes()): this.myParser.stringConverter.lowercase.length
    //#input(void sendModes()): this.myParser.stringConverter.lowercase[0..65_535]
    //#input(void sendModes()): this.sNickname
    //#input(void sendModes()): this.sNickname._tainted
    //#output(void sendModes()): java.lang.String:substring(...)._tainted
    //#output(void sendModes()): new IRCStringConverter(getIRCStringConverter#1) num objects
    //#output(void sendModes()): new IRCStringConverter(getIRCStringConverter#1).__Tag
    //#output(void sendModes()): new IRCStringConverter(getIRCStringConverter#1).limit
    //#output(void sendModes()): new IRCStringConverter(getIRCStringConverter#1).lowercase
    //#output(void sendModes()): new IRCStringConverter(getIRCStringConverter#1).uppercase
    //#output(void sendModes()): new char[](IRCStringConverter#1) num objects
    //#output(void sendModes()): new char[](IRCStringConverter#1).length
    //#output(void sendModes()): new char[](IRCStringConverter#1)[0..65_535]
    //#output(void sendModes()): new char[](IRCStringConverter#2) num objects
    //#output(void sendModes()): new char[](IRCStringConverter#2).length
    //#output(void sendModes()): new char[](IRCStringConverter#2)[0..65_567]
    //#output(void sendModes()): this...myAwayReason
    //#output(void sendModes()): this.myParser.stringConverter
    //#new obj(void sendModes()): java.lang.String:substring(...)
    //#new obj(void sendModes()): new IRCStringConverter(getIRCStringConverter#1)
    //#new obj(void sendModes()): new char[](IRCStringConverter#1)
    //#new obj(void sendModes()): new char[](IRCStringConverter#2)
    //#pre[4] (void sendModes()): this.lModeQueue != null
    //#pre[2] (void sendModes()): (soft) init'ed(this.myParser.stringConverter)
    //#pre[5] (void sendModes()): (soft) this.myParser != null
    //#pre[6] (void sendModes()): (soft) this.myParser.__Tag == com/dmdirc/parser/irc/IRCParser
    //#pre[7] (void sendModes()): (soft) this.myParser.cMyself != null
    //#pre[8] (void sendModes()): (soft) init'ed(this.myParser.currentSocketState)
    //#pre[9] (void sendModes()): (soft) this.myParser.hChanModesOther != null
    //#pre[10] (void sendModes()): (soft) this.myParser.hChannelList != null
    //#pre[12] (void sendModes()): (soft) this.myParser.myCallbackManager != null
    //#pre[13] (void sendModes()): (soft) this.myParser.myCallbackManager.callbackHash != null
    //#pre[14] (void sendModes()): (soft) init'ed(this.myParser.out)
    //#pre[15] (void sendModes()): (soft) init'ed(this.sNickname)
    //#presumption(void sendModes()): java.util.List:get(...)@398 != null
    //#post(void sendModes()): init'ed(java.lang.String:substring(...)._tainted)
    //#post(void sendModes()): possibly_updated(this...myAwayReason)
    //#post(void sendModes()): this.myParser.stringConverter == One-of{old this.myParser.stringConverter, &new IRCStringConverter(getIRCStringConverter#1)}
    //#post(void sendModes()): init'ed(this.myParser.stringConverter)
    //#post(void sendModes()): new IRCStringConverter(getIRCStringConverter#1) num objects <= 1
    //#post(void sendModes()): init'ed(new IRCStringConverter(getIRCStringConverter#1).__Tag)
    //#post(void sendModes()): init'ed(new IRCStringConverter(getIRCStringConverter#1).limit)
    //#post(void sendModes()): init'ed(new IRCStringConverter(getIRCStringConverter#1).lowercase)
    //#post(void sendModes()): init'ed(new IRCStringConverter(getIRCStringConverter#1).uppercase)
    //#post(void sendModes()): new char[](IRCStringConverter#1) num objects <= 1
    //#post(void sendModes()): init'ed(new char[](IRCStringConverter#1).length)
    //#post(void sendModes()): possibly_updated(new char[](IRCStringConverter#1)[0..65_535])
    //#post(void sendModes()): new char[](IRCStringConverter#2) num objects <= 1
    //#post(void sendModes()): init'ed(new char[](IRCStringConverter#2).length)
    //#post(void sendModes()): possibly_updated(new char[](IRCStringConverter#2)[0..65_567])
    //#unanalyzed(void sendModes()): Effects-of-calling:java.util.List:clear
    //#unanalyzed(void sendModes()): Effects-of-calling:java.util.Map:containsKey
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.String:toLowerCase
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.RuntimeException
    //#unanalyzed(void sendModes()): Effects-of-calling:java.util.Map:get
    //#unanalyzed(void sendModes()): Effects-of-calling:call
    //#unanalyzed(void sendModes()): Effects-of-calling:callDebugInfo
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.String:format
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.Integer:valueOf
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.String:toCharArray
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.String:length
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.String
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.String:indexOf
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.String:split
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.String:equalsIgnoreCase
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.Character:valueOf
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.Byte:byteValue
    //#unanalyzed(void sendModes()): Effects-of-calling:doSendString
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.Boolean:valueOf
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.String:charAt
    //#unanalyzed(void sendModes()): Effects-of-calling:java.io.PrintWriter:printf
    //#unanalyzed(void sendModes()): Effects-of-calling:setAwayReason
    //#unanalyzed(void sendModes()): Effects-of-calling:java.util.LinkedList
    //#unanalyzed(void sendModes()): Effects-of-calling:getListModeQueue
    //#unanalyzed(void sendModes()): Effects-of-calling:java.util.LinkedList:contains
    //#unanalyzed(void sendModes()): Effects-of-calling:java.util.Queue:offer
    //#unanalyzed(void sendModes()): Effects-of-calling:java.util.LinkedList:offer
    //#unanalyzed(void sendModes()): Effects-of-calling:java.lang.System:currentTimeMillis
    //#test_vector(void sendModes()): java.lang.String:charAt(...)@399: {0..42, 44..65_535}, {43}
    //#test_vector(void sendModes()): java.lang.StringBuilder:length(...)@406: {-2_147_483_648..0}, {1..4_294_967_295}
    //#test_vector(void sendModes()): java.lang.StringBuilder:length(...)@407: {-2_147_483_648..0}, {1..4_294_967_295}
    //#test_vector(void sendModes()): java.util.List:isEmpty(...)@391: {0}, {1}
		final StringBuilder positivemode = new StringBuilder();
		final StringBuilder negativemode = new StringBuilder();
		final StringBuilder sendModeStr = new StringBuilder();
		String modestr;
		boolean positive;
		for (int i = 0; i < lModeQueue.size(); ++i) {
			modestr = lModeQueue.get(i);
			positive = modestr.charAt(0) == '+';
			if (positive) {
				positivemode.append(modestr.charAt(1));
			} else {
				negativemode.append(modestr.charAt(1));
			}
		}
		if (negativemode.length() > 0) { sendModeStr.append("-").append(negativemode); }
		if (positivemode.length() > 0) { sendModeStr.append("+").append(positivemode); }
		myParser.callDebugInfo(IRCParser.DEBUG_INFO, "Sending mode: %s", sendModeStr.toString());
		myParser.sendLine("MODE " + sNickname + " " + sendModeStr.toString());
		clearModeQueue();
	}
    //#ClientInfo.java:411: end of method: void com.dmdirc.parser.irc.ClientInfo.sendModes()
	
	/**
	 * This function will clear the mode queue (WITHOUT Sending).
	 */
	public void clearModeQueue() { 
		lModeQueue.clear();
    //#ClientInfo.java:417: method: void com.dmdirc.parser.irc.ClientInfo.clearModeQueue()
    //#input(void clearModeQueue()): this
    //#input(void clearModeQueue()): this.lModeQueue
    //#pre[2] (void clearModeQueue()): this.lModeQueue != null
	}
    //#ClientInfo.java:418: end of method: void com.dmdirc.parser.irc.ClientInfo.clearModeQueue()
	
	/**
	 * Get the parser object that owns this client.
	 *
	 * @return The parser object that owns this client
	 */
	public IRCParser getParser() { return myParser; }
    //#ClientInfo.java:425: method: IRCParser com.dmdirc.parser.irc.ClientInfo.getParser()
    //#input(IRCParser getParser()): this
    //#input(IRCParser getParser()): this.myParser
    //#output(IRCParser getParser()): return_value
    //#post(IRCParser getParser()): return_value == this.myParser
    //#post(IRCParser getParser()): init'ed(return_value)
    //#ClientInfo.java:425: end of method: IRCParser com.dmdirc.parser.irc.ClientInfo.getParser()

}
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Descendant_Table[com/dmdirc/parser/irc/ClientInfo]
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.addChannelClientInfo(Lcom/dmdirc/parser/irc/ChannelClientInfo;)V
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.alterMode(ZLjava/lang/Character;)V
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.channelCount()I
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.checkVisibility()Z
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.clearModeQueue()V
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.delChannelClientInfo(Lcom/dmdirc/parser/irc/ChannelClientInfo;)V
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getAwayReason()Ljava/lang/String;
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getAwayState()Z
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getChannelClients()Ljava/util/List;
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getHost()Ljava/lang/String;
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getIdent()Ljava/lang/String;
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getMap()Ljava/util/Map;
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getNickname()Ljava/lang/String;
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getParser()Lcom/dmdirc/parser/irc/IRCParser;
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getRealName()Ljava/lang/String;
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getUserMode()J
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getUserModeStr()Ljava/lang/String;
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.isFake()Z
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.isOper()Z
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.isServer()Z
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.sendModes()V
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.setAwayReason(Ljava/lang/String;)V
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.setAwayState(Z)V
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.setFake(Z)Lcom/dmdirc/parser/irc/ClientInfo;
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.setMap(Ljava/util/Map;)V
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.setRealName(Ljava/lang/String;)V
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.setUserBits(Ljava/lang/String;Z)V
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.setUserBits(Ljava/lang/String;ZZ)V
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.setUserMode(J)V
    //#output(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.toString()Ljava/lang/String;
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Descendant_Table[com/dmdirc/parser/irc/ClientInfo] == &__Dispatch_Table
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.addChannelClientInfo(Lcom/dmdirc/parser/irc/ChannelClientInfo;)V == &addChannelClientInfo
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.alterMode(ZLjava/lang/Character;)V == &alterMode
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.channelCount()I == &channelCount
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.checkVisibility()Z == &checkVisibility
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.clearModeQueue()V == &clearModeQueue
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.delChannelClientInfo(Lcom/dmdirc/parser/irc/ChannelClientInfo;)V == &delChannelClientInfo
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getAwayReason()Ljava/lang/String; == &getAwayReason
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getAwayState()Z == &getAwayState
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getChannelClients()Ljava/util/List; == &getChannelClients
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getHost()Ljava/lang/String; == &getHost
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getIdent()Ljava/lang/String; == &getIdent
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getMap()Ljava/util/Map; == &getMap
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getNickname()Ljava/lang/String; == &getNickname
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getParser()Lcom/dmdirc/parser/irc/IRCParser; == &getParser
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getRealName()Ljava/lang/String; == &getRealName
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getUserMode()J == &getUserMode
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.getUserModeStr()Ljava/lang/String; == &getUserModeStr
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.isFake()Z == &isFake
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.isOper()Z == &isOper
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.isServer()Z == &isServer
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.sendModes()V == &sendModes
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.setAwayReason(Ljava/lang/String;)V == &setAwayReason
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.setAwayState(Z)V == &setAwayState
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.setFake(Z)Lcom/dmdirc/parser/irc/ClientInfo; == &setFake
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.setMap(Ljava/util/Map;)V == &setMap
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.setRealName(Ljava/lang/String;)V == &setRealName
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.setUserBits(Ljava/lang/String;Z)V == &setUserBits
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.setUserBits(Ljava/lang/String;ZZ)V == &setUserBits
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.setUserMode(J)V == &setUserMode
    //#post(com.dmdirc.parser.irc.ClientInfo__static_init): __Dispatch_Table.toString()Ljava/lang/String; == &toString
    //#ClientInfo.java:: end of method: com.dmdirc.parser.irc.ClientInfo.com.dmdirc.parser.irc.ClientInfo__static_init
    //#ClientInfo.java:: end of class: com.dmdirc.parser.irc.ClientInfo
