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

package com.dmdirc.addons.identd;

import com.dmdirc.Server;
import com.dmdirc.ServerManager;
import com.dmdirc.config.ConfigManager;
import com.dmdirc.config.IdentityManager;
import com.dmdirc.logger.ErrorLevel;
import com.dmdirc.logger.Logger;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;

/**
 * The IdentClient responds to an ident request.
 *
 * @author Shane "Dataforce" Mc Cormack
 */
public final class IdentClient implements Runnable {
	/** The IdentdServer that owns this Client. */
	private final IdentdServer myServer;
	/** The Socket that we are in charge of. */
	private final Socket mySocket;
	/** The Thread in use for this client. */
	private volatile Thread myThread;
	/** The plugin that owns us. */
	private final IdentdPlugin myPlugin;
	
	/**
	 * Create the IdentClient.
	 *
	 * @param server The server that owns this
	 * @param socket The socket we are handing
	 */
	public IdentClient(final IdentdServer server, final Socket socket, final IdentdPlugin plugin) {
    //#IdentClient.java:59: method: void com.dmdirc.addons.identd.IdentClient.com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)
    //#input(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): plugin
    //#input(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): server
    //#input(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): socket
    //#input(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): this
    //#output(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): new Thread(IdentClient#1) num objects
    //#output(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): this.myPlugin
    //#output(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): this.myServer
    //#output(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): this.mySocket
    //#output(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): this.myThread
    //#new obj(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): new Thread(IdentClient#1)
    //#post(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): this.myPlugin == plugin
    //#post(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): init'ed(this.myPlugin)
    //#post(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): this.myServer == server
    //#post(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): init'ed(this.myServer)
    //#post(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): this.mySocket == socket
    //#post(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): init'ed(this.mySocket)
    //#post(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): this.myThread == &new Thread(IdentClient#1)
    //#post(void com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)): new Thread(IdentClient#1) num objects == 1
		myServer = server;
		mySocket = socket;
		myPlugin = plugin;
		
		myThread = new Thread(this);
		myThread.start();
	}
    //#IdentClient.java:66: end of method: void com.dmdirc.addons.identd.IdentClient.com.dmdirc.addons.identd.IdentClient(IdentdServer, Socket, IdentdPlugin)
	
	/**
	 * Process this connection.
	 */
    @Override
	public void run() {
		final Thread thisThread = Thread.currentThread();
    //#IdentClient.java:73: method: void com.dmdirc.addons.identd.IdentClient.run()
    //#input(void run()): "ClientSocket Error: "._tainted
    //#input(void run()): com.dmdirc.logger.ErrorLevel.HIGH
    //#input(void run()): com/dmdirc/Server.__Descendant_Table[com/dmdirc/Server]
    //#input(void run()): com/dmdirc/Server.__Descendant_Table[others]
    //#input(void run()): com/dmdirc/Server.__Dispatch_Table.getParser()Lcom/dmdirc/parser/irc/IRCParser;
    //#input(void run()): com/dmdirc/ServerManager.__Class_Obj.__Lock
    //#input(void run()): com/dmdirc/ServerManager.me.servers
    //#input(void run()): this
    //#input(void run()): this.myPlugin
    //#input(void run()): this.myServer
    //#input(void run()): this.myServer.clientList
    //#input(void run()): this.mySocket
    //#input(void run()): this.myThread
    //#output(void run()): com/dmdirc/ServerManager.me
    //#output(void run()): new ArrayList(ServerManager#1) num objects
    //#output(void run()): new ServerManager(getServerManager#1) num objects
    //#output(void run()): new ServerManager(getServerManager#1).__Tag
    //#output(void run()): new ServerManager(getServerManager#1).servers
    //#new obj(void run()): new ArrayList(ServerManager#1)
    //#new obj(void run()): new ServerManager(getServerManager#1)
    //#pre[5] (void run()): this.myServer != null
    //#pre[6] (void run()): this.myServer.clientList != null
    //#pre[8] (void run()): (soft) this.mySocket != null
    //#pre[9] (void run()): (soft) init'ed(this.myThread)
    //#presumption(void run()): init'ed(com.dmdirc.logger.ErrorLevel.HIGH)
    //#post(void run()): com/dmdirc/ServerManager.me == One-of{old com/dmdirc/ServerManager.me, &new ServerManager(getServerManager#1)}
    //#post(void run()): new ArrayList(ServerManager#1) num objects <= 1
    //#post(void run()): new ServerManager(getServerManager#1) num objects <= 1
    //#post(void run()): init'ed(new ServerManager(getServerManager#1).__Tag)
    //#post(void run()): init'ed(new ServerManager(getServerManager#1).servers)
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:replaceAll
    //#unanalyzed(void run()): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void run()): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(void run()): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(void run()): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void run()): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void run()): Effects-of-calling:com.dmdirc.parser.irc.IRCParser:getLocalPort
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:split
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:format
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:trim
    //#unanalyzed(void run()): Effects-of-calling:java.lang.Integer:parseInt
    //#unanalyzed(void run()): Effects-of-calling:java.lang.Integer:valueOf
    //#unanalyzed(void run()): Effects-of-calling:com.dmdirc.addons.identd.IdentdPlugin:getDomain
    //#unanalyzed(void run()): Effects-of-calling:com.dmdirc.config.ConfigManager:getOptionBool
    //#unanalyzed(void run()): Effects-of-calling:java.lang.System:getProperty
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:toLowerCase
    //#unanalyzed(void run()): Effects-of-calling:com.dmdirc.config.ConfigManager:getOption
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:length
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:startsWith
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:indexOf
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:equals
    //#unanalyzed(void run()): Effects-of-calling:com.dmdirc.parser.irc.IRCParser:getMyNickname
    //#unanalyzed(void run()): Effects-of-calling:com.dmdirc.parser.irc.IRCParser:getMyUsername
    //#unanalyzed(void run()): Effects-of-calling:java.util.List:size
    //#unanalyzed(void run()): Effects-of-calling:java.util.List:get
    //#unanalyzed(void run()): Effects-of-calling:java.util.List:remove
		PrintWriter out = null;
		BufferedReader in = null;
		try {
			out = new PrintWriter(mySocket.getOutputStream(), true);
			in = new BufferedReader(new InputStreamReader(mySocket.getInputStream()));
			final String inputLine;
			if ((inputLine = in.readLine()) != null) {
				out.println(getIdentResponse(inputLine, IdentityManager.getGlobalConfig()));
    //#IdentClient.java:81: Warning: method not available - call not analyzed
    //#    call on ConfigManager com.dmdirc.config.IdentityManager:getGlobalConfig()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: void run()
    //#    unanalyzed callee: ConfigManager com.dmdirc.config.IdentityManager:getGlobalConfig()
			}
		} catch (IOException e) {
			if (thisThread == myThread) {
				Logger.userError(ErrorLevel.HIGH ,"ClientSocket Error: "+e.getMessage());
    //#IdentClient.java:85: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.logger.Logger:userError(ErrorLevel, String)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: void run()
    //#    unanalyzed callee: void com.dmdirc.logger.Logger:userError(ErrorLevel, String)
			}
		} finally {
			try {
				out.close();
    //#IdentClient.java:89: ?!null dereference
    //#    out != null
    //#    severity: HIGH
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: void run()
    //#    basic block: bb_11
    //#    assertion: out != null
    //#    VN: null
    //#    Expected: Inverse{null} or Invalid
    //#    Bad: Addr_Set{null}
    //#    Attribs:  Ptr  null in Bad
				in.close();
    //#IdentClient.java:90: ?!null dereference
    //#    in != null
    //#    severity: HIGH
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: void run()
    //#    basic block: bb_11
    //#    assertion: in != null
    //#    VN: null
    //#    Expected: Inverse{null} or Invalid
    //#    Bad: Addr_Set{null}
    //#    Attribs:  Ptr  null in Bad
				mySocket.close();
			} catch (IOException e) { }
    //#IdentClient.java:92: Warning: unused assignment
    //#    Unused assignment into e
    //#    severity: LOW
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: void run()
		}
		myServer.delClient(this);
	}
    //#IdentClient.java:95: end of method: void com.dmdirc.addons.identd.IdentClient.run()
	
	/**
	 * Get the ident response for a given line.
	 * Complies with rfc1413 (http://www.faqs.org/rfcs/rfc1413.html)
	 *
	 * @param input Line to generate response for
	 * @param config The config manager to use for settings
	 * @return the ident response for the given line
	 */
	protected String getIdentResponse(final String input, final ConfigManager config) {
		final String unescapedInput = unescapeString(input);
    //#IdentClient.java:106: method: String com.dmdirc.addons.identd.IdentClient.getIdentResponse(String, ConfigManager)
    //#input(String getIdentResponse(String, ConfigManager)): com/dmdirc/Server.__Descendant_Table[com/dmdirc/Server]
    //#input(String getIdentResponse(String, ConfigManager)): com/dmdirc/Server.__Descendant_Table[others]
    //#input(String getIdentResponse(String, ConfigManager)): com/dmdirc/Server.__Dispatch_Table.getParser()Lcom/dmdirc/parser/irc/IRCParser;
    //#input(String getIdentResponse(String, ConfigManager)): com/dmdirc/ServerManager.__Class_Obj.__Lock
    //#input(String getIdentResponse(String, ConfigManager)): com/dmdirc/ServerManager.me.servers
    //#input(String getIdentResponse(String, ConfigManager)): config
    //#input(String getIdentResponse(String, ConfigManager)): input
    //#input(String getIdentResponse(String, ConfigManager)): this
    //#input(String getIdentResponse(String, ConfigManager)): this.myPlugin
    //#output(String getIdentResponse(String, ConfigManager)): com/dmdirc/ServerManager.me
    //#output(String getIdentResponse(String, ConfigManager)): new ArrayList(ServerManager#1) num objects
    //#output(String getIdentResponse(String, ConfigManager)): new ServerManager(getServerManager#1) num objects
    //#output(String getIdentResponse(String, ConfigManager)): new ServerManager(getServerManager#1).__Tag
    //#output(String getIdentResponse(String, ConfigManager)): new ServerManager(getServerManager#1).servers
    //#output(String getIdentResponse(String, ConfigManager)): return_value
    //#new obj(String getIdentResponse(String, ConfigManager)): new ArrayList(ServerManager#1)
    //#new obj(String getIdentResponse(String, ConfigManager)): new ServerManager(getServerManager#1)
    //#pre[3] (String getIdentResponse(String, ConfigManager)): input != null
    //#post(String getIdentResponse(String, ConfigManager)): com/dmdirc/ServerManager.me == One-of{old com/dmdirc/ServerManager.me, &new ServerManager(getServerManager#1)}
    //#post(String getIdentResponse(String, ConfigManager)): init'ed(return_value)
    //#post(String getIdentResponse(String, ConfigManager)): new ArrayList(ServerManager#1) num objects == 0
    //#post(String getIdentResponse(String, ConfigManager)): new ServerManager(getServerManager#1) num objects == 0
    //#post(String getIdentResponse(String, ConfigManager)): init'ed(new ServerManager(getServerManager#1).__Tag)
    //#post(String getIdentResponse(String, ConfigManager)): init'ed(new ServerManager(getServerManager#1).servers)
    //#unanalyzed(String getIdentResponse(String, ConfigManager)): Effects-of-calling:java.lang.String:replaceAll
    //#unanalyzed(String getIdentResponse(String, ConfigManager)): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(String getIdentResponse(String, ConfigManager)): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(String getIdentResponse(String, ConfigManager)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(String getIdentResponse(String, ConfigManager)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(String getIdentResponse(String, ConfigManager)): Effects-of-calling:com.dmdirc.parser.irc.IRCParser:getLocalPort
		final String[] bits = unescapedInput.replaceAll("\\s+", "").split(",", 2);
		if (bits.length < 2) {
    //#IdentClient.java:108: ?use of default init
    //#    init'ed(bits.length)
    //#    severity: LOW
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    basic block: Entry_BB_1
    //#    assertion: init'ed(bits.length)
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
    //#IdentClient.java:108: Warning: test always goes same way
    //#    Test predetermined because bits.length == 0
    //#    severity: LOW
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    from bb: Entry_BB_1
    //#    live edge: Entry_BB_1-->bb_2
    //#    tested vn: undefined - 2
    //#    tested vn values: {-2}
			return String.format("%s : ERROR : X-INVALID-INPUT", escapeString(unescapedInput));
		}
		final int myPort;
		final int theirPort;
		try {
			myPort = Integer.parseInt(bits[0].trim());
    //#IdentClient.java:114: Warning: dead code
    //#    Dead code here because bits.length == 0
    //#    severity: LOW
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_3
    //#IdentClient.java:114: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_4
			theirPort = Integer.parseInt(bits[1].trim());
		} catch (NumberFormatException e) {
			return String.format("%s , %s : ERROR : X-INVALID-INPUT", escapeString(bits[0]), escapeString(bits[1]));
		}
		
		if (myPort > 65535 || myPort < 1 || theirPort > 65535 || theirPort < 1) {
    //#IdentClient.java:120: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_6
    //#IdentClient.java:120: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_7
    //#IdentClient.java:120: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_8
    //#IdentClient.java:120: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_9
			return String.format("%d , %d : ERROR : INVALID-PORT", myPort, theirPort);
    //#IdentClient.java:121: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_10
		}
		
		final Server server = getServerByPort(myPort);
    //#IdentClient.java:124: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_11
		if (!config.getOptionBool(myPlugin.getDomain(), "advanced.alwaysOn") && (server == null || config.getOptionBool(myPlugin.getDomain(), "advanced.isNoUser"))) {
    //#IdentClient.java:125: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_12
    //#IdentClient.java:125: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_13
			return String.format("%d , %d : ERROR : NO-USER", myPort, theirPort);
    //#IdentClient.java:126: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_14
		}
		
		if (config.getOptionBool(myPlugin.getDomain(), "advanced.isHiddenUser")) {
    //#IdentClient.java:129: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_15
			return String.format("%d , %d : ERROR : HIDDEN-USER", myPort, theirPort);
    //#IdentClient.java:130: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_16
		}
		
		final String osName = System.getProperty("os.name").toLowerCase();
    //#IdentClient.java:133: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_17
		final String os;
		final String username;

		final String customSystem = config.getOption(myPlugin.getDomain(), "advanced.customSystem");
		if (config.getOptionBool(myPlugin.getDomain(), "advanced.useCustomSystem") && customSystem != null && customSystem.length() > 0 && customSystem.length() < 513) {
    //#IdentClient.java:138: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_18
    //#IdentClient.java:138: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_19
    //#IdentClient.java:138: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_20
			os = customSystem;
    //#IdentClient.java:139: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_21
		} else {
			// Tad excessive maybe, but complete!
			// Based on: http://mindprod.com/jgloss/properties.html
			// and the SYSTEM NAMES section of rfc1340 (http://www.faqs.org/rfcs/rfc1340.html)
			if (osName.startsWith("windows")) { os = "WIN32"; }
    //#IdentClient.java:144: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_22
    //#IdentClient.java:144: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_23
			else if (osName.startsWith("mac")) { os = "MACOS"; }
    //#IdentClient.java:145: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_24
    //#IdentClient.java:145: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_25
			else if (osName.startsWith("linux")) { os = "UNIX"; }
    //#IdentClient.java:146: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_26
    //#IdentClient.java:146: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_27
			else if (osName.indexOf("bsd") > -1) { os = "UNIX-BSD"; }
    //#IdentClient.java:147: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_28
    //#IdentClient.java:147: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_29
			else if ("os/2".equals(osName)) { os = "OS/2"; }
    //#IdentClient.java:148: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_30
    //#IdentClient.java:148: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_31
			else if (osName.indexOf("unix") > -1) { os = "UNIX"; }
    //#IdentClient.java:149: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_32
    //#IdentClient.java:149: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_33
			else if ("irix".equals(osName)) { os = "IRIX"; }
    //#IdentClient.java:150: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_34
    //#IdentClient.java:150: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_35
			else { os = "UNKNOWN"; }
    //#IdentClient.java:151: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_36
		}
		
		final String customName = config.getOption(myPlugin.getDomain(), "general.customName");
    //#IdentClient.java:154: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_37
		if (config.getOptionBool(myPlugin.getDomain(), "general.useCustomName") && customName != null && customName.length() > 0 && customName.length() < 513) {
    //#IdentClient.java:155: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_38
    //#IdentClient.java:155: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_39
    //#IdentClient.java:155: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_40
			username = customName;
    //#IdentClient.java:156: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_41
		} else if (server != null && config.getOptionBool(myPlugin.getDomain(), "general.useNickname")) {
    //#IdentClient.java:157: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_42
    //#IdentClient.java:157: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_43
			username = server.getParser().getMyNickname();
    //#IdentClient.java:158: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_44
		} else if (server != null && config.getOptionBool(myPlugin.getDomain(), "general.useUsername")) {
    //#IdentClient.java:159: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_45
    //#IdentClient.java:159: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_46
			username = server.getParser().getMyUsername();
    //#IdentClient.java:160: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_47
		} else {
			username = System.getProperty("user.name");
    //#IdentClient.java:162: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_48
		}
		
		return String.format("%d , %d : USERID : %s : %s", myPort, theirPort, escapeString(os), escapeString(username));
    //#IdentClient.java:165: Warning: dead code continues
    //#    Dead code continues
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: String getIdentResponse(String, ConfigManager)
    //#    dead bb: bb_49
    //#IdentClient.java:165: end of method: String com.dmdirc.addons.identd.IdentClient.getIdentResponse(String, ConfigManager)
	}
	
	/**
	 * Escape special chars.
	 *
	 * @param str String to escape
	 * @return Escaped string.
	 */
	public static String escapeString(final String str) {
		return str.replaceAll("\\\\", "\\\\\\\\").replaceAll(":", "\\\\:").replaceAll(",", "\\\\,").replaceAll(" ", "\\\\ ");
    //#IdentClient.java:175: method: String com.dmdirc.addons.identd.IdentClient.escapeString(String)
    //#input(String escapeString(String)): str
    //#output(String escapeString(String)): return_value
    //#pre[1] (String escapeString(String)): str != null
    //#post(String escapeString(String)): return_value != null
    //#IdentClient.java:175: end of method: String com.dmdirc.addons.identd.IdentClient.escapeString(String)
	}
	
	/**
	 * Unescape special chars.
	 *
	 * @param str String to escape
	 * @return Escaped string.
	 */
	public static String unescapeString(final String str) {
		return str.replaceAll("\\\\:", ":").replaceAll("\\\\ ", " ").replaceAll("\\\\,", ",").replaceAll("\\\\\\\\", "\\\\");
    //#IdentClient.java:185: method: String com.dmdirc.addons.identd.IdentClient.unescapeString(String)
    //#input(String unescapeString(String)): str
    //#output(String unescapeString(String)): return_value
    //#pre[1] (String unescapeString(String)): str != null
    //#post(String unescapeString(String)): return_value != null
    //#IdentClient.java:185: end of method: String com.dmdirc.addons.identd.IdentClient.unescapeString(String)
	}
	
	/**
	 * Close this IdentClient.
	 */
	public void close() {
		if (myThread != null) {
    //#IdentClient.java:192: method: void com.dmdirc.addons.identd.IdentClient.close()
    //#input(void close()): this
    //#input(void close()): this.mySocket
    //#input(void close()): this.myThread
    //#output(void close()): this.myThread
    //#pre[1] (void close()): init'ed(this.myThread)
    //#pre[3] (void close()): (soft) this.mySocket != null
    //#post(void close()): this.myThread == null
    //#test_vector(void close()): this.myThread: Addr_Set{null}, Inverse{null}
			final Thread tmpThread = myThread;
			myThread = null;
			if (tmpThread != null) { tmpThread.interrupt(); }
    //#IdentClient.java:195: Warning: test always goes same way
    //#    Test predetermined because tmpThread != null
    //#    severity: LOW
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: void close()
    //#    from bb: bb_2
    //#    live edge: bb_2-->bb_3
    //#    tested vn: this.myThread == null
    //#    tested vn values: {0}
			try { mySocket.close(); } catch (IOException e) { }
		}
	}
    //#IdentClient.java:198: end of method: void com.dmdirc.addons.identd.IdentClient.close()

	/**
	 * Retrieves the server that is bound to the specified local port.
	 *
	 * @param port Port to check for
	 * @return The server instance listening on the given port
	 */
	protected static Server getServerByPort(final int port) {
		for (Server server : ServerManager.getServerManager().getServers()) {
    //#IdentClient.java:207: method: Server com.dmdirc.addons.identd.IdentClient.getServerByPort(int)
    //#input(Server getServerByPort(int)): com/dmdirc/Server.__Descendant_Table[com/dmdirc/Server]
    //#input(Server getServerByPort(int)): com/dmdirc/Server.__Descendant_Table[others]
    //#input(Server getServerByPort(int)): com/dmdirc/Server.__Dispatch_Table.getParser()Lcom/dmdirc/parser/irc/IRCParser;
    //#input(Server getServerByPort(int)): com/dmdirc/ServerManager.__Class_Obj.__Lock
    //#input(Server getServerByPort(int)): com/dmdirc/ServerManager.me
    //#input(Server getServerByPort(int)): com/dmdirc/ServerManager.me.servers
    //#input(Server getServerByPort(int)): port
    //#output(Server getServerByPort(int)): com/dmdirc/ServerManager.me
    //#output(Server getServerByPort(int)): new ArrayList(ServerManager#1) num objects
    //#output(Server getServerByPort(int)): new ServerManager(getServerManager#1) num objects
    //#output(Server getServerByPort(int)): new ServerManager(getServerManager#1).__Tag
    //#output(Server getServerByPort(int)): new ServerManager(getServerManager#1).servers
    //#output(Server getServerByPort(int)): return_value
    //#new obj(Server getServerByPort(int)): new ArrayList(ServerManager#1)
    //#new obj(Server getServerByPort(int)): new ServerManager(getServerManager#1)
    //#pre[1] (Server getServerByPort(int)): init'ed(com/dmdirc/ServerManager.me)
    //#presumption(Server getServerByPort(int)): java.util.Iterator:next(...).__Tag@207 == com/dmdirc/Server
    //#presumption(Server getServerByPort(int)): java.util.Iterator:next(...)@207 != null
    //#presumption(Server getServerByPort(int)): server.parser@207 != null
    //#post(Server getServerByPort(int)): com/dmdirc/ServerManager.me == One-of{old com/dmdirc/ServerManager.me, &new ServerManager(getServerManager#1)}
    //#post(Server getServerByPort(int)): com/dmdirc/ServerManager.me != null
    //#post(Server getServerByPort(int)): init'ed(return_value)
    //#post(Server getServerByPort(int)): new ArrayList(ServerManager#1) num objects <= 1
    //#post(Server getServerByPort(int)): new ServerManager(getServerManager#1) num objects == new ArrayList(ServerManager#1) num objects
    //#post(Server getServerByPort(int)): new ServerManager(getServerManager#1).__Tag == com/dmdirc/ServerManager
    //#post(Server getServerByPort(int)): new ServerManager(getServerManager#1).servers == &new ArrayList(ServerManager#1)
    //#unanalyzed(Server getServerByPort(int)): Effects-of-calling:java.util.ArrayList
    //#test_vector(Server getServerByPort(int)): java.util.Iterator:hasNext(...)@207: {0}, {1}
			if (server.getParser().getLocalPort() == port) {
    //#IdentClient.java:208: Warning: method not available - call not analyzed
    //#    call on int com.dmdirc.parser.irc.IRCParser:getLocalPort()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.identd.IdentClient
    //#    method: Server getServerByPort(int)
    //#    unanalyzed callee: int com.dmdirc.parser.irc.IRCParser:getLocalPort()
				return server;
			}
		}
		return null;
    //#IdentClient.java:212: end of method: Server com.dmdirc.addons.identd.IdentClient.getServerByPort(int)
	}

}

    //#output(com.dmdirc.addons.identd.IdentClient__static_init): __Descendant_Table[com/dmdirc/addons/identd/IdentClient]
    //#output(com.dmdirc.addons.identd.IdentClient__static_init): __Dispatch_Table.close()V
    //#output(com.dmdirc.addons.identd.IdentClient__static_init): __Dispatch_Table.getIdentResponse(Ljava/lang/String;Lcom/dmdirc/config/ConfigManager;)Ljava/lang/String;
    //#output(com.dmdirc.addons.identd.IdentClient__static_init): __Dispatch_Table.run()V
    //#post(com.dmdirc.addons.identd.IdentClient__static_init): __Descendant_Table[com/dmdirc/addons/identd/IdentClient] == &__Dispatch_Table
    //#post(com.dmdirc.addons.identd.IdentClient__static_init): __Dispatch_Table.close()V == &close
    //#post(com.dmdirc.addons.identd.IdentClient__static_init): __Dispatch_Table.getIdentResponse(Ljava/lang/String;Lcom/dmdirc/config/ConfigManager;)Ljava/lang/String; == &getIdentResponse
    //#post(com.dmdirc.addons.identd.IdentClient__static_init): __Dispatch_Table.run()V == &run
    //#IdentClient.java:: end of method: com.dmdirc.addons.identd.IdentClient.com.dmdirc.addons.identd.IdentClient__static_init
    //#IdentClient.java:: end of class: com.dmdirc.addons.identd.IdentClient
