* @param client
	 */
	public void init_disconn(final Client client, final Boolean logout) {
		debug("init_disconn(" + client.getIPAddress() + ")");

		// get the player associated with the client
		final Player player = getPlayer(client);

		// if such a player does not exist, then just disconnect the client
		if (player == null) {
			debug("Player not found for client: " + client);
			disconnect(client);
			return;
		}

		final String playerName = player.getName();
		
		// TODO fix this kludgy use of a command invocation...
		// break any current control of npcs
		cmd_control("#break", client);

		// remove listener
		getRoom( player.getLocation() ).removeListener(player);
		
		// remove from chat channels
		for(final ChatChannel ch : chan.getChatChannels()) {
			if( ch.isListener(player) ) ch.removeListener(player);
		}
		
		// TODO less kludgy route to removing player from channel listens?
		// remove player from joined channels
		/*for(final String channelName : chan.getChannelNames()) {
			if( chan.isPlayerListening(channelName, player) ) {
				try {
					chan.remove(player, OOC_CHANNEL);
				}
				catch(final NoSuchChannelException nsce) {
					debug("INIT_DISCONN: No such chat channel.");
				}
			}
		}*/

		/*
		 * unequip gear
		 * 
		 * If we didn't do this, stuff could get stuck in limbo, alternatively,
		 * we could just loop through the items array and put a new copy of the
		 * references in the inventory, since it's all going to end up back in
		 * the inventory anyway (or at least until I figure out how to persist
		 * information about reloading slots for a player).
		 */

		// Unequipping gear
		final List<Item> inventory = player.getInventory();

		for (final Slot slot : player.getSlots().values()) {
			if (slot.isFull()) {
				if (slot.getItem() != null) inventory.add(slot.remove());
			}
		}

		send("Equipment un-equipped!", client);

		player.setStatus("ZZZ");
		
		// handle account modifications
		if (use_accounts) {
			final Account account = acctMgr.getAccount(player);

			if (account != null) {
				debug("Account ID: " + account.getId());

				account.setPlayer(null);

				if (!logout) {
					account.setClient(null);
					account.setOnline(false);
				}
			}
		}
		
		// get time
		final Time time = getTime();
		final Date date = getDate();
		
		logDisconnect(player, time);

		// this part should only be done when a player enters or exits play/the game
		if (!use_accounts || (use_accounts && logout)) {
			// get session
			Session toRemove = sessionMap.get(player);

			// record disconnect time
			toRemove.disconnect = new Tuple<Date, Time>(date, time);

			// store the session info on disk

			// clear session
			sessionMap.remove(player);
		}

		// if player is a guest
		if (player.hasFlag(ObjectFlag.GUEST)) {
			objectDB.remove(player); // remove from database (replace db entry with NULLObject?)
		}
		else {
			send("Saving mail...", player.getClient());

			saveMail(player); // save mail
		}

		// TODO resolve where I get the numbers from

		// cName handling
		// int temp = numPlayersOnlinePerClass.get( player.getPClass() );
		int temp = objectDB.getNumPlayers(player.getPClass());
		
		numPlayersOnlinePerClass.put(player.getPClass(), temp--);

		cNames.remove(player.getCName());

		// synchronized to deal with the possibility that someone invoked 'who'
		// and needs to finish iterating through the list
		synchronized (players) {
			players.remove(player); // Remove the player object for the disconnecting player
		}

		// DEBUG: Tell us which character was disconnected
		debug(playerName + " removed from play!");
		
		// if this is a complete disconnect, then disconnect the client as well
		if (!logout) {
			send("Disconnected from " + serverName + "!", client);
			disconnect(client);
		}
	}