site

(djk)
2011-06-11: Remove unused alien source files.

Remove unused alien source files.

diff --git a/alien/src/net/pterodactylus/fcp/highlevel/FcpClient.java b/alien/src/net/pterodactylus/fcp/highlevel/FcpClient.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/fcp/highlevel/FcpClient.java
+++ /dev/null
@@ -1,1172 +0,0 @@
-/*
- * jFCPlib - FcpClient.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-import java.util.concurrent.CountDownLatch;
-
-import net.pterodactylus.fcp.AddPeer;
-import net.pterodactylus.fcp.ClientHello;
-import net.pterodactylus.fcp.CloseConnectionDuplicateClientName;
-import net.pterodactylus.fcp.DataFound;
-import net.pterodactylus.fcp.EndListPeerNotes;
-import net.pterodactylus.fcp.EndListPeers;
-import net.pterodactylus.fcp.EndListPersistentRequests;
-import net.pterodactylus.fcp.FCPPluginMessage;
-import net.pterodactylus.fcp.FCPPluginReply;
-import net.pterodactylus.fcp.FcpAdapter;
-import net.pterodactylus.fcp.FcpConnection;
-import net.pterodactylus.fcp.FcpListener;
-import net.pterodactylus.fcp.GenerateSSK;
-import net.pterodactylus.fcp.GetFailed;
-import net.pterodactylus.fcp.GetNode;
-import net.pterodactylus.fcp.ListPeerNotes;
-import net.pterodactylus.fcp.ListPeers;
-import net.pterodactylus.fcp.ListPersistentRequests;
-import net.pterodactylus.fcp.ModifyPeer;
-import net.pterodactylus.fcp.ModifyPeerNote;
-import net.pterodactylus.fcp.NodeData;
-import net.pterodactylus.fcp.NodeHello;
-import net.pterodactylus.fcp.NodeRef;
-import net.pterodactylus.fcp.Peer;
-import net.pterodactylus.fcp.PeerNote;
-import net.pterodactylus.fcp.PeerRemoved;
-import net.pterodactylus.fcp.PersistentGet;
-import net.pterodactylus.fcp.PersistentPut;
-import net.pterodactylus.fcp.ProtocolError;
-import net.pterodactylus.fcp.RemovePeer;
-import net.pterodactylus.fcp.SSKKeypair;
-import net.pterodactylus.fcp.SimpleProgress;
-import net.pterodactylus.fcp.WatchGlobal;
-import net.pterodactylus.util.filter.Filter;
-import net.pterodactylus.util.filter.Filters;
-import net.pterodactylus.util.thread.ObjectWrapper;
-
-/**
- * High-level FCP client that hides the details of the underlying FCP
- * implementation.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class FcpClient {
-
-	/** Object used for synchronization. */
-	private final Object syncObject = new Object();
-
-	/** Listener management. */
-	private final FcpClientListenerManager fcpClientListenerManager = new FcpClientListenerManager(this);
-
-	/** The underlying FCP connection. */
-	private final FcpConnection fcpConnection;
-
-	/** The {@link NodeHello} data sent by the node on connection. */
-	private volatile NodeHello nodeHello;
-
-	/** Whether the client is currently connected. */
-	private volatile boolean connected;
-
-	/** The listener for “connection closed” events. */
-	private FcpListener connectionClosedListener;
-
-	/**
-	 * Creates an FCP client with the given name.
-	 *
-	 * @throws UnknownHostException
-	 *             if the hostname “localhost” is unknown
-	 */
-	public FcpClient() throws UnknownHostException {
-		this("localhost");
-	}
-
-	/**
-	 * Creates an FCP client.
-	 *
-	 * @param hostname
-	 *            The hostname of the Freenet node
-	 * @throws UnknownHostException
-	 *             if the given hostname can not be resolved
-	 */
-	public FcpClient(String hostname) throws UnknownHostException {
-		this(hostname, FcpConnection.DEFAULT_PORT);
-	}
-
-	/**
-	 * Creates an FCP client.
-	 *
-	 * @param hostname
-	 *            The hostname of the Freenet node
-	 * @param port
-	 *            The Freenet node’s FCP port
-	 * @throws UnknownHostException
-	 *             if the given hostname can not be resolved
-	 */
-	public FcpClient(String hostname, int port) throws UnknownHostException {
-		this(InetAddress.getByName(hostname), port);
-	}
-
-	/**
-	 * Creates an FCP client.
-	 *
-	 * @param host
-	 *            The host address of the Freenet node
-	 */
-	public FcpClient(InetAddress host) {
-		this(host, FcpConnection.DEFAULT_PORT);
-	}
-
-	/**
-	 * Creates an FCP client.
-	 *
-	 * @param host
-	 *            The host address of the Freenet node
-	 * @param port
-	 *            The Freenet node’s FCP port
-	 */
-	public FcpClient(InetAddress host, int port) {
-		this(new FcpConnection(host, port), false);
-	}
-
-	/**
-	 * Creates a new high-level FCP client that will use the given connection.
-	 * This constructor will assume that the FCP connection is already
-	 * connected.
-	 *
-	 * @param fcpConnection
-	 *            The FCP connection to use
-	 */
-	public FcpClient(FcpConnection fcpConnection) {
-		this(fcpConnection, true);
-	}
-
-	/**
-	 * Creates a new high-level FCP client that will use the given connection.
-	 *
-	 * @param fcpConnection
-	 *            The FCP connection to use
-	 * @param connected
-	 *            The initial status of the FCP connection
-	 */
-	public FcpClient(FcpConnection fcpConnection, boolean connected) {
-		this.fcpConnection = fcpConnection;
-		this.connected = connected;
-		connectionClosedListener = new FcpAdapter() {
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			@SuppressWarnings("synthetic-access")
-			public void connectionClosed(FcpConnection fcpConnection, Throwable throwable) {
-				FcpClient.this.connected = false;
-				fcpClientListenerManager.fireFcpClientDisconnected();
-			}
-		};
-		fcpConnection.addFcpListener(connectionClosedListener);
-	}
-
-	//
-	// LISTENER MANAGEMENT
-	//
-
-	/**
-	 * Adds an FCP listener to the underlying connection.
-	 *
-	 * @param fcpListener
-	 *            The FCP listener to add
-	 */
-	public void addFcpListener(FcpListener fcpListener) {
-		fcpConnection.addFcpListener(fcpListener);
-	}
-
-	/**
-	 * Removes an FCP listener from the underlying connection.
-	 *
-	 * @param fcpListener
-	 *            The FCP listener to remove
-	 */
-	public void removeFcpListener(FcpListener fcpListener) {
-		fcpConnection.removeFcpListener(fcpListener);
-	}
-
-	/**
-	 * Adds an FCP client listener to the list of registered listeners.
-	 *
-	 * @param fcpClientListener
-	 *            The FCP client listener to add
-	 */
-	public void addFcpClientListener(FcpClientListener fcpClientListener) {
-		fcpClientListenerManager.addListener(fcpClientListener);
-	}
-
-	/**
-	 * Removes an FCP client listener from the list of registered listeners.
-	 *
-	 * @param fcpClientListener
-	 *            The FCP client listener to remove
-	 */
-	public void removeFcpClientListener(FcpClientListener fcpClientListener) {
-		fcpClientListenerManager.removeListener(fcpClientListener);
-	}
-
-	//
-	// ACCESSORS
-	//
-
-	/**
-	 * Returns the {@link NodeHello} object that the node returned when
-	 * connecting.
-	 *
-	 * @return The {@code NodeHello} data container
-	 */
-	public NodeHello getNodeHello() {
-		return nodeHello;
-	}
-
-	/**
-	 * Returns the underlying FCP connection.
-	 *
-	 * @return The underlying FCP connection
-	 */
-	public FcpConnection getConnection() {
-		return fcpConnection;
-	}
-
-	//
-	// ACTIONS
-	//
-
-	/**
-	 * Connects the FCP client.
-	 *
-	 * @param name
-	 *            The name of the client
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public void connect(final String name) throws IOException, FcpException {
-		checkConnected(false);
-		connected = true;
-		new ExtendedFcpAdapter() {
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			@SuppressWarnings("synthetic-access")
-			public void run() throws IOException {
-				fcpConnection.connect();
-				ClientHello clientHello = new ClientHello(name);
-				fcpConnection.sendMessage(clientHello);
-				WatchGlobal watchGlobal = new WatchGlobal(true);
-				fcpConnection.sendMessage(watchGlobal);
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			@SuppressWarnings("synthetic-access")
-			public void receivedNodeHello(FcpConnection fcpConnection, NodeHello nodeHello) {
-				FcpClient.this.nodeHello = nodeHello;
-				completionLatch.countDown();
-			}
-		}.execute();
-	}
-
-	/**
-	 * Disconnects the FCP client.
-	 */
-	public void disconnect() {
-		synchronized (syncObject) {
-			fcpConnection.close();
-			syncObject.notifyAll();
-		}
-	}
-
-	/**
-	 * Returns whether this client is currently connected.
-	 *
-	 * @return {@code true} if the client is currently connected, {@code false}
-	 *         otherwise
-	 */
-	public boolean isConnected() {
-		return connected;
-	}
-
-	/**
-	 * Detaches this client from its underlying FCP connection.
-	 */
-	public void detach() {
-		fcpConnection.removeFcpListener(connectionClosedListener);
-	}
-
-	//
-	// PEER MANAGEMENT
-	//
-
-	/**
-	 * Returns all peers that the node has.
-	 *
-	 * @param withMetadata
-	 *            <code>true</code> to include peer metadata
-	 * @param withVolatile
-	 *            <code>true</code> to include volatile peer data
-	 * @return A set containing the node’s peers
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public Collection<Peer> getPeers(final boolean withMetadata, final boolean withVolatile) throws IOException, FcpException {
-		final Set<Peer> peers = Collections.synchronizedSet(new HashSet<Peer>());
-		new ExtendedFcpAdapter() {
-
-			/** The ID of the “ListPeers” request. */
-			@SuppressWarnings("synthetic-access")
-			private String identifier = createIdentifier("list-peers");
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			@SuppressWarnings("synthetic-access")
-			public void run() throws IOException {
-				fcpConnection.sendMessage(new ListPeers(identifier, withMetadata, withVolatile));
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
-				if (peer.getIdentifier().equals(identifier)) {
-					peers.add(peer);
-				}
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			public void receivedEndListPeers(FcpConnection fcpConnection, EndListPeers endListPeers) {
-				if (endListPeers.getIdentifier().equals(identifier)) {
-					completionLatch.countDown();
-				}
-			}
-		}.execute();
-		return peers;
-	}
-
-	/**
-	 * Returns all darknet peers.
-	 *
-	 * @param withMetadata
-	 *            <code>true</code> to include peer metadata
-	 * @param withVolatile
-	 *            <code>true</code> to include volatile peer data
-	 * @return A set containing the node’s darknet peers
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public Collection<Peer> getDarknetPeers(boolean withMetadata, boolean withVolatile) throws IOException, FcpException {
-		Collection<Peer> allPeers = getPeers(withMetadata, withVolatile);
-		Collection<Peer> darknetPeers = new HashSet<Peer>();
-		for (Peer peer : allPeers) {
-			if (!peer.isOpennet() && !peer.isSeed()) {
-				darknetPeers.add(peer);
-			}
-		}
-		return darknetPeers;
-	}
-
-	/**
-	 * Returns all opennet peers.
-	 *
-	 * @param withMetadata
-	 *            <code>true</code> to include peer metadata
-	 * @param withVolatile
-	 *            <code>true</code> to include volatile peer data
-	 * @return A set containing the node’s opennet peers
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public Collection<Peer> getOpennetPeers(boolean withMetadata, boolean withVolatile) throws IOException, FcpException {
-		Collection<Peer> allPeers = getPeers(withMetadata, withVolatile);
-		Collection<Peer> opennetPeers = new HashSet<Peer>();
-		for (Peer peer : allPeers) {
-			if (peer.isOpennet() && !peer.isSeed()) {
-				opennetPeers.add(peer);
-			}
-		}
-		return opennetPeers;
-	}
-
-	/**
-	 * Returns all seed peers.
-	 *
-	 * @param withMetadata
-	 *            <code>true</code> to include peer metadata
-	 * @param withVolatile
-	 *            <code>true</code> to include volatile peer data
-	 * @return A set containing the node’s seed peers
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public Collection<Peer> getSeedPeers(boolean withMetadata, boolean withVolatile) throws IOException, FcpException {
-		Collection<Peer> allPeers = getPeers(withMetadata, withVolatile);
-		Collection<Peer> seedPeers = new HashSet<Peer>();
-		for (Peer peer : allPeers) {
-			if (peer.isSeed()) {
-				seedPeers.add(peer);
-			}
-		}
-		return seedPeers;
-	}
-
-	/**
-	 * Adds the given peer to the node.
-	 *
-	 * @param peer
-	 *            The peer to add
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public void addPeer(Peer peer) throws IOException, FcpException {
-		addPeer(peer.getNodeRef());
-	}
-
-	/**
-	 * Adds the peer defined by the noderef to the node.
-	 *
-	 * @param nodeRef
-	 *            The noderef that defines the new peer
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public void addPeer(NodeRef nodeRef) throws IOException, FcpException {
-		addPeer(new AddPeer(nodeRef));
-	}
-
-	/**
-	 * Adds a peer, reading the noderef from the given URL.
-	 *
-	 * @param url
-	 *            The URL to read the noderef from
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public void addPeer(URL url) throws IOException, FcpException {
-		addPeer(new AddPeer(url));
-	}
-
-	/**
-	 * Adds a peer, reading the noderef of the peer from the given file.
-	 * <strong>Note:</strong> the file to read the noderef from has to reside on
-	 * the same machine as the node!
-	 *
-	 * @param file
-	 *            The name of the file containing the peer’s noderef
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public void addPeer(String file) throws IOException, FcpException {
-		addPeer(new AddPeer(file));
-	}
-
-	/**
-	 * Sends the given {@link AddPeer} message to the node. This method should
-	 * not be called directly. Use one of {@link #addPeer(Peer)},
-	 * {@link #addPeer(NodeRef)}, {@link #addPeer(URL)}, or
-	 * {@link #addPeer(String)} instead.
-	 *
-	 * @param addPeer
-	 *            The “AddPeer” message
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	private void addPeer(final AddPeer addPeer) throws IOException, FcpException {
-		new ExtendedFcpAdapter() {
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			@SuppressWarnings("synthetic-access")
-			public void run() throws IOException {
-				fcpConnection.sendMessage(addPeer);
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
-				completionLatch.countDown();
-			}
-		}.execute();
-	}
-
-	/**
-	 * Modifies the given peer.
-	 *
-	 * @param peer
-	 *            The peer to modify
-	 * @param allowLocalAddresses
-	 *            <code>true</code> to allow local address, <code>false</code>
-	 *            to not allow local address, <code>null</code> to not change
-	 *            the setting
-	 * @param disabled
-	 *            <code>true</code> to disable the peer, <code>false</code> to
-	 *            enable the peer, <code>null</code> to not change the setting
-	 * @param listenOnly
-	 *            <code>true</code> to enable “listen only” for the peer,
-	 *            <code>false</code> to disable it, <code>null</code> to not
-	 *            change it
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public void modifyPeer(final Peer peer, final Boolean allowLocalAddresses, final Boolean disabled, final Boolean listenOnly) throws IOException, FcpException {
-		new ExtendedFcpAdapter() {
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			@SuppressWarnings("synthetic-access")
-			public void run() throws IOException {
-				fcpConnection.sendMessage(new ModifyPeer(peer.getIdentity(), allowLocalAddresses, disabled, listenOnly));
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
-				completionLatch.countDown();
-			}
-		}.execute();
-	}
-
-	/**
-	 * Removes the given peer.
-	 *
-	 * @param peer
-	 *            The peer to remove
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public void removePeer(final Peer peer) throws IOException, FcpException {
-		new ExtendedFcpAdapter() {
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			@SuppressWarnings("synthetic-access")
-			public void run() throws IOException {
-				fcpConnection.sendMessage(new RemovePeer(peer.getIdentity()));
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			public void receivedPeerRemoved(FcpConnection fcpConnection, PeerRemoved peerRemoved) {
-				completionLatch.countDown();
-			}
-		}.execute();
-	}
-
-	//
-	// PEER NOTES MANAGEMENT
-	//
-
-	/**
-	 * Returns the peer note of the given peer.
-	 *
-	 * @param peer
-	 *            The peer to get the note for
-	 * @return The peer’s note
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public PeerNote getPeerNote(final Peer peer) throws IOException, FcpException {
-		final ObjectWrapper<PeerNote> objectWrapper = new ObjectWrapper<PeerNote>();
-		new ExtendedFcpAdapter() {
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			@SuppressWarnings("synthetic-access")
-			public void run() throws IOException {
-				fcpConnection.sendMessage(new ListPeerNotes(peer.getIdentity()));
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			public void receivedPeerNote(FcpConnection fcpConnection, PeerNote peerNote) {
-				if (peerNote.getNodeIdentifier().equals(peer.getIdentity())) {
-					objectWrapper.set(peerNote);
-				}
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			public void receivedEndListPeerNotes(FcpConnection fcpConnection, EndListPeerNotes endListPeerNotes) {
-				completionLatch.countDown();
-			}
-		}.execute();
-		return objectWrapper.get();
-	}
-
-	/**
-	 * Replaces the peer note for the given peer.
-	 *
-	 * @param peer
-	 *            The peer
-	 * @param noteText
-	 *            The new base64-encoded note text
-	 * @param noteType
-	 *            The type of the note (currently only <code>1</code> is
-	 *            allowed)
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public void modifyPeerNote(final Peer peer, final String noteText, final int noteType) throws IOException, FcpException {
-		new ExtendedFcpAdapter() {
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			@SuppressWarnings("synthetic-access")
-			public void run() throws IOException {
-				fcpConnection.sendMessage(new ModifyPeerNote(peer.getIdentity(), noteText, noteType));
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			public void receivedPeer(FcpConnection fcpConnection, Peer receivedPeer) {
-				if (receivedPeer.getIdentity().equals(peer.getIdentity())) {
-					completionLatch.countDown();
-				}
-			}
-		}.execute();
-	}
-
-	//
-	// KEY GENERATION
-	//
-
-	/**
-	 * Generates a new SSK key pair.
-	 *
-	 * @return The generated key pair
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public SSKKeypair generateKeyPair() throws IOException, FcpException {
-		final ObjectWrapper<SSKKeypair> sskKeypairWrapper = new ObjectWrapper<SSKKeypair>();
-		new ExtendedFcpAdapter() {
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			@SuppressWarnings("synthetic-access")
-			public void run() throws IOException {
-				fcpConnection.sendMessage(new GenerateSSK());
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair) {
-				sskKeypairWrapper.set(sskKeypair);
-				completionLatch.countDown();
-			}
-		}.execute();
-		return sskKeypairWrapper.get();
-	}
-
-	//
-	// REQUEST MANAGEMENT
-	//
-
-	/**
-	 * Returns all currently visible persistent get requests.
-	 *
-	 * @param global
-	 *            <code>true</code> to return get requests from the global
-	 *            queue, <code>false</code> to only show requests from the
-	 *            client-local queue
-	 * @return All get requests
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public Collection<Request> getGetRequests(final boolean global) throws IOException, FcpException {
-		return Filters.filteredCollection(getRequests(global), new Filter<Request>() {
-
-			/**
-			 * {@inheritDoc}
-			 */
-			public boolean filterObject(Request request) {
-				return request instanceof GetRequest;
-			}
-		});
-	}
-
-	/**
-	 * Returns all currently visible persistent put requests.
-	 *
-	 * @param global
-	 *            <code>true</code> to return put requests from the global
-	 *            queue, <code>false</code> to only show requests from the
-	 *            client-local queue
-	 * @return All put requests
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public Collection<Request> getPutRequests(final boolean global) throws IOException, FcpException {
-		return Filters.filteredCollection(getRequests(global), new Filter<Request>() {
-
-			/**
-			 * {@inheritDoc}
-			 */
-			public boolean filterObject(Request request) {
-				return request instanceof PutRequest;
-			}
-		});
-	}
-
-	/**
-	 * Returns all currently visible persistent requests.
-	 *
-	 * @param global
-	 *            <code>true</code> to return requests from the global queue,
-	 *            <code>false</code> to only show requests from the client-local
-	 *            queue
-	 * @return All requests
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public Collection<Request> getRequests(final boolean global) throws IOException, FcpException {
-		final Map<String, Request> requests = Collections.synchronizedMap(new HashMap<String, Request>());
-		new ExtendedFcpAdapter() {
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			@SuppressWarnings("synthetic-access")
-			public void run() throws IOException {
-				fcpConnection.sendMessage(new ListPersistentRequests());
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			public void receivedPersistentGet(FcpConnection fcpConnection, PersistentGet persistentGet) {
-				if (!persistentGet.isGlobal() || global) {
-					GetRequest getRequest = new GetRequest(persistentGet);
-					requests.put(persistentGet.getIdentifier(), getRequest);
-				}
-			}
-
-			/**
-			 * {@inheritDoc}
-			 *
-			 * @see net.pterodactylus.fcp.FcpAdapter#receivedDataFound(net.pterodactylus.fcp.FcpConnection,
-			 *      net.pterodactylus.fcp.DataFound)
-			 */
-			@Override
-			public void receivedDataFound(FcpConnection fcpConnection, DataFound dataFound) {
-				Request getRequest = requests.get(dataFound.getIdentifier());
-				if (getRequest == null) {
-					return;
-				}
-				getRequest.setComplete(true);
-				getRequest.setLength(dataFound.getDataLength());
-				getRequest.setContentType(dataFound.getMetadataContentType());
-			}
-
-			/**
-			 * {@inheritDoc}
-			 *
-			 * @see net.pterodactylus.fcp.FcpAdapter#receivedGetFailed(net.pterodactylus.fcp.FcpConnection,
-			 *      net.pterodactylus.fcp.GetFailed)
-			 */
-			@Override
-			public void receivedGetFailed(FcpConnection fcpConnection, GetFailed getFailed) {
-				Request getRequest = requests.get(getFailed.getIdentifier());
-				if (getRequest == null) {
-					return;
-				}
-				getRequest.setComplete(true);
-				getRequest.setFailed(true);
-				getRequest.setFatal(getFailed.isFatal());
-				getRequest.setErrorCode(getFailed.getCode());
-			}
-
-			/**
-			 * {@inheritDoc}
-			 *
-			 * @see net.pterodactylus.fcp.FcpAdapter#receivedPersistentPut(net.pterodactylus.fcp.FcpConnection,
-			 *      net.pterodactylus.fcp.PersistentPut)
-			 */
-			@Override
-			public void receivedPersistentPut(FcpConnection fcpConnection, PersistentPut persistentPut) {
-				if (!persistentPut.isGlobal() || global) {
-					PutRequest putRequest = new PutRequest(persistentPut);
-					requests.put(persistentPut.getIdentifier(), putRequest);
-				}
-			}
-
-			/**
-			 * {@inheritDoc}
-			 *
-			 * @see net.pterodactylus.fcp.FcpAdapter#receivedSimpleProgress(net.pterodactylus.fcp.FcpConnection,
-			 *      net.pterodactylus.fcp.SimpleProgress)
-			 */
-			@Override
-			public void receivedSimpleProgress(FcpConnection fcpConnection, SimpleProgress simpleProgress) {
-				Request request = requests.get(simpleProgress.getIdentifier());
-				if (request == null) {
-					return;
-				}
-				request.setTotalBlocks(simpleProgress.getTotal());
-				request.setRequiredBlocks(simpleProgress.getRequired());
-				request.setFailedBlocks(simpleProgress.getFailed());
-				request.setFatallyFailedBlocks(simpleProgress.getFatallyFailed());
-				request.setSucceededBlocks(simpleProgress.getSucceeded());
-				request.setFinalizedTotal(simpleProgress.isFinalizedTotal());
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			public void receivedEndListPersistentRequests(FcpConnection fcpConnection, EndListPersistentRequests endListPersistentRequests) {
-				completionLatch.countDown();
-			}
-		}.execute();
-		return requests.values();
-	}
-
-	/**
-	 * Sends a message to a plugin and waits for the response.
-	 *
-	 * @param pluginClass
-	 *            The name of the plugin class
-	 * @param parameters
-	 *            The parameters for the plugin
-	 * @return The responses from the plugin
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public Map<String, String> sendPluginMessage(String pluginClass, Map<String, String> parameters) throws IOException, FcpException {
-		return sendPluginMessage(pluginClass, parameters, 0, null);
-	}
-
-	/**
-	 * Sends a message to a plugin and waits for the response.
-	 *
-	 * @param pluginClass
-	 *            The name of the plugin class
-	 * @param parameters
-	 *            The parameters for the plugin
-	 * @param dataLength
-	 *            The length of the optional data stream, or {@code 0} if there
-	 *            is no optional data stream
-	 * @param dataInputStream
-	 *            The input stream for the payload, or {@code null} if there is
-	 *            no payload
-	 * @return The responses from the plugin
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public Map<String, String> sendPluginMessage(final String pluginClass, final Map<String, String> parameters, final long dataLength, final InputStream dataInputStream) throws IOException, FcpException {
-		final Map<String, String> pluginReplies = Collections.synchronizedMap(new HashMap<String, String>());
-		new ExtendedFcpAdapter() {
-
-			@SuppressWarnings("synthetic-access")
-			private final String identifier = createIdentifier("FCPPluginMessage");
-
-			@Override
-			@SuppressWarnings("synthetic-access")
-			public void run() throws IOException {
-				FCPPluginMessage fcpPluginMessage = new FCPPluginMessage(pluginClass);
-				for (Entry<String, String> parameter : parameters.entrySet()) {
-					fcpPluginMessage.setParameter(parameter.getKey(), parameter.getValue());
-				}
-				fcpPluginMessage.setIdentifier(identifier);
-				if ((dataLength > 0) && (dataInputStream != null)) {
-					fcpPluginMessage.setDataLength(dataLength);
-					fcpPluginMessage.setPayloadInputStream(dataInputStream);
-				}
-				fcpConnection.sendMessage(fcpPluginMessage);
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			public void receivedFCPPluginReply(FcpConnection fcpConnection, FCPPluginReply fcpPluginReply) {
-				if (!fcpPluginReply.getIdentifier().equals(identifier)) {
-					return;
-				}
-				pluginReplies.putAll(fcpPluginReply.getReplies());
-				completionLatch.countDown();
-			}
-
-		}.execute();
-		return pluginReplies;
-	}
-
-	//
-	// NODE INFORMATION
-	//
-
-	/**
-	 * Returns information about the node.
-	 *
-	 * @param giveOpennetRef
-	 *            Whether to return the OpenNet reference
-	 * @param withPrivate
-	 *            Whether to return private node data
-	 * @param withVolatile
-	 *            Whether to return volatile node data
-	 * @return Node information
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public NodeData getNodeInformation(final Boolean giveOpennetRef, final Boolean withPrivate, final Boolean withVolatile) throws IOException, FcpException {
-		final ObjectWrapper<NodeData> nodeDataWrapper = new ObjectWrapper<NodeData>();
-		new ExtendedFcpAdapter() {
-
-			@Override
-			@SuppressWarnings("synthetic-access")
-			public void run() throws IOException {
-				GetNode getNodeMessage = new GetNode(giveOpennetRef, withPrivate, withVolatile);
-				fcpConnection.sendMessage(getNodeMessage);
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			public void receivedNodeData(FcpConnection fcpConnection, NodeData nodeData) {
-				nodeDataWrapper.set(nodeData);
-				completionLatch.countDown();
-			}
-		}.execute();
-		return nodeDataWrapper.get();
-	}
-
-	//
-	// PRIVATE METHODS
-	//
-
-	/**
-	 * Creates a unique request identifier.
-	 *
-	 * @param basename
-	 *            The basename of the request
-	 * @return The created request identifier
-	 */
-	private String createIdentifier(String basename) {
-		return basename + "-" + System.currentTimeMillis() + "-" + (int) (Math.random() * Integer.MAX_VALUE);
-	}
-
-	/**
-	 * Checks whether the connection is in the required state.
-	 *
-	 * @param connected
-	 *            The required connection state
-	 * @throws FcpException
-	 *             if the connection is not in the required state
-	 */
-	private void checkConnected(boolean connected) throws FcpException {
-		if (this.connected != connected) {
-			throw new FcpException("Client is " + (connected ? "not" : "already") + " connected.");
-		}
-	}
-
-	/**
-	 * Tells the client that it is now disconnected. This method is called by
-	 * {@link ExtendedFcpAdapter} only.
-	 */
-	private void setDisconnected() {
-		connected = false;
-	}
-
-	/**
-	 * Implementation of an {@link FcpListener} that can store an
-	 * {@link FcpException} and wait for the arrival of a certain command.
-	 *
-	 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
-	 */
-	private abstract class ExtendedFcpAdapter extends FcpAdapter {
-
-		/** The count down latch used to wait for completion. */
-		protected final CountDownLatch completionLatch = new CountDownLatch(1);
-
-		/** The FCP exception, if any. */
-		protected FcpException fcpException;
-
-		/**
-		 * Creates a new extended FCP adapter.
-		 */
-		public ExtendedFcpAdapter() {
-			/* do nothing. */
-		}
-
-		/**
-		 * Executes the FCP commands in {@link #run()}, wrapping the execution
-		 * and catching exceptions.
-		 *
-		 * @throws IOException
-		 *             if an I/O error occurs
-		 * @throws FcpException
-		 *             if an FCP error occurs
-		 */
-		@SuppressWarnings("synthetic-access")
-		public void execute() throws IOException, FcpException {
-			checkConnected(true);
-			fcpConnection.addFcpListener(this);
-			try {
-				run();
-				while (true) {
-					try {
-						completionLatch.await();
-						break;
-					} catch (InterruptedException ie1) {
-						/* ignore, we’ll loop. */
-					}
-				}
-			} catch (IOException ioe1) {
-				setDisconnected();
-				throw ioe1;
-			} finally {
-				fcpConnection.removeFcpListener(this);
-			}
-			if (fcpException != null) {
-				setDisconnected();
-				throw fcpException;
-			}
-		}
-
-		/**
-		 * The FCP commands that actually get executed.
-		 *
-		 * @throws IOException
-		 *             if an I/O error occurs
-		 */
-		public abstract void run() throws IOException;
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public void connectionClosed(FcpConnection fcpConnection, Throwable throwable) {
-			fcpException = new FcpException("Connection closed", throwable);
-			completionLatch.countDown();
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public void receivedCloseConnectionDuplicateClientName(FcpConnection fcpConnection, CloseConnectionDuplicateClientName closeConnectionDuplicateClientName) {
-			fcpException = new FcpException("Connection closed, duplicate client name");
-			completionLatch.countDown();
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError) {
-			fcpException = new FcpException("Protocol error (" + protocolError.getCode() + ", " + protocolError.getCodeDescription());
-			completionLatch.countDown();
-		}
-
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/fcp/highlevel/FcpClientListener.java b/alien/src/net/pterodactylus/fcp/highlevel/FcpClientListener.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/fcp/highlevel/FcpClientListener.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * jFCPlib - FcpClientListener.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import java.util.EventListener;
-
-/**
- * Listener for {@link FcpClient} events.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public interface FcpClientListener extends EventListener {
-
-	/**
-	 * Notifies a listener that the given FCP client was disconnected.
-	 *
-	 * @param fcpClient
-	 *            The FCP client that was disconnected
-	 */
-	public void fcpClientDisconnected(FcpClient fcpClient);
-
-}
diff --git a/alien/src/net/pterodactylus/fcp/highlevel/FcpClientListenerManager.java b/alien/src/net/pterodactylus/fcp/highlevel/FcpClientListenerManager.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/fcp/highlevel/FcpClientListenerManager.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * jFCPlib - FcpClientListenerManager.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import net.pterodactylus.util.event.AbstractListenerManager;
-
-/**
- * Manages {@link FcpClientListener}s and fires events.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class FcpClientListenerManager extends AbstractListenerManager<FcpClient, FcpClientListener> {
-
-	/**
-	 * Creates a new FCP client listener manager.
-	 *
-	 * @param fcpClient
-	 *            The source FCP client
-	 */
-	public FcpClientListenerManager(FcpClient fcpClient) {
-		super(fcpClient);
-	}
-
-	/**
-	 * Notifies all listeners that the FCP client was disconnected.
-	 *
-	 * @see FcpClientListener#fcpClientDisconnected(FcpClient)
-	 */
-	public void fireFcpClientDisconnected() {
-		for (FcpClientListener fcpClientListener : getListeners()) {
-			fcpClientListener.fcpClientDisconnected(getSource());
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/fcp/highlevel/FcpException.java b/alien/src/net/pterodactylus/fcp/highlevel/FcpException.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/fcp/highlevel/FcpException.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * jFCPlib - FcpException.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-/**
- * Exception that signals an error in the FCP protocol.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class FcpException extends Exception {
-
-	/**
-	 * Creates a new FCP exception.
-	 */
-	public FcpException() {
-		super();
-	}
-
-	/**
-	 * Creates a new FCP exception.
-	 *
-	 * @param message
-	 *            The message of the exception
-	 */
-	public FcpException(String message) {
-		super(message);
-	}
-
-	/**
-	 * Creates a new FCP exception.
-	 *
-	 * @param cause
-	 *            The cause of the exception
-	 */
-	public FcpException(Throwable cause) {
-		super(cause);
-	}
-
-	/**
-	 * Creates a new FCP exception.
-	 *
-	 * @param message
-	 *            The message of the exception
-	 * @param cause
-	 *            The cause of the exception
-	 */
-	public FcpException(String message, Throwable cause) {
-		super(message, cause);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/fcp/highlevel/GetRequest.java b/alien/src/net/pterodactylus/fcp/highlevel/GetRequest.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/fcp/highlevel/GetRequest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * jFCPlib - GetRequest.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import net.pterodactylus.fcp.PersistentGet;
-
-/**
- * High-level wrapper around {@link PersistentGet}.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class GetRequest extends Request {
-
-	/**
-	 * Creates a new get request.
-	 *
-	 * @param persistentGet
-	 *            The persistent Get request to wrap
-	 */
-	GetRequest(PersistentGet persistentGet) {
-		super(persistentGet.getIdentifier(), persistentGet.getClientToken(), persistentGet.isGlobal());
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/fcp/highlevel/PutRequest.java b/alien/src/net/pterodactylus/fcp/highlevel/PutRequest.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/fcp/highlevel/PutRequest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * jFCPlib - PutRequest.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import net.pterodactylus.fcp.PersistentPut;
-
-/**
- * High-level wrapper around a {@link PersistentPut}.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class PutRequest extends Request {
-
-	/**
-	 * Creates a new put request.
-	 *
-	 * @param persistentPut
-	 *            The FCP message to wrap
-	 */
-	PutRequest(PersistentPut persistentPut) {
-		super(persistentPut.getIdentifier(), persistentPut.getClientToken(), persistentPut.isGlobal());
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/fcp/highlevel/Request.java b/alien/src/net/pterodactylus/fcp/highlevel/Request.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/fcp/highlevel/Request.java
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * jFCPlib - Request.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import net.pterodactylus.fcp.PersistentGet;
-import net.pterodactylus.fcp.PersistentPut;
-
-/**
- * Wrapper class around request responses from the node, such as
- * {@link PersistentGet} or {@link PersistentPut}.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public abstract class Request {
-
-	/** The identifier of the request. */
-	private final String identifier;
-
-	/** The client token of the request. */
-	private final String clientToken;
-
-	/** Whether the request is on the global queue. */
-	private final boolean global;
-
-	/** Whether the get request is complete. */
-	private boolean complete;
-
-	/** Whether the get request has failed. */
-	private boolean failed;
-
-	/** The data length. */
-	private long length;
-
-	/** The mime type. */
-	private String contentType;
-
-	/** The error code in case of failure. */
-	private int errorCode;
-
-	/** Whether the failure is fatal. */
-	private boolean fatal;
-
-	/** The total number of blocks. */
-	private int totalBlocks;
-
-	/** The required number of blocks. */
-	private int requiredBlocks;
-
-	/** The successfully processed number of blocks. */
-	private int succeededBlocks;
-
-	/** The number of failed blocks. */
-	private int failedBlocks;
-
-	/** The number of fatally failed blocks. */
-	private int fatallyFailedBlocks;
-
-	/** Whether the total number of blocks is finalized. */
-	private boolean finalizedTotal;
-
-	/**
-	 * Creates a new request with the given identifier and client token.
-	 *
-	 * @param identifier
-	 *            The identifier of the request
-	 * @param clientToken
-	 *            The client token of the request
-	 * @param global
-	 *            <code>true</code> if the request is on the global queue,
-	 *            <code>false</code> otherwise
-	 */
-	protected Request(String identifier, String clientToken, boolean global) {
-		this.identifier = identifier;
-		this.clientToken = clientToken;
-		this.global = global;
-	}
-
-	/**
-	 * Returns the identifier of the request.
-	 *
-	 * @return The request’s identifier
-	 */
-	public String getIdentifier() {
-		return identifier;
-	}
-
-	/**
-	 * Returns the client token of the request.
-	 *
-	 * @return The request’s client token
-	 */
-	public String getClientToken() {
-		return clientToken;
-	}
-
-	/**
-	 * Returns whether this request is on the global queue.
-	 *
-	 * @return <code>true</code> if the request is on the global queue,
-	 *         <code>false</code> otherwise
-	 */
-	public boolean isGlobal() {
-		return global;
-	}
-
-	/**
-	 * Returns whether this request is complete.
-	 *
-	 * @return <code>true</code> if this request is complete, false otherwise
-	 */
-	public boolean isComplete() {
-		return complete;
-	}
-
-	/**
-	 * Sets whether this request is complete.
-	 *
-	 * @param complete
-	 *            <code>true</code> if this request is complete, false otherwise
-	 */
-	void setComplete(boolean complete) {
-		this.complete = complete;
-	}
-
-	/**
-	 * Returns whether this request has failed. This method should only be
-	 * called if {@link #isComplete()} returns <code>true</code>.
-	 *
-	 * @return <code>true</code> if this request failed, <code>false</code>
-	 *         otherwise
-	 */
-	public boolean hasFailed() {
-		return failed;
-	}
-
-	/**
-	 * Sets whether this request has failed.
-	 *
-	 * @param failed
-	 *            <code>true</code> if this request failed, <code>false</code>
-	 *            otherwise
-	 */
-	void setFailed(boolean failed) {
-		this.failed = failed;
-	}
-
-	/**
-	 * Returns the length of the data.
-	 *
-	 * @return The length of the data
-	 */
-	public long getLength() {
-		return length;
-	}
-
-	/**
-	 * Sets the length of the data.
-	 *
-	 * @param length
-	 *            The length of the data
-	 */
-	void setLength(long length) {
-		this.length = length;
-	}
-
-	/**
-	 * Returns the content type of the data.
-	 *
-	 * @return The content type of the data
-	 */
-	public String getContentType() {
-		return contentType;
-	}
-
-	/**
-	 * Sets the content type of the data.
-	 *
-	 * @param contentType
-	 *            The content type of the data
-	 */
-	void setContentType(String contentType) {
-		this.contentType = contentType;
-	}
-
-	/**
-	 * Returns the error code. This method should only be called if
-	 * {@link #hasFailed()} returns <code>true</code>.
-	 *
-	 * @return The error code
-	 */
-	public int getErrorCode() {
-		return errorCode;
-	}
-
-	/**
-	 * Sets the error code.
-	 *
-	 * @param errorCode
-	 *            The error code
-	 */
-	void setErrorCode(int errorCode) {
-		this.errorCode = errorCode;
-	}
-
-	/**
-	 * Returns whether this request has fatally failed, i.e. repitition will not
-	 * cause the request to succeed.
-	 *
-	 * @return <code>true</code> if this request can not be made succeed by
-	 *         repeating, <code>false</code> otherwise
-	 */
-	public boolean isFatal() {
-		return fatal;
-	}
-
-	/**
-	 * Sets whether this request has fatally failed.
-	 *
-	 * @param fatal
-	 *            <code>true</code> if this request failed fatally,
-	 *            <code>false</code> otherwise
-	 */
-	void setFatal(boolean fatal) {
-		this.fatal = fatal;
-	}
-
-	/**
-	 * Returns the total number of blocks of this request.
-	 *
-	 * @return This request’s total number of blocks
-	 */
-	public int getTotalBlocks() {
-		return totalBlocks;
-	}
-
-	/**
-	 * Sets the total number of blocks of this request.
-	 *
-	 * @param totalBlocks
-	 *            This request’s total number of blocks
-	 */
-	void setTotalBlocks(int totalBlocks) {
-		this.totalBlocks = totalBlocks;
-	}
-
-	/**
-	 * Returns the number of required blocks. Any progress percentages should be
-	 * calculated against this value as 100%. Also, as long as
-	 * {@link #isFinalizedTotal()} returns {@code false} this value might
-	 * change.
-	 *
-	 * @return The number of required blocks
-	 */
-	public int getRequiredBlocks() {
-		return requiredBlocks;
-	}
-
-	/**
-	 * Sets the number of required blocks.
-	 *
-	 * @param requiredBlocks
-	 *            The number of required blocks
-	 */
-	void setRequiredBlocks(int requiredBlocks) {
-		this.requiredBlocks = requiredBlocks;
-	}
-
-	/**
-	 * Returns the number of succeeded blocks.
-	 *
-	 * @return The number of succeeded blocks
-	 */
-	public int getSucceededBlocks() {
-		return succeededBlocks;
-	}
-
-	/**
-	 * Sets the number of succeeded blocks.
-	 *
-	 * @param succeededBlocks
-	 *            The number of succeeded blocks
-	 */
-	void setSucceededBlocks(int succeededBlocks) {
-		this.succeededBlocks = succeededBlocks;
-	}
-
-	/**
-	 * Returns the number of failed blocks. These blocks may be retried untill
-	 * the maximum number of retries has been reached.
-	 *
-	 * @return The number of failed blocks
-	 */
-	public int getFailedBlocks() {
-		return failedBlocks;
-	}
-
-	/**
-	 * Sets the number of failed blocks.
-	 *
-	 * @param failedBlocks
-	 *            The number of failed blocks
-	 */
-	void setFailedBlocks(int failedBlocks) {
-		this.failedBlocks = failedBlocks;
-	}
-
-	/**
-	 * Returns the number of fatally failed blocks.
-	 *
-	 * @return The number of fatally failed blocks
-	 */
-	public int getFatallyFailedBlocks() {
-		return fatallyFailedBlocks;
-	}
-
-	/**
-	 * Sets the number of fatally failed blocks.
-	 *
-	 * @param fatallyFailedBlocks
-	 *            The number of fatally failed blocks
-	 */
-	void setFatallyFailedBlocks(int fatallyFailedBlocks) {
-		this.fatallyFailedBlocks = fatallyFailedBlocks;
-	}
-
-	/**
-	 * Returns whether the number of blocks has been finalized.
-	 *
-	 * @return {@code true} if the number of blocks is finalized, {@code false}
-	 *         otherwise
-	 */
-	public boolean isFinalizedTotal() {
-		return finalizedTotal;
-	}
-
-	/**
-	 * Sets whether the number of blocks has been finalized.
-	 *
-	 * @param finalizedTotal
-	 *            {@code true} if the number of blocks has been finalized,
-	 *            {@code false} otherwise
-	 */
-	void setFinalizedTotal(boolean finalizedTotal) {
-		this.finalizedTotal = finalizedTotal;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/fcp/plugin/WebOfTrustPlugin.java b/alien/src/net/pterodactylus/fcp/plugin/WebOfTrustPlugin.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/fcp/plugin/WebOfTrustPlugin.java
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
- * jFCPlib - WebOfTrustPlugin.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.plugin;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import net.pterodactylus.fcp.highlevel.FcpClient;
-import net.pterodactylus.fcp.highlevel.FcpException;
-
-/**
- * Simplifies handling of the web-of-trust plugin.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class WebOfTrustPlugin {
-
-	/** The FCP client to use. */
-	private final FcpClient fcpClient;
-
-	/**
-	 * Creates a new web-of-trust plugin wrapper around the given FCP client.
-	 *
-	 * @param fcpClient
-	 *            The FCP client to use for communication with the web-of-trust
-	 *            plugin
-	 */
-	public WebOfTrustPlugin(FcpClient fcpClient) {
-		this.fcpClient = fcpClient;
-	}
-
-	/**
-	 * Creates a new identity.
-	 *
-	 * @param nickname
-	 *            The nickname of the new identity
-	 * @param context
-	 *            The context for the new identity
-	 * @param publishTrustList
-	 *            {@code true} if the new identity should publish its trust list
-	 * @return The new identity
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public OwnIdentity createIdentity(String nickname, String context, boolean publishTrustList) throws IOException, FcpException {
-		return createIdentity(nickname, context, publishTrustList, null, null);
-	}
-
-	/**
-	 * Creates a new identity from the given request and insert URI.
-	 *
-	 * @param nickname
-	 *            The nickname of the new identity
-	 * @param context
-	 *            The context for the new identity
-	 * @param publishTrustList
-	 *            {@code true} if the new identity should publish its trust list
-	 * @param requestUri
-	 *            The request URI of the identity
-	 * @param insertUri
-	 *            The insert URI of the identity
-	 * @return The new identity
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public OwnIdentity createIdentity(String nickname, String context, boolean publishTrustList, String requestUri, String insertUri) throws IOException, FcpException {
-		Map<String, String> parameters = new HashMap<String, String>();
-		parameters.put("Message", "CreateIdentity");
-		parameters.put("Nickname", nickname);
-		parameters.put("Context", context);
-		parameters.put("PublishTrustList", String.valueOf(publishTrustList));
-		if ((requestUri != null) && (insertUri != null)) {
-			parameters.put("RequestURI", requestUri);
-			parameters.put("InsertURI", insertUri);
-		}
-		Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", parameters);
-		if (!replies.get("Message").equals("IdentityCreated")) {
-			throw new FcpException("WebOfTrust Plugin did not reply with “IdentityCreated” message!");
-		}
-		String identifier = replies.get("ID");
-		String newRequestUri = replies.get("RequestURI");
-		String newInsertUri = replies.get("InsertURI");
-		return new OwnIdentity(identifier, nickname, newRequestUri, newInsertUri);
-	}
-
-	/**
-	 * Returns all own identities of the web-of-trust plugins. Almost all other
-	 * commands require an {@link OwnIdentity} to return meaningful values.
-	 *
-	 * @return All own identities of the web-of-trust plugin
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public Set<OwnIdentity> getOwnIdentites() throws IOException, FcpException {
-		Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetOwnIdentities"));
-		if (!replies.get("Message").equals("OwnIdentities")) {
-			throw new FcpException("WebOfTrust Plugin did not reply with “OwnIdentities” message!");
-		}
-		Set<OwnIdentity> ownIdentities = new HashSet<OwnIdentity>();
-		for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
-			String identity = replies.get("Identity" + identityIndex);
-			String nickname = replies.get("Nickname" + identityIndex);
-			String requestUri = replies.get("RequestURI" + identityIndex);
-			String insertUri = replies.get("InsertURI" + identityIndex);
-			ownIdentities.add(new OwnIdentity(identity, nickname, requestUri, insertUri));
-		}
-		return ownIdentities;
-	}
-
-	/**
-	 * Returns the trust given to the identity with the given identifier by the
-	 * given own identity.
-	 *
-	 * @param ownIdentity
-	 *            The own identity that is used to calculate trust values
-	 * @param identifier
-	 *            The identifier of the identity whose trust to get
-	 * @return The request identity trust
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public CalculatedTrust getIdentityTrust(OwnIdentity ownIdentity, String identifier) throws IOException, FcpException {
-		Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetIdentity", "TreeOwner", ownIdentity.getIdentifier(), "Identity", identifier));
-		if (!replies.get("Message").equals("Identity")) {
-			throw new FcpException("WebOfTrust Plugin did not reply with “Identity” message!");
-		}
-		Byte trust = null;
-		try {
-			trust = Byte.valueOf(replies.get("Trust"));
-		} catch (NumberFormatException nfe1) {
-			/* ignore. */
-		}
-		Integer score = null;
-		try {
-			score = Integer.valueOf(replies.get("Score"));
-		} catch (NumberFormatException nfe1) {
-			/* ignore. */
-		}
-		Integer rank = null;
-		try {
-			rank = Integer.valueOf(replies.get("Rank"));
-		} catch (NumberFormatException nfe1) {
-			/* ignore. */
-		}
-		return new CalculatedTrust(trust, score, rank);
-	}
-
-	/**
-	 * Adds a new identity by its request URI.
-	 *
-	 * @param requestUri
-	 *            The request URI of the identity to add
-	 * @return The added identity
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public Identity addIdentity(String requestUri) throws IOException, FcpException {
-		Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "AddIdentity", "RequestURI", requestUri));
-		if (!replies.get("Message").equals("IdentityAdded")) {
-			throw new FcpException("WebOfTrust Plugin did not reply with “IdentityAdded” message!");
-		}
-		String identifier = replies.get("ID");
-		String nickname = replies.get("Nickname");
-		return new Identity(identifier, nickname, requestUri);
-	}
-
-	/**
-	 * Returns identities by the given score.
-	 *
-	 * @param ownIdentity
-	 *            The own identity
-	 * @param context
-	 *            The context to get the identities for
-	 * @param positive
-	 *            {@code null} to return neutrally trusted identities, {@code
-	 *            true} to return positively trusted identities, {@code false}
-	 *            for negatively trusted identities
-	 * @return The trusted identites
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public Set<Identity> getIdentitesByScore(OwnIdentity ownIdentity, String context, Boolean positive) throws IOException, FcpException {
-		Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetIdentitiesByScore", "TreeOwner", ownIdentity.getIdentifier(), "Context", context, "Selection", ((positive == null) ? "0" : (positive ? "+" : "-"))));
-		if (!replies.get("Message").equals("Identities")) {
-			throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
-		}
-		Set<Identity> identities = new HashSet<Identity>();
-		for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
-			String identifier = replies.get("Identity" + identityIndex);
-			String nickname = replies.get("Nickname" + identityIndex);
-			String requestUri = replies.get("RequestURI" + identityIndex);
-			identities.add(new Identity(identifier, nickname, requestUri));
-		}
-		return identities;
-	}
-
-	/**
-	 * Returns the identities that trust the given identity.
-	 *
-	 * @param identity
-	 *            The identity to get the trusters for
-	 * @param context
-	 *            The context to get the trusters for
-	 * @return The identities and their trust values
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public Map<Identity, IdentityTrust> getTrusters(Identity identity, String context) throws IOException, FcpException {
-		Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetTrusters", "Identity", identity.getIdentifier(), "Context", context));
-		if (!replies.get("Message").equals("Identities")) {
-			throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
-		}
-		Map<Identity, IdentityTrust> identityTrusts = new HashMap<Identity, IdentityTrust>();
-		for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
-			String identifier = replies.get("Identity" + identityIndex);
-			String nickname = replies.get("Nickname" + identityIndex);
-			String requestUri = replies.get("RequestURI" + identityIndex);
-			byte trust = Byte.parseByte(replies.get("Value" + identityIndex));
-			String comment = replies.get("Comment" + identityIndex);
-			identityTrusts.put(new Identity(identifier, nickname, requestUri), new IdentityTrust(trust, comment));
-		}
-		return identityTrusts;
-	}
-
-	/**
-	 * Returns the identities that given identity trusts.
-	 *
-	 * @param identity
-	 *            The identity to get the trustees for
-	 * @param context
-	 *            The context to get the trustees for
-	 * @return The identities and their trust values
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public Map<Identity, IdentityTrust> getTrustees(Identity identity, String context) throws IOException, FcpException {
-		Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetTrustees", "Identity", identity.getIdentifier(), "Context", context));
-		if (!replies.get("Message").equals("Identities")) {
-			throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
-		}
-		Map<Identity, IdentityTrust> identityTrusts = new HashMap<Identity, IdentityTrust>();
-		for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
-			String identifier = replies.get("Identity" + identityIndex);
-			String nickname = replies.get("Nickname" + identityIndex);
-			String requestUri = replies.get("RequestURI" + identityIndex);
-			byte trust = Byte.parseByte(replies.get("Value" + identityIndex));
-			String comment = replies.get("Comment" + identityIndex);
-			identityTrusts.put(new Identity(identifier, nickname, requestUri), new IdentityTrust(trust, comment));
-		}
-		return identityTrusts;
-	}
-
-	/**
-	 * Sets the trust given to the given identify by the given own identity.
-	 *
-	 * @param ownIdentity
-	 *            The identity that gives the trust
-	 * @param identity
-	 *            The identity that receives the trust
-	 * @param trust
-	 *            The trust value (ranging from {@code -100} to {@code 100}
-	 * @param comment
-	 *            The comment for setting the trust
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public void setTrust(OwnIdentity ownIdentity, Identity identity, byte trust, String comment) throws IOException, FcpException {
-		Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "SetTrust", "Truster", ownIdentity.getIdentifier(), "Trustee", identity.getIdentifier(), "Value", String.valueOf(trust), "Comment", comment));
-		if (!replies.get("Message").equals("TrustSet")) {
-			throw new FcpException("WebOfTrust Plugin did not reply with “TrustSet” message!");
-		}
-	}
-
-	/**
-	 * Adds the given context to the given identity.
-	 *
-	 * @param ownIdentity
-	 *            The identity to add the context to
-	 * @param context
-	 *            The context to add
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public void addContext(OwnIdentity ownIdentity, String context) throws IOException, FcpException {
-		Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "AddContext", "Identity", ownIdentity.getIdentifier(), "Context", context));
-		if (!replies.get("Message").equals("ContextAdded")) {
-			throw new FcpException("WebOfTrust Plugin did not reply with “ContextAdded” message!");
-		}
-	}
-
-	/**
-	 * Removes the given context from the given identity.
-	 *
-	 * @param ownIdentity
-	 *            The identity to remove the context from
-	 * @param context
-	 *            The context to remove
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public void removeContext(OwnIdentity ownIdentity, String context) throws IOException, FcpException {
-		Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "RemoveContext", "Identity", ownIdentity.getIdentifier(), "Context", context));
-		if (!replies.get("Message").equals("ContextRemoved")) {
-			throw new FcpException("WebOfTrust Plugin did not reply with “ContextRemoved” message!");
-		}
-	}
-
-	/**
-	 * Sets the given property for the given identity.
-	 *
-	 * @param ownIdentity
-	 *            The identity to set a property for
-	 * @param property
-	 *            The name of the property to set
-	 * @param value
-	 *            The value of the property to set
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public void setProperty(OwnIdentity ownIdentity, String property, String value) throws IOException, FcpException {
-		Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "SetProperty", "Identity", ownIdentity.getIdentifier(), "Property", property, "Value", value));
-		if (!replies.get("Message").equals("PropertyAdded")) {
-			throw new FcpException("WebOfTrust Plugin did not reply with “PropertyAdded” message!");
-		}
-	}
-
-	/**
-	 * Returns the value of the given property for the given identity.
-	 *
-	 * @param ownIdentity
-	 *            The identity to get a property for
-	 * @param property
-	 *            The name of the property to get
-	 * @return The value of the property
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public String getProperty(OwnIdentity ownIdentity, String property) throws IOException, FcpException {
-		Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetProperty", "Identity", ownIdentity.getIdentifier(), "Property", property));
-		if (!replies.get("Message").equals("PropertyValue")) {
-			throw new FcpException("WebOfTrust Plugin did not reply with “PropertyValue” message!");
-		}
-		return replies.get("Property");
-	}
-
-	/**
-	 * Removes the given property from the given identity.
-	 *
-	 * @param ownIdentity
-	 *            The identity to remove a property from
-	 * @param property
-	 *            The name of the property to remove
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 * @throws FcpException
-	 *             if an FCP error occurs
-	 */
-	public void removeProperty(OwnIdentity ownIdentity, String property) throws IOException, FcpException {
-		Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "RemoveProperty", "Identity", ownIdentity.getIdentifier(), "Property", property));
-		if (!replies.get("Message").equals("PropertyRemoved")) {
-			throw new FcpException("WebOfTrust Plugin did not reply with “PropertyRemoved” message!");
-		}
-	}
-
-	//
-	// PRIVATE METHODS
-	//
-
-	/**
-	 * Creates a map from each pair of parameters in the given array.
-	 *
-	 * @param parameters
-	 *            The array of parameters
-	 * @return The map created from the array
-	 * @throws ArrayIndexOutOfBoundsException
-	 *             if the given parameter array does not contains an even number
-	 *             of elements
-	 */
-	private Map<String, String> createParameters(String... parameters) throws ArrayIndexOutOfBoundsException {
-		Map<String, String> parameterMap = new HashMap<String, String>();
-		for (int index = 0; index < parameters.length; index += 2) {
-			parameterMap.put(parameters[index], parameters[index + 1]);
-		}
-		return parameterMap;
-	}
-
-	/**
-	 * Wrapper around a web-of-trust identity.
-	 *
-	 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
-	 */
-	public static class Identity {
-
-		/** The identity’s identifier. */
-		private final String identifier;
-
-		/** The identity’s nickname. */
-		private final String nickname;
-
-		/** The identity’s request URI. */
-		private final String requestUri;
-
-		/**
-		 * Creates a new identity.
-		 *
-		 * @param identifier
-		 *            The identifies of the identity
-		 * @param nickname
-		 *            The nickname of the identity
-		 * @param requestUri
-		 *            The request URI of the identity
-		 */
-		public Identity(String identifier, String nickname, String requestUri) {
-			this.identifier = identifier;
-			this.nickname = nickname;
-			this.requestUri = requestUri;
-		}
-
-		/**
-		 * Returns the identifier of this identity.
-		 *
-		 * @return This identity’s identifier
-		 */
-		public String getIdentifier() {
-			return identifier;
-		}
-
-		/**
-		 * Returns the nickname of this identity.
-		 *
-		 * @return This identity’s nickname
-		 */
-		public String getNickname() {
-			return nickname;
-		}
-
-		/**
-		 * Returns the request URI of this identity.
-		 *
-		 * @return This identity’s request URI
-		 */
-		public String getRequestUri() {
-			return requestUri;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public boolean equals(Object obj) {
-			if ((obj == null) || (obj.getClass() != this.getClass())) {
-				return false;
-			}
-			Identity identity = (Identity) obj;
-			return identifier.equals(identity.identifier);
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public int hashCode() {
-			return identifier.hashCode();
-		}
-
-	}
-
-	/**
-	 * Container for the trust given from one identity to another.
-	 *
-	 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
-	 */
-	public static class IdentityTrust {
-
-		/** The trust given to the identity. */
-		private final byte trust;
-
-		/** The command for the trust value. */
-		private final String comment;
-
-		/**
-		 * Creates a new identity trust container.
-		 *
-		 * @param trust
-		 *            The trust given to the identity
-		 * @param comment
-		 *            The comment for the trust value
-		 */
-		public IdentityTrust(byte trust, String comment) {
-			this.trust = trust;
-			this.comment = comment;
-		}
-
-		/**
-		 * Returns the trust value given to the identity.
-		 *
-		 * @return The trust value
-		 */
-		public byte getTrust() {
-			return trust;
-		}
-
-		/**
-		 * Returns the comment for the trust value.
-		 *
-		 * @return The comment for the trust value
-		 */
-		public String getComment() {
-			return comment;
-		}
-
-	}
-
-	/**
-	 * Container that stores the trust that is calculated by taking all trustees
-	 * and their trust lists into account.
-	 *
-	 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
-	 */
-	public static class CalculatedTrust {
-
-		/** The calculated trust value. */
-		private final Byte trust;
-
-		/** The calculated score value. */
-		private final Integer score;
-
-		/** The calculated rank. */
-		private final Integer rank;
-
-		/**
-		 * Creates a new calculated trust container.
-		 *
-		 * @param trust
-		 *            The calculated trust value
-		 * @param score
-		 *            The calculated score value
-		 * @param rank
-		 *            The calculated rank of the
-		 */
-		public CalculatedTrust(Byte trust, Integer score, Integer rank) {
-			this.trust = trust;
-			this.score = score;
-			this.rank = rank;
-		}
-
-		/**
-		 * Returns the calculated trust value.
-		 *
-		 * @return The calculated trust value, or {@code null} if the trust
-		 *         value is not known
-		 */
-		public Byte getTrust() {
-			return trust;
-		}
-
-		/**
-		 * Returns the calculated score value.
-		 *
-		 * @return The calculated score value, or {@code null} if the score
-		 *         value is not known
-		 */
-		public Integer getScore() {
-			return score;
-		}
-
-		/**
-		 * Returns the calculated rank.
-		 *
-		 * @return The calculated rank, or {@code null} if the rank is not known
-		 */
-		public Integer getRank() {
-			return rank;
-		}
-
-	}
-
-	/**
-	 * Wrapper around a web-of-trust own identity.
-	 *
-	 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
-	 */
-	public static class OwnIdentity extends Identity {
-
-		/** The identity’s insert URI. */
-		private final String insertUri;
-
-		/**
-		 * Creates a new web-of-trust own identity.
-		 *
-		 * @param identifier
-		 *            The identifier of the identity
-		 * @param nickname
-		 *            The nickname of the identity
-		 * @param requestUri
-		 *            The request URI of the identity
-		 * @param insertUri
-		 *            The insert URI of the identity
-		 */
-		public OwnIdentity(String identifier, String nickname, String requestUri, String insertUri) {
-			super(identifier, nickname, requestUri);
-			this.insertUri = insertUri;
-		}
-
-		/**
-		 * Returns the insert URI of this identity.
-		 *
-		 * @return This identity’s insert URI
-		 */
-		public String getInsertUri() {
-			return insertUri;
-		}
-
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/beans/AbstractBean.java b/alien/src/net/pterodactylus/util/beans/AbstractBean.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/beans/AbstractBean.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * utils - AbstractBean.java - Copyright © 2008-2010 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.util.beans;
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Abstract bean super class that contains property change listener management.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public abstract class AbstractBean {
-
-	/** Property change listeners. */
-	private final List<PropertyChangeListener> propertyChangeListeners = Collections.synchronizedList(new ArrayList<PropertyChangeListener>());
-
-	/**
-	 * Adds a property change listener.
-	 *
-	 * @param propertyChangeListener
-	 *            The property change listener to add
-	 */
-	public void addPropertyChangeListener(PropertyChangeListener propertyChangeListener) {
-		propertyChangeListeners.add(propertyChangeListener);
-	}
-
-	/**
-	 * Removes a property change listener.
-	 *
-	 * @param propertyChangeListener
-	 *            The property change listener to remove
-	 */
-	public void removePropertyChangeListener(PropertyChangeListener propertyChangeListener) {
-		propertyChangeListeners.remove(propertyChangeListener);
-	}
-
-	/**
-	 * Notifies all listeners that a property has changed.
-	 *
-	 * @param property
-	 *            The name of the property
-	 * @param oldValue
-	 *            The old value of the property
-	 * @param newValue
-	 *            The new value of the property
-	 */
-	protected void firePropertyChange(String property, Object oldValue, Object newValue) {
-		PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(this, property, oldValue, newValue);
-		for (PropertyChangeListener propertyChangeListener : propertyChangeListeners) {
-			propertyChangeListener.propertyChange(propertyChangeEvent);
-		}
-
-	}
-
-	/**
-	 * Fires a property change event if the two values are not equal.
-	 *
-	 * @param propertyName
-	 *            The name of the property
-	 * @param oldValue
-	 *            The old value of the property
-	 * @param newValue
-	 *            The new value of the property
-	 */
-	protected void fireIfPropertyChanged(String propertyName, Object oldValue, Object newValue) {
-		if (!equal(oldValue, newValue)) {
-			firePropertyChange(propertyName, oldValue, newValue);
-		}
-	}
-
-	//
-	// PRIVATE METHODS
-	//
-
-	/**
-	 * Compares the two objects and returns whether they are equal according to
-	 * {@link Object#equals(Object)}. This method takes <code>null</code>
-	 * into account as a valid value for an object.
-	 *
-	 * @param first
-	 *            The first object
-	 * @param second
-	 *            The second object
-	 * @return <code>true</code> if the two objects are equal,
-	 *         <code>false</code> otherwise
-	 */
-	private boolean equal(Object first, Object second) {
-		return ((first == null) && (second == null)) || ((first != null) && first.equals(second)) || second.equals(first);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/cache/AbstractCache.java b/alien/src/net/pterodactylus/util/cache/AbstractCache.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/cache/AbstractCache.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * utils - AbstractCache.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.cache;
-
-/**
- * Abstract base implementation of a {@link Cache}. All implementations should
- * extend this base class.
- *
- * @param <K>
- *            The type of the key
- * @param <V>
- *            The value of the key
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public abstract class AbstractCache<K, V> implements Cache<K, V> {
-
-	/** The value retriever. */
-	private final ValueRetriever<K, V> valueRetriever;
-
-	/**
-	 * Creates a new abstract cache.
-	 *
-	 * @param valueRetriever
-	 *            The value retriever
-	 */
-	protected AbstractCache(ValueRetriever<K, V> valueRetriever) {
-		this.valueRetriever = valueRetriever;
-	}
-
-	/**
-	 * Retrieves a value from the value retriever.
-	 *
-	 * @param key
-	 *            The key of the value to retrieve
-	 * @return The value of the key, or {@code null} if there is no value
-	 * @throws CacheException
-	 *             if an error occurs retrieving the value
-	 */
-	protected CacheItem<V> retrieveValue(K key) throws CacheException {
-		return valueRetriever.retrieve(key);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/cache/Cache.java b/alien/src/net/pterodactylus/util/cache/Cache.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/cache/Cache.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * utils - Cache.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.cache;
-
-import java.util.WeakHashMap;
-
-/**
- * Interface for caches with different strategies.
- *
- * @param <K>
- *            The type of the key
- * @param <V>
- *            The type of the value
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface Cache<K, V> {
-
-	/**
-	 * Checks whether this cache contains a value for the given key. No query to
-	 * the underlying {@link ValueRetriever} will be made! Note that it is legal
-	 * for this method to return {@code true} but for a following
-	 * {@link #get(Object)} to return {@code null} (see {@link WeakHashMap}) for
-	 * a possible explanation).
-	 *
-	 * @param key
-	 *            The key to check for
-	 * @return {@code true} if this cache contains a value for the given key,
-	 *         {@code false} otherwise
-	 */
-	public boolean contains(K key);
-
-	/**
-	 * Returns a value from the cache. If this cache does not contain a value
-	 * for the given key, the underlying {@link ValueRetriever} is asked to
-	 * retrieve the value. This operation may result in a {@link CacheException}
-	 * to be thrown. The returned value is cached if it is non-{@code null}.
-	 *
-	 * @param key
-	 *            The key to get the value for
-	 * @return The value of the key, or {@code null} if there is no value for
-	 *         the key
-	 * @throws CacheException
-	 *             if an error occurs retrieving the value from the underlying
-	 *             {@link ValueRetriever}
-	 */
-	public V get(K key) throws CacheException;
-
-	/**
-	 * Removes all cached values. For non-memory based caches this operation may
-	 * be slow.
-	 */
-	public void clear();
-
-	/**
-	 * Returns the number of currently cached values. For non-memory based
-	 * caches this operation may be slow.
-	 *
-	 * @return The number of cached values
-	 */
-	public int size();
-
-}
diff --git a/alien/src/net/pterodactylus/util/cache/CacheException.java b/alien/src/net/pterodactylus/util/cache/CacheException.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/cache/CacheException.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * utils - CacheException.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.cache;
-
-/**
- * Exception that signals an error in cache management.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class CacheException extends Exception {
-
-	/**
-	 * Creates a new cache exception.
-	 */
-	public CacheException() {
-		super();
-	}
-
-	/**
-	 * Creates a new cache exception.
-	 *
-	 * @param message
-	 *            The message of the exception
-	 */
-	public CacheException(String message) {
-		super(message);
-	}
-
-	/**
-	 * Creates a new cache exception.
-	 *
-	 * @param cause
-	 *            The cause of the exception
-	 */
-	public CacheException(Throwable cause) {
-		super(cause);
-	}
-
-	/**
-	 * Creates a new cache exception.
-	 *
-	 * @param message
-	 *            The message of the exception
-	 * @param cause
-	 *            The cause of the exception
-	 */
-	public CacheException(String message, Throwable cause) {
-		super(message, cause);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/cache/CacheItem.java b/alien/src/net/pterodactylus/util/cache/CacheItem.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/cache/CacheItem.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * utils - CacheItem.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.cache;
-
-/**
- * Wrapper interface for cached items.
- *
- * @param <V>
- *            The type of the value
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface CacheItem<V> {
-
-	/**
-	 * Returns the wrapped item.
-	 *
-	 * @return The wrapped item
-	 */
-	public V getItem();
-
-	/**
-	 * Notifies the item that it is removed from the cache and can free any
-	 * resources it uses.
-	 */
-	public void remove();
-
-}
diff --git a/alien/src/net/pterodactylus/util/cache/DefaultCacheItem.java b/alien/src/net/pterodactylus/util/cache/DefaultCacheItem.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/cache/DefaultCacheItem.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * utils - DefaultCacheItem.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.cache;
-
-/**
- * Default implementation of a {@link CacheItem} that simply stores a value and
- * does nothing when {@link CacheItem#remove()} is called.
- *
- * @param <V>
- *            The type of the item to store
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class DefaultCacheItem<V> implements CacheItem<V> {
-
-	/** The item to store. */
-	private final V item;
-
-	/**
-	 * Creates a new cache item.
-	 *
-	 * @param item
-	 *            The item to store
-	 */
-	public DefaultCacheItem(V item) {
-		this.item = item;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public V getItem() {
-		return item;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void remove() {
-		/* does nothing. */
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/cache/MemoryCache.java b/alien/src/net/pterodactylus/util/cache/MemoryCache.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/cache/MemoryCache.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * utils - MemoryCache.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.cache;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import net.pterodactylus.util.logging.Logging;
-
-/**
- * Memory-based {@link Cache} implementation.
- *
- * @param <K>
- *            The type of the key
- * @param <V>
- *            The type of the value
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class MemoryCache<K, V> extends AbstractCache<K, V> {
-
-	/** The logger. */
-	private static Logger logger = Logging.getLogger(MemoryCache.class.getName());
-
-	/** The number of values to cache. */
-	private volatile int cacheSize;
-
-	/** The cache for the values. */
-	private final Map<K, CacheItem<V>> cachedValues = new LinkedHashMap<K, CacheItem<V>>() {
-
-		/**
-		 * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry)
-		 */
-		@Override
-		@SuppressWarnings("synthetic-access")
-		protected boolean removeEldestEntry(Map.Entry<K, CacheItem<V>> eldest) {
-			if (super.size() > cacheSize) {
-				eldest.getValue().remove();
-				return true;
-			}
-			return false;
-		}
-	};
-
-	/** The lock for cache accesses. */
-	private final ReadWriteLock cacheLock = new ReentrantReadWriteLock();
-
-	/**
-	 * Creates a new memory-based cache.
-	 *
-	 * @param valueRetriever
-	 *            The value retriever
-	 */
-	public MemoryCache(ValueRetriever<K, V> valueRetriever) {
-		this(valueRetriever, 50);
-	}
-
-	/**
-	 * Creates a new memory-based cache.
-	 *
-	 * @param valueRetriever
-	 *            The value retriever
-	 * @param cacheSize
-	 *            The number of values to cache
-	 */
-	public MemoryCache(ValueRetriever<K, V> valueRetriever, int cacheSize) {
-		super(valueRetriever);
-		this.cacheSize = cacheSize;
-	}
-
-	/**
-	 * Sets the logger to use.
-	 *
-	 * @param logger
-	 *            The logger to use
-	 */
-	public static void setLogger(Logger logger) {
-		MemoryCache.logger = logger;
-	}
-
-	/**
-	 * @see net.pterodactylus.util.cache.Cache#clear()
-	 */
-	@Override
-	public void clear() {
-		cacheLock.writeLock().lock();
-		try {
-			cachedValues.clear();
-		} finally {
-			cacheLock.writeLock().unlock();
-		}
-	}
-
-	/**
-	 * @see net.pterodactylus.util.cache.Cache#contains(java.lang.Object)
-	 */
-	@Override
-	public boolean contains(K key) {
-		cacheLock.readLock().lock();
-		try {
-			return cachedValues.containsKey(key);
-		} finally {
-			cacheLock.readLock().unlock();
-		}
-	}
-
-	/**
-	 * @see net.pterodactylus.util.cache.Cache#get(java.lang.Object)
-	 */
-	@Override
-	public V get(K key) throws CacheException {
-		cacheLock.readLock().lock();
-		try {
-			if (cachedValues.containsKey(key)) {
-				logger.log(Level.FINE, "Value for Key “%1$s” is in cache.", key);
-				return cachedValues.get(key).getItem();
-			}
-			logger.log(Level.INFO, "Retrieving Value for Key “%1$s”...", key);
-			CacheItem<V> value = retrieveValue(key);
-			if (value != null) {
-				cacheLock.readLock().unlock();
-				cacheLock.writeLock().lock();
-				try {
-					cachedValues.put(key, value);
-				} finally {
-					cacheLock.readLock().lock();
-					cacheLock.writeLock().unlock();
-				}
-			}
-			return (value != null) ? value.getItem() : null;
-		} finally {
-			cacheLock.readLock().unlock();
-			logger.log(Level.FINE, "Retrieved Value for Key “%1$s”.", key);
-		}
-	}
-
-	/**
-	 * @see net.pterodactylus.util.cache.Cache#size()
-	 */
-	@Override
-	public int size() {
-		cacheLock.readLock().lock();
-		try {
-			return cachedValues.size();
-		} finally {
-			cacheLock.readLock().unlock();
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/cache/ValueRetriever.java b/alien/src/net/pterodactylus/util/cache/ValueRetriever.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/cache/ValueRetriever.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * utils - ValueRetriever.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.cache;
-
-/**
- * Interface for objects that can fill a {@link Cache} from arbitrary sources.
- *
- * @param <K>
- *            The type of the key
- * @param <V>
- *            The type of the value
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface ValueRetriever<K, V> {
-
-	/**
-	 * Retrieves the value for the given key.
-	 *
-	 * @param key
-	 *            The key to retrieve the value for
-	 * @return The value of the key, or {@code null} if there is no value
-	 * @throws CacheException
-	 *             if an error occurs retrieving the value
-	 */
-	public CacheItem<V> retrieve(K key) throws CacheException;
-
-}
diff --git a/alien/src/net/pterodactylus/util/cmdline/CommandLine.java b/alien/src/net/pterodactylus/util/cmdline/CommandLine.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/cmdline/CommandLine.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * utils - CommandLine.java - Copyright © 2008-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.cmdline;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import net.pterodactylus.util.validation.Validation;
-
-/**
- * Command-line parser.
- * <p>
- * This parser parses a {@link String} array containing the command-line
- * parameters into options as defined by
- * {@link #CommandLine(String[], Option...)}. Include code like the following in
- * your main startup method:
- *
- * <pre>
- * List<Option> options = new ArrayList<Option>();
- * options.add(new Option('h', "help"));
- * options.add(new Option('C', "config-file", true));
- * CommandLine commandLine = new CommandLine(arguments, options);
- * </pre>
- *
- * After the command-line has been parsed successfully, querying it is quite
- * simple:
- *
- * <pre>
- * if (commandLine.getOption("h").isPresent()) {
- * 	showHelp();
- * 	return;
- * }
- * if (commandLine.getOption("C").isPresent()) {
- * 	String configFile = commandLine.getOption("C").getValue();
- * }
- * </pre>
- *
- * Additional arguments on the command line can be queried via the
- * {@link #getArguments()} method. A line like
- * <code>program -C config.txt file1.txt file2.txt</code> with the constructor
- * from above and the code below would result in the output below the code:
- *
- * <pre>
- * for (String argument : commandLine.getArguments()) {
- * 	System.out.println(argument);
- * }
- * </pre>
- *
- * Output:
- *
- * <pre>
- * file1.txt
- * file2.txt
- * </pre>
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class CommandLine {
-
-	/** Mapping from short names to options. */
-	private final Map<Character, Option> shortNameOptions = new HashMap<Character, Option>();
-
-	/** Mapping from long names to options. */
-	private final Map<String, Option> longNameOptions = new HashMap<String, Option>();
-
-	/** The remaining arguments. */
-	private List<String> arguments = new ArrayList<String>();
-
-	/**
-	 * Creates a new command line and parses the given command-line arguments
-	 * according to the given options.
-	 *
-	 * @param commandLineArguments
-	 *            The command-line arguments
-	 * @param options
-	 *            The options
-	 * @throws CommandLineException
-	 *             if a command-line argument could not be parsed
-	 */
-	public CommandLine(String[] commandLineArguments, Collection<Option> options) throws CommandLineException {
-		this(commandLineArguments, options.toArray(new Option[options.size()]));
-	}
-
-	/**
-	 * Creates a new command line and parses the given command-line arguments
-	 * according to the given options.
-	 *
-	 * @param commandLineArguments
-	 *            The command-line arguments
-	 * @param options
-	 *            The options
-	 * @throws CommandLineException
-	 *             if a command-line argument could not be parsed
-	 */
-	public CommandLine(String[] commandLineArguments, Option... options) throws CommandLineException {
-		Validation.begin().isNotNull("commandLineArguments", commandLineArguments).check();
-		for (Option option : options) {
-			/* TODO - sanity checks */
-			if (option.getShortName() != 0) {
-				shortNameOptions.put(option.getShortName(), option);
-			}
-			if (option.getLongName() != null) {
-				longNameOptions.put(option.getLongName(), option);
-			}
-		}
-		int argumentCount = commandLineArguments.length;
-		boolean argumentsOnly = false;
-		List<Option> optionsNeedingParameters = new ArrayList<Option>();
-		for (int argumentIndex = 0; argumentIndex < argumentCount; argumentIndex++) {
-			String argument = commandLineArguments[argumentIndex];
-			if (!optionsNeedingParameters.isEmpty()) {
-				Option option = optionsNeedingParameters.remove(0);
-				option.setValue(argument);
-				continue;
-			}
-			if (argumentsOnly) {
-				arguments.add(argument);
-				continue;
-			}
-			if ("--".equals(argument)) {
-				argumentsOnly = true;
-				continue;
-			}
-			if (argument.startsWith("--")) {
-				String longName = argument.substring(2);
-				Option option = longNameOptions.get(longName);
-				if (option == null) {
-					throw new CommandLineException("unknown long name: " + longName);
-				}
-				if (option.needsParameter()) {
-					int equals = longName.indexOf('=');
-					if (equals == -1) {
-						optionsNeedingParameters.add(option);
-					} else {
-						option.setValue(longName.substring(equals + 1));
-					}
-				}
-				option.incrementCounter();
-				continue;
-			}
-			if (argument.startsWith("-")) {
-				String optionChars = argument.substring(1);
-				for (char optionChar : optionChars.toCharArray()) {
-					Option option = shortNameOptions.get(optionChar);
-					if (option == null) {
-						throw new CommandLineException("unknown short name: " + optionChar);
-					}
-					if (option.needsParameter()) {
-						optionsNeedingParameters.add(option);
-					}
-					option.incrementCounter();
-				}
-				continue;
-			}
-			arguments.add(argument);
-		}
-		if (!optionsNeedingParameters.isEmpty()) {
-			throw new CommandLineException("missing value for option " + optionsNeedingParameters.get(0));
-		}
-	}
-
-	/**
-	 * Returns the option with the given name. If there is no option with the
-	 * given short name, <code>null</code> is returned.
-	 *
-	 * @param name
-	 *            The short name of the option
-	 * @return The option, or <code>null</code> if no option could be found
-	 */
-	public Option getOption(char name) {
-		return shortNameOptions.get(name);
-	}
-
-	/**
-	 * Returns the option with the given name. If the name is longer than one
-	 * character and matches an option’s long name, that option is returned. If
-	 * the name is exactly one character long and matches an option’s short
-	 * name, that options is returned. Otherwise <code>null</code> is returned.
-	 *
-	 * @param name
-	 *            The long or short name of the option
-	 * @return The option, or <code>null</code> if no option could be found
-	 */
-	public Option getOption(String name) {
-		Validation.begin().isNotNull("name", name).check();
-		if ((name.length() > 1) && longNameOptions.containsKey(name)) {
-			return longNameOptions.get(name);
-		}
-		if ((name.length() == 1) && (shortNameOptions.containsKey(name.charAt(0)))) {
-			return shortNameOptions.get(name.charAt(0));
-		}
-		return null;
-	}
-
-	/**
-	 * Returns all remaining arguments from the original command-line arguments.
-	 *
-	 * @return The remaining arguments
-	 */
-	public String[] getArguments() {
-		return arguments.toArray(new String[arguments.size()]);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/cmdline/CommandLineException.java b/alien/src/net/pterodactylus/util/cmdline/CommandLineException.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/cmdline/CommandLineException.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * utils - CommandLineException.java - Copyright © 2008-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.cmdline;
-
-/**
- * Exception that signals an error in command-line argument parsing.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class CommandLineException extends Exception {
-
-	/**
-	 * Creates a new command-line exception.
-	 */
-	public CommandLineException() {
-		super();
-	}
-
-	/**
-	 * Creates a new command-line exception with the given message.
-	 *
-	 * @param message
-	 *            The message of the exception
-	 */
-	public CommandLineException(String message) {
-		super(message);
-	}
-
-	/**
-	 * Creates a new command-line exception with the given cause.
-	 *
-	 * @param cause
-	 *            The cause of the exception
-	 */
-	public CommandLineException(Throwable cause) {
-		super(cause);
-	}
-
-	/**
-	 * Creates a new command-line exception with the given message and cause.
-	 *
-	 * @param message
-	 *            The message of the exception
-	 * @param cause
-	 *            The cause of the exception
-	 */
-	public CommandLineException(String message, Throwable cause) {
-		super(message, cause);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/cmdline/Option.java b/alien/src/net/pterodactylus/util/cmdline/Option.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/cmdline/Option.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * utils - Option.java - Copyright © 2008-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.cmdline;
-
-/**
- * Container for {@link CommandLine} options and their values.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Option {
-
-	/** The short name. */
-	private final char shortName;
-
-	/** The long name. */
-	private final String longName;
-
-	/** Whether the option needs a parameter. */
-	private final boolean needsParameter;
-
-	/** The value of the parameter. */
-	private String value;
-
-	/** The option counter. */
-	private int counter;
-
-	/**
-	 * Creates a new option that does not require a parameter.
-	 *
-	 * @param shortName
-	 *            The short name of the option (may be <code>\u0000</code>)
-	 * @param longName
-	 *            The long name of the option (may be <code>null</code>)
-	 */
-	public Option(char shortName, String longName) {
-		this(shortName, longName, false);
-	}
-
-	/**
-	 * Creates a new option.
-	 *
-	 * @param shortName
-	 *            The short name of the option (may be <code>\u0000</code>)
-	 * @param longName
-	 *            The long name of the option (may be <code>null</code>)
-	 * @param needsParameter
-	 *            <code>true</code> if the option requires a parameter,
-	 *            <code>false</code> otherwise
-	 */
-	public Option(char shortName, String longName, boolean needsParameter) {
-		this.shortName = shortName;
-		this.longName = longName;
-		this.needsParameter = needsParameter;
-	}
-
-	/**
-	 * Returns the short name of the option.
-	 *
-	 * @return The short name of the option
-	 */
-	public char getShortName() {
-		return shortName;
-	}
-
-	/**
-	 * Returns the long name of the option.
-	 *
-	 * @return The long name of the option
-	 */
-	public String getLongName() {
-		return longName;
-	}
-
-	/**
-	 * Returns whether the option needs a parameter.
-	 *
-	 * @return <code>true</code> if the option requires a parameter,
-	 *         <code>false</code> otherwise
-	 */
-	public boolean needsParameter() {
-		return needsParameter;
-	}
-
-	/**
-	 * Returns the value of the option’s parameter.
-	 *
-	 * @return The value of the parameter, or <code>null</code> if no parameter
-	 *         was set
-	 */
-	public String getValue() {
-		return value;
-	}
-
-	/**
-	 * Sets the value of the option’s parameter.
-	 *
-	 * @param value
-	 *            The value of the parameter
-	 */
-	void setValue(String value) {
-		this.value = value;
-	}
-
-	/**
-	 * Returns the counter of the option.
-	 *
-	 * @return The number of times the option was given on the command line
-	 */
-	public int getCounter() {
-		return counter;
-	}
-
-	/**
-	 * Returns whether this option was present in the command line.
-	 *
-	 * @return <code>true</code> if the option was present, <code>false</code>
-	 *         otherwise
-	 */
-	public boolean isPresent() {
-		return counter > 0;
-	}
-
-	/**
-	 * Increments the option counter.
-	 */
-	void incrementCounter() {
-		counter++;
-	}
-
-	/**
-	 * @see java.lang.Object#toString()
-	 */
-	@Override
-	public String toString() {
-		return ((shortName != 0) ? ("-" + shortName) : "") + ((longName != null) ? (((shortName != 0) ? ("|") : ("")) + "--" + longName) : ("")) + (needsParameter ? ("=") : (""));
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/cmdline/package-info.java b/alien/src/net/pterodactylus/util/cmdline/package-info.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/cmdline/package-info.java
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * Command-line argument parser.
- * <p>
- * See {@link net.pterodactylus.util.cmdline.CommandLine} for more information.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-package net.pterodactylus.util.cmdline;
-
diff --git a/alien/src/net/pterodactylus/util/collection/ArrayMap.java b/alien/src/net/pterodactylus/util/collection/ArrayMap.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/collection/ArrayMap.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * utils - ArrayMap.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.collection;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * An {@code ArrayMap} is a {@link Map} implementation that is backed by arrays.
- * It does not rely on {@link Object#hashCode() object hashes} but solely uses
- * {@link Object#equals(Object)} to compare objects.
- *
- * @param <K>
- *            The type of the keys
- * @param <V>
- *            The type of the values
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ArrayMap<K, V> implements Map<K, V> {
-
-	/** The keys. */
-	private Object[] keys;
-
-	/** The values. */
-	private Object[] values;
-
-	/** The current size. */
-	private int size = 0;
-
-	/**
-	 * Creates a new array map with a default size of 10.
-	 */
-	public ArrayMap() {
-		this(10);
-	}
-
-	/**
-	 * Creates a new array map with the given default size.
-	 *
-	 * @param initialSize
-	 *            The initial size of the array map
-	 */
-	public ArrayMap(int initialSize) {
-		keys = new Object[initialSize];
-		values = new Object[initialSize];
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int size() {
-		return size;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean isEmpty() {
-		return size == 0;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean containsKey(Object key) {
-		return locateKey(key) != -1;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean containsValue(Object value) {
-		return locateValue(value) != -1;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	@SuppressWarnings("unchecked")
-	public V get(Object key) {
-		int index = locateKey(key);
-		if (index == -1) {
-			return null;
-		}
-		return (V) values[index];
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	@SuppressWarnings("unchecked")
-	public V put(K key, V value) {
-		int index = locateKey(key);
-		if (index == -1) {
-			checkResize();
-			keys[size] = key;
-			values[size] = value;
-			++size;
-			return null;
-		}
-		Object oldValue = values[index];
-		values[index] = value;
-		return (V) oldValue;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	@SuppressWarnings("unchecked")
-	public V remove(Object key) {
-		int index = locateKey(key);
-		if (index == -1) {
-			return null;
-		}
-		Object value = values[index];
-		if (index < (size - 1)) {
-			keys[index] = keys[size - 1];
-			values[index] = values[size - 1];
-		}
-		--size;
-		return (V) value;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void putAll(Map<? extends K, ? extends V> map) {
-		for (Entry<? extends K, ? extends V> entry : map.entrySet()) {
-			put(entry.getKey(), entry.getValue());
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void clear() {
-		size = 0;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	@SuppressWarnings("unchecked")
-	public Set<K> keySet() {
-		if (size < keys.length) {
-			Object[] temp = new Object[size];
-			System.arraycopy(keys, 0, temp, 0, size);
-			return new HashSet<K>(Arrays.asList((K[]) temp));
-		}
-		return new HashSet<K>(Arrays.asList((K[]) keys));
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	@SuppressWarnings("unchecked")
-	public Collection<V> values() {
-		if (size < keys.length) {
-			Object[] temp = new Object[size];
-			System.arraycopy(values, 0, temp, 0, size);
-			return Arrays.asList((V[]) temp);
-		}
-		return Arrays.asList((V[]) values);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	@SuppressWarnings("unchecked")
-	public Set<Entry<K, V>> entrySet() {
-		Set<Entry<K, V>> entries = new HashSet<Entry<K, V>>();
-		for (int index = 0; index < size; ++index) {
-			final K key = (K) keys[index];
-			final V value = (V) values[index];
-			entries.add(new Entry<K, V>() {
-
-				@Override
-				public K getKey() {
-					return key;
-				}
-
-				@Override
-				public V getValue() {
-					return value;
-				}
-
-				@Override
-				public V setValue(V value) {
-					/* nothing. */
-					return value;
-				}
-			});
-		}
-		return entries;
-	}
-
-	//
-	// PRIVATE METHODS
-	//
-
-	/**
-	 * Locates the given key in the {@link #keys} array.
-	 *
-	 * @param key
-	 *            The key to locate
-	 * @return The index of the key, or {@code -1} if the key could not be found
-	 */
-	private int locateKey(Object key) {
-		return locateObject(keys, key);
-	}
-
-	/**
-	 * Locates the index of the given value.
-	 *
-	 * @param value
-	 *            The value to locate
-	 * @return The index of the value, or {@code -1} if the value could not be
-	 *         found
-	 */
-	private int locateValue(Object value) {
-		return locateObject(values, value);
-	}
-
-	/**
-	 * Locates an object in the given array of objects.
-	 *
-	 * @param data
-	 *            The array of objects to search
-	 * @param value
-	 *            The object to search
-	 * @return The index of the object, or {@code -1} if the object could not be
-	 *         found
-	 */
-	private int locateObject(Object[] data, Object value) {
-		for (int index = 0; index < size; ++index) {
-			if ((value == null) && (data[index] == null) || ((value != null) && value.equals(data[index]))) {
-				return index;
-			}
-		}
-		return -1;
-	}
-
-	/**
-	 * Checks if the map needs to be resized and resizes it if the current
-	 * {@link #size} equals the current capacity of the {@link #keys} array.
-	 */
-	private void checkResize() {
-		if (size == (keys.length)) {
-			Object[] newKeys = new Object[keys.length * 2];
-			Object[] newValues = new Object[keys.length * 2];
-			System.arraycopy(keys, 0, newKeys, 0, size);
-			System.arraycopy(values, 0, newValues, 0, size);
-			keys = newKeys;
-			values = newValues;
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/collection/ComparablePair.java b/alien/src/net/pterodactylus/util/collection/ComparablePair.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/collection/ComparablePair.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * utils - ComparablePair.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.collection;
-
-/**
- * Container for two {@link Comparable} objects that are tied together.
- * Comparisons are done by first comparing the left object and only comparing
- * the right objects if the left objects are considered the same (i.e.
- * {@link Comparable#compareTo(Object)} returns {@code 0}).
- *
- * @param <S>
- *            The type of the left value
- * @param <T>
- *            The type of the right value
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ComparablePair<S extends Comparable<S>, T extends Comparable<T>> extends Pair<S, T> implements Comparable<ComparablePair<S, T>> {
-
-	/**
-	 * Creates a new pair consisting of the two values.
-	 *
-	 * @param left
-	 *            The left value
-	 * @param right
-	 *            The right value
-	 */
-	public ComparablePair(S left, T right) {
-		super(left, right);
-	}
-
-	/**
-	 * @see java.lang.Comparable#compareTo(Object)
-	 */
-	@Override
-	public int compareTo(ComparablePair<S, T> pair) {
-		int leftDifference = left.compareTo(pair.left);
-		return (leftDifference == 0) ? right.compareTo(pair.right) : leftDifference;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/collection/MapWriter.java b/alien/src/net/pterodactylus/util/collection/MapWriter.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/collection/MapWriter.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * utils - MapWriter.java - Copyright © 2008-2010 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.util.collection;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Map.Entry;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import net.pterodactylus.util.io.Closer;
-import net.pterodactylus.util.logging.Logging;
-import net.pterodactylus.util.number.Hex;
-
-/**
- * Helper class that emulates the function of
- * {@link Properties#store(java.io.OutputStream, String)} and
- * {@link Properties#load(java.io.InputStream)} but does not suffer from the
- * drawbacks of {@link Properties} (namely the fact that a
- * <code>Properties</code> can not contain <code>null</code> values).
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class MapWriter {
-
-	/** The logger. */
-	private static final Logger logger = Logging.getLogger(MapWriter.class.getName());
-
-	/**
-	 * Writes the given map to the given writer.
-	 *
-	 * @param writer
-	 *            The writer to write the map’s content to
-	 * @param map
-	 *            The map to write
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public static void write(Writer writer, Map<String, String> map) throws IOException {
-		for (Entry<String, String> entry : map.entrySet()) {
-			if (entry.getValue() != null) {
-				writer.write(encode(entry.getKey()));
-				writer.write('=');
-				writer.write(encode(entry.getValue()));
-				writer.write('\n');
-			}
-		}
-	}
-
-	/**
-	 * Reads a map from the given reader. Lines are read from the given reader
-	 * until a line is encountered that does not contain a colon (“:”) or equals
-	 * sign (“=”).
-	 *
-	 * @param reader
-	 *            The reader to read from
-	 * @return The map that was read
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public static Map<String, String> read(Reader reader) throws IOException {
-		logger.log(Level.FINE, "MapWriter.read(reader=" + reader + ")");
-		Map<String, String> map = new HashMap<String, String>();
-		BufferedReader bufferedReader = new BufferedReader(reader);
-		try {
-			String line;
-			while ((line = bufferedReader.readLine()) != null) {
-				logger.log(Level.FINEST, "Read line: “" + line + "”");
-				if (line.startsWith("#") || (line.length() == 0)) {
-					continue;
-				}
-				if (line.indexOf('=') == -1) {
-					break;
-				}
-				int split = line.indexOf('=');
-				String key = decode(line.substring(0, split));
-				String value = decode(line.substring(split + 1));
-				map.put(key, value);
-			}
-		} finally {
-			Closer.close(bufferedReader);
-		}
-		return map;
-	}
-
-	//
-	// PRIVATE METHODS
-	//
-
-	/**
-	 * Encodes the given String by replacing certain “unsafe” characters. CR
-	 * (0x0d) is replaced by “\r”, LF (0x0a) is replaced by “\n”, the backslash
-	 * (‘\’) will be replaced by “\\”, other characters that are either smaller
-	 * than 0x20 or larger than 0x7f or that are ‘:’ or ‘=’ will be replaced by
-	 * their unicode notation (“\u0000” for NUL, 0x00). All other values are
-	 * copied verbatim.
-	 *
-	 * @param value
-	 *            The value to encode
-	 * @return The encoded value
-	 */
-	static String encode(String value) {
-		StringBuilder encodedString = new StringBuilder();
-		for (char character : value.toCharArray()) {
-			if (character == 0x0d) {
-				encodedString.append("\\r");
-			} else if (character == 0x0a) {
-				encodedString.append("\\n");
-			} else if (character == '\\') {
-				encodedString.append("\\\\");
-			} else if ((character < 0x20) || (character == '=') || (character > 0x7f)) {
-				encodedString.append("\\u").append(Hex.toHex(character, 4));
-			} else {
-				encodedString.append(character);
-			}
-		}
-		return encodedString.toString();
-	}
-
-	/**
-	 * Decodes the given value by reversing the changes made by
-	 * {@link #encode(String)}.
-	 *
-	 * @param value
-	 *            The value to decode
-	 * @return The decoded value
-	 */
-	static String decode(String value) {
-		StringBuilder decodedString = new StringBuilder();
-		boolean backslash = false;
-		int hexDigit = 0;
-		char[] hexDigits = new char[4];
-		for (char character : value.toCharArray()) {
-			if (hexDigit > 0) {
-				hexDigits[hexDigit - 1] = character;
-				hexDigit++;
-				if (hexDigit > 4) {
-					decodedString.append((char) Integer.parseInt(new String(hexDigits), 16));
-					hexDigit = 0;
-				}
-			} else if (backslash) {
-				if (character == '\\') {
-					decodedString.append('\\');
-				} else if (character == 'r') {
-					decodedString.append('\r');
-				} else if (character == 'n') {
-					decodedString.append('\n');
-				} else if (character == 'u') {
-					hexDigit = 1;
-				}
-				backslash = false;
-			} else if (character == '\\') {
-				backslash = true;
-				continue;
-			} else {
-				decodedString.append(character);
-			}
-		}
-		return decodedString.toString();
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/collection/ObjectMethods.java b/alien/src/net/pterodactylus/util/collection/ObjectMethods.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/collection/ObjectMethods.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * utils - ObjectMethods.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.collection;
-
-/**
- * Contains helper methods for implementating {@link Object} methods such as
- * {@link Object#equals(Object)} and {@link Object#hashCode()} for objects that
- * may be {@code null}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ObjectMethods {
-
-	/**
-	 * Checks whether the two objects are equal.
-	 *
-	 * @param first
-	 *            The first object
-	 * @param second
-	 *            The second object
-	 * @return {@code true} if the objects are equal (according to
-	 *         {@link Object#equals(Object)}) or both {@code null}
-	 */
-	public static boolean equal(Object first, Object second) {
-		return (first == null) ? (second == null) : first.equals(second);
-	}
-
-	/**
-	 * Calculates the hash code for the given object.
-	 * @param object The object to get the hash code for
-	 * @return The hash code of the object, or
-	 */
-	public static int hashCode(Object object) {
-		return (object == null) ? 0xCF018C37 : object.hashCode();
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/collection/Pagination.java b/alien/src/net/pterodactylus/util/collection/Pagination.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/collection/Pagination.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * utils - Pagination.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.collection;
-
-import java.util.List;
-
-/**
- * Helper class for lists that need pagination. Setting the page or the page
- * size will automatically recalculate all other parameters, and the next call
- * to {@link #getItems()} retrieves all items on the current page.
- *
- * @param <T>
- *            The type of the list elements
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Pagination<T> {
-
-	/** The list to paginate. */
-	private final List<T> list;
-
-	/** The page size. */
-	private int pageSize;
-
-	/** The current page, 0-based. */
-	private int page;
-
-	/** The total number of pages. */
-	private int pageCount;
-
-	/**
-	 * Paginates the given list.
-	 *
-	 * @param list
-	 *            The list to paginate
-	 * @param pageSize
-	 *            The page size
-	 */
-	public Pagination(List<T> list, int pageSize) {
-		this.list = list;
-		this.pageSize = pageSize;
-		pageCount = (list.size() - 1) / pageSize + 1;
-	}
-
-	//
-	// ACCESSORS
-	//
-
-	/**
-	 * Returns the current page, 0-based.
-	 *
-	 * @return The current page, 0-based
-	 */
-	public int getPage() {
-		return page;
-	}
-
-	/**
-	 * Returns the current page, 1-based.
-	 *
-	 * @return The current page, 1-based
-	 */
-	public int getPageNumber() {
-		return page + 1;
-	}
-
-	/**
-	 * Sets the new page. If the new page is out of range it is silently
-	 * corrected.
-	 *
-	 * @param page
-	 *            The new page number
-	 * @return This pagination helper (for method chaining)
-	 */
-	public Pagination<T> setPage(int page) {
-		if (page < 0) {
-			this.page = 0;
-		} else if (page >= pageCount) {
-			this.page = pageCount - 1;
-		} else {
-			this.page = page;
-		}
-		return this;
-	}
-
-	/**
-	 * Returns the total number of pages.
-	 *
-	 * @return The total number of pages
-	 */
-	public int getPageCount() {
-		return pageCount;
-	}
-
-	/**
-	 * Returns the number of items per page.
-	 *
-	 * @return The number of items per page
-	 */
-	public int getPageSize() {
-		return pageSize;
-	}
-
-	/**
-	 * Sets the page size. The page is adjusted so that the first item on the
-	 * old page is still contained in the new page. A page size of less than 1
-	 * is silently corrected to 1.
-	 *
-	 * @param pageSize
-	 *            The new page size
-	 * @return This pagination helper (for method chaining)
-	 */
-	public Pagination<T> setPageSize(int pageSize) {
-		int newPageSize = (pageSize < 1) ? 1 : pageSize;
-		int index = page * this.pageSize;
-		this.pageSize = newPageSize;
-		pageCount = (list.size() - 1) / newPageSize + 1;
-		page = index / newPageSize;
-		return this;
-	}
-
-	/**
-	 * Returns the number of items on the current page. For all but the last
-	 * page this will equal the page size.
-	 *
-	 * @return The number of items on the current page
-	 */
-	public int getItemCount() {
-		return Math.min(pageSize, list.size() - page * pageSize);
-	}
-
-	/**
-	 * Returns the items on the current page.
-	 *
-	 * @return The items on the current page
-	 */
-	public List<T> getItems() {
-		return list.subList(page * pageSize, page * pageSize + getItemCount());
-	}
-
-	/**
-	 * Returns whether the current page is the first page
-	 *
-	 * @return {@code true} if the current page is the first page, {@code false}
-	 *         otherwise
-	 */
-	public boolean isFirst() {
-		return page == 0;
-	}
-
-	/**
-	 * Returns whether the current page is the last page.
-	 *
-	 * @return {@code true} if the current page is the last page, {@code false}
-	 *         otherwise
-	 */
-	public boolean isLast() {
-		return page == (pageCount - 1);
-	}
-
-	/**
-	 * Returns whether pagination is actually necessary, i.e. if the number of
-	 * pages is greater than 1.
-	 *
-	 * @return {@code true} if there are more than one page in this pagination,
-	 *         {@code false} otherwise
-	 */
-	public boolean isNecessary() {
-		return pageCount > 1;
-	}
-
-	/**
-	 * Returns the index of the previous page. {@link #isFirst()} should be
-	 * called first to determine whether there is a page before the current
-	 * page.
-	 *
-	 * @return The index of the previous page
-	 */
-	public int getPreviousPage() {
-		return page - 1;
-	}
-
-	/**
-	 * Returns the index of the next page. {@link #isLast()} should be called
-	 * first to determine whether there is a page after the current page.
-	 *
-	 * @return The index of the next page
-	 */
-	public int getNextPage() {
-		return page + 1;
-	}
-
-	/**
-	 * Returns the index of the last page.
-	 *
-	 * @return The index of the last page
-	 */
-	public int getLastPage() {
-		return pageCount - 1;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/collection/Pair.java b/alien/src/net/pterodactylus/util/collection/Pair.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/collection/Pair.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * utils - Pair.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.collection;
-
-/**
- * Container for two objects that are tied together.
- *
- * @param <S>
- *            The type of the left value
- * @param <T>
- *            The type of the right value
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Pair<S, T> {
-
-	/** The left value. */
-	protected final S left;
-
-	/** The right value. */
-	protected final T right;
-
-	/**
-	 * Creates a new pair consisting of the two values. None of the values may
-	 * be {@code null}.
-	 *
-	 * @param left
-	 *            The left value
-	 * @param right
-	 *            The right value
-	 */
-	public Pair(S left, T right) {
-		if ((left == null) || (right == null)) {
-			throw new NullPointerException("null is not allowed in a pair");
-		}
-		this.left = left;
-		this.right = right;
-	}
-
-	/**
-	 * Returns the left value.
-	 *
-	 * @return The left value
-	 */
-	public S getLeft() {
-		return left;
-	}
-
-	/**
-	 * Returns the right value.
-	 *
-	 * @return The right value
-	 */
-	public T getRight() {
-		return right;
-	}
-
-	/**
-	 * @see java.lang.Object#equals(java.lang.Object)
-	 */
-	@Override
-	public boolean equals(Object obj) {
-		if ((obj == null) || (obj.getClass() != getClass())) {
-			return false;
-		}
-		Pair<?, ?> pair = (Pair<?, ?>) obj;
-		return left.equals(pair.left) && right.equals(pair.right);
-	}
-
-	/**
-	 * @see java.lang.Object#hashCode()
-	 */
-	@Override
-	public int hashCode() {
-		int leftHashCode = left.hashCode();
-		return ((leftHashCode << 16) | (leftHashCode >>> 16)) ^ ~right.hashCode();
-	}
-
-	/**
-	 * @see java.lang.Object#toString()
-	 */
-	@Override
-	public String toString() {
-		return "<" + left + "," + right + ">";
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/collection/ReverseComparator.java b/alien/src/net/pterodactylus/util/collection/ReverseComparator.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/collection/ReverseComparator.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * utils - ReverseComparator.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.collection;
-
-import java.util.Comparator;
-
-/**
- * This {@link Comparator} implementation compares to {@link Comparable}s but
- * reverses the result of the comparison.
- *
- * @param <T>
- *            The type to compare
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ReverseComparator<T extends Comparable<T>> implements Comparator<T> {
-
-	/**
-	 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
-	 */
-	@Override
-	public int compare(T o1, T o2) {
-		return -o1.compareTo(o2);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/collection/Triplet.java b/alien/src/net/pterodactylus/util/collection/Triplet.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/collection/Triplet.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * utils - Triplet.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.collection;
-
-import net.pterodactylus.util.number.Bits;
-
-/**
- * 3-tuple.
- *
- * @param <T>
- *            The type of the first element
- * @param <U>
- *            The type of the second element
- * @param <V>
- *            The type of the third element
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Triplet<T, U, V> {
-
-	/** The first element. */
-	private final T first;
-
-	/** The second element. */
-	private final U second;
-
-	/** The third element. */
-	private final V third;
-
-	/**
-	 * Creates a new triplet.
-	 *
-	 * @param first
-	 *            The first element
-	 * @param second
-	 *            The second element
-	 * @param third
-	 *            The third element
-	 */
-	public Triplet(T first, U second, V third) {
-		this.first = first;
-		this.second = second;
-		this.third = third;
-	}
-
-	/**
-	 * Returns the first element.
-	 *
-	 * @return The first element
-	 */
-	public T getFirst() {
-		return first;
-	}
-
-	/**
-	 * Returns the second element.
-	 *
-	 * @return The second element
-	 */
-	public U getSecond() {
-		return second;
-	}
-
-	/**
-	 * Returns the third element.
-	 *
-	 * @return The third element
-	 */
-	public V getThird() {
-		return third;
-	}
-
-	/**
-	 * @see java.lang.Object#equals(java.lang.Object)
-	 */
-	@Override
-	public boolean equals(Object obj) {
-		if (!(obj instanceof Triplet<?, ?, ?>)) {
-			return false;
-		}
-		Triplet<?, ?, ?> triplet = (Triplet<?, ?, ?>) obj;
-		return ObjectMethods.equal(first, triplet.first) && ObjectMethods.equal(second, triplet.second) && ObjectMethods.equal(third, triplet.third);
-	}
-
-	/**
-	 * @see java.lang.Object#hashCode()
-	 */
-	@Override
-	public int hashCode() {
-		return Bits.rotateLeft(ObjectMethods.hashCode(first), 8) ^ Bits.rotateLeft(ObjectMethods.hashCode(second), 16) ^ Bits.rotateLeft(ObjectMethods.hashCode(third), 24);
-	}
-
-	/**
-	 * @see java.lang.Object#toString()
-	 */
-	@Override
-	public String toString() {
-		return "<" + first + "," + second + "," + third + ">";
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/AbstractValue.java b/alien/src/net/pterodactylus/util/config/AbstractValue.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/AbstractValue.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * utils - AbstractValue.java - Copyright © 2007-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-/**
- * An abstract implementation of a {@link Value}.
- *
- * @param <T>
- *            The type of the wrapped value
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public abstract class AbstractValue<T> implements Value<T> {
-
-	/** The configuration that created this value. */
-	protected final Configuration configuration;
-
-	/** The name of the attribute this is the value for. */
-	protected final String attribute;
-
-	/**
-	 * Creates a new value that reads its values from the given configuration
-	 * backend.
-	 *
-	 * @param configuration
-	 *            The configuration that created this value
-	 * @param attribute
-	 *            The name of this value’s attribute
-	 */
-	public AbstractValue(Configuration configuration, String attribute) {
-		this.configuration = configuration;
-		this.attribute = attribute;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/AttributeNotFoundException.java b/alien/src/net/pterodactylus/util/config/AttributeNotFoundException.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/AttributeNotFoundException.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * utils - AttributeNotFoundException.java - Copyright © 2007-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-/**
- * Exception that will be thrown when a non-existing attribute is requested.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class AttributeNotFoundException extends ConfigurationException {
-
-	/** The requested, non-existing attribute. */
-	private final String attribute;
-
-	/**
-	 * Constructs a new exception.
-	 */
-	public AttributeNotFoundException() {
-		super();
-		attribute = null;
-	}
-
-	/**
-	 * Constructs a new exception with the specified message.
-	 *
-	 * @param attribute
-	 *            The name of the attribute that could not be found
-	 */
-	public AttributeNotFoundException(String attribute) {
-		super("attribute not found: " + attribute);
-		this.attribute = attribute;
-	}
-
-	/**
-	 * Returns the requested, non-existing attribute's name.
-	 *
-	 * @return The name of the attribute that does not exist
-	 */
-	public String getAttribute() {
-		return attribute;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/BooleanValue.java b/alien/src/net/pterodactylus/util/config/BooleanValue.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/BooleanValue.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * utils - BooleanValue.java - Copyright © 2007-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-/**
- * A wrapper around a boolean value.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class BooleanValue extends AbstractValue<Boolean> {
-
-	/**
-	 * Creates a new boolean value that updates its value to the given attribute
-	 * from the given configuration.
-	 *
-	 * @param configuration
-	 *            The configuration that created this value
-	 * @param attribute
-	 *            The name of this value’s attribute name
-	 */
-	public BooleanValue(Configuration configuration, String attribute) {
-		super(configuration, attribute);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.Value#getValue()
-	 */
-	@Override
-	public Boolean getValue() throws ConfigurationException {
-		if (configuration.configurationBackend instanceof ExtendedConfigurationBackend) {
-			return ((ExtendedConfigurationBackend) configuration.configurationBackend).getBooleanValue(attribute);
-		}
-		String value = configuration.configurationBackend.getValue(attribute);
-		return Boolean.valueOf(("true".equalsIgnoreCase(value)) || ("yes".equalsIgnoreCase(value)) || ("1".equalsIgnoreCase(value)) || ("on".equalsIgnoreCase(value)));
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.Value#getValue(java.lang.Object)
-	 */
-	@Override
-	public Boolean getValue(Boolean defaultValue) {
-		try {
-			if (configuration.configurationBackend instanceof ExtendedConfigurationBackend) {
-				return ((ExtendedConfigurationBackend) configuration.configurationBackend).getBooleanValue(attribute);
-			}
-			String value = configuration.configurationBackend.getValue(attribute);
-			return Boolean.valueOf(("true".equalsIgnoreCase(value)) || ("yes".equalsIgnoreCase(value)) || ("1".equalsIgnoreCase(value)) || ("on".equalsIgnoreCase(value)));
-		} catch (ConfigurationException ce1) {
-			return defaultValue;
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.Value#setValue(java.lang.Object)
-	 */
-	@Override
-	public void setValue(Boolean newValue) throws ConfigurationException {
-		if (configuration.configurationBackend instanceof ExtendedConfigurationBackend) {
-			((ExtendedConfigurationBackend) configuration.configurationBackend).setBooleanValue(attribute, newValue);
-		}
-		configuration.configurationBackend.putValue(attribute, (newValue != null) ? String.valueOf(newValue) : null);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/CachingConfigurationBackend.java b/alien/src/net/pterodactylus/util/config/CachingConfigurationBackend.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/CachingConfigurationBackend.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * utils - CachingConfigurationBackend.java - Copyright © 2007-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Configuration backend proxy that caches the attribute values it retrieves.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class CachingConfigurationBackend implements ConfigurationBackend {
-
-	/** The real configuration backend. */
-	private final ConfigurationBackend realConfigurationBackend;
-
-	/** The cache for the attribute values. */
-	private final Map<String, String> attributeCache = new HashMap<String, String>();
-
-	/**
-	 * Creates a new caching configuration backend that works as a proxy for the
-	 * specified configuration backend and caches all values it retrieves.
-	 *
-	 * @param realConfigurationBackend
-	 *            The configuration backend to proxy
-	 */
-	public CachingConfigurationBackend(ConfigurationBackend realConfigurationBackend) {
-		this.realConfigurationBackend = realConfigurationBackend;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.ConfigurationBackend#getValue(java.lang.String)
-	 */
-	@Override
-	public synchronized String getValue(String attribute) throws ConfigurationException {
-		if (attributeCache.containsKey(attribute)) {
-			return attributeCache.get(attribute);
-		}
-		String value = realConfigurationBackend.getValue(attribute);
-		attributeCache.put(attribute, value);
-		return value;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.ConfigurationBackend#putValue(java.lang.String,
-	 *      java.lang.String)
-	 */
-	@Override
-	public synchronized void putValue(String attribute, String value) throws ConfigurationException {
-		attributeCache.put(attribute, value);
-		realConfigurationBackend.putValue(attribute, value);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void save() throws ConfigurationException {
-		realConfigurationBackend.save();
-	}
-
-	/**
-	 * Clears the current cache, causing the all further lookups to be repeated.
-	 */
-	public synchronized void clear() {
-		attributeCache.clear();
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/Configuration.java b/alien/src/net/pterodactylus/util/config/Configuration.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/Configuration.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * utils - Configuration.java - Copyright © 2007-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A configuration contains all necessary methods to read integral data types
- * from a {@link ConfigurationBackend}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Configuration {
-
-	/** The backend backing this configuration. */
-	final ConfigurationBackend configurationBackend;
-
-	/** The cache for boolean values. */
-	private final Map<String, BooleanValue> booleanCache = new HashMap<String, BooleanValue>();
-
-	/** The cache for double values. */
-	private final Map<String, DoubleValue> doubleCache = new HashMap<String, DoubleValue>();
-
-	/** The cache for string values. */
-	private final Map<String, StringValue> stringCache = new HashMap<String, StringValue>();
-
-	/** The cache for integer values. */
-	private final Map<String, IntegerValue> integerCache = new HashMap<String, IntegerValue>();
-
-	/** The cache for long values. */
-	private final Map<String, LongValue> longCache = new HashMap<String, LongValue>();
-
-	/**
-	 * Creates a new configuration that operates on the given backend.
-	 *
-	 * @param configurationBackend
-	 *            The backend backing this configuration
-	 */
-	public Configuration(ConfigurationBackend configurationBackend) {
-		this.configurationBackend = configurationBackend;
-	}
-
-	/**
-	 * Returns the boolean value stored at the given attribute.
-	 *
-	 * @param attribute
-	 *            The name of the attribute
-	 * @return The boolean value stored at the given attribute
-	 */
-	public Value<Boolean> getBooleanValue(String attribute) {
-		BooleanValue booleanValue = booleanCache.get(attribute);
-		if (booleanValue == null) {
-			booleanValue = new BooleanValue(this, attribute);
-			booleanCache.put(attribute, booleanValue);
-		}
-		return booleanValue;
-	}
-
-	/**
-	 * Returns the double value stored at the given attribute.
-	 *
-	 * @param attribute
-	 *            The name of the attribute
-	 * @return The double value stored at the given attribute
-	 */
-	public Value<Double> getDoubleValue(String attribute) {
-		DoubleValue doubleValue = doubleCache.get(attribute);
-		if (doubleValue == null) {
-			doubleValue = new DoubleValue(this, attribute);
-			doubleCache.put(attribute, doubleValue);
-		}
-		return doubleValue;
-	}
-
-	/**
-	 * Returns the integer value stored at the given attribute.
-	 *
-	 * @param attribute
-	 *            The name of the attribute
-	 * @return The integer value stored at the given attribute
-	 */
-	public Value<Integer> getIntValue(String attribute) {
-		IntegerValue integerValue = integerCache.get(attribute);
-		if (integerValue == null) {
-			integerValue = new IntegerValue(this, attribute);
-			integerCache.put(attribute, integerValue);
-		}
-		return integerValue;
-	}
-
-	/**
-	 * Returns the long value stored at the given attribute.
-	 *
-	 * @param attribute
-	 *            The name of the attribute
-	 * @return The long value stored at the given attribute
-	 */
-	public Value<Long> getLongValue(String attribute) {
-		LongValue longValue = longCache.get(attribute);
-		if (longValue == null) {
-			longValue = new LongValue(this, attribute);
-			longCache.put(attribute, longValue);
-		}
-		return longValue;
-	}
-
-	/**
-	 * Returns the string value stored at the given attribute.
-	 *
-	 * @param attribute
-	 *            The name of the attribute
-	 * @return The double value stored at the given attribute
-	 */
-	public Value<String> getStringValue(String attribute) {
-		StringValue stringValue = stringCache.get(attribute);
-		if (stringValue == null) {
-			stringValue = new StringValue(this, attribute);
-			stringCache.put(attribute, stringValue);
-		}
-		return stringValue;
-	}
-
-	/**
-	 * Saves the configuration. This request is usually forwarded to the
-	 * {@link ConfigurationBackend}.
-	 *
-	 * @see ConfigurationBackend#save()
-	 * @throws ConfigurationException
-	 *             if the configuration can not be saved
-	 */
-	public void save() throws ConfigurationException {
-		configurationBackend.save();
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/ConfigurationBackend.java b/alien/src/net/pterodactylus/util/config/ConfigurationBackend.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/ConfigurationBackend.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * utils - ConfigurationBackend.java - Copyright © 2007-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-/**
- * Interface for backends that can read and (optionally) write values at given
- * attribute names.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface ConfigurationBackend {
-
-	/**
-	 * Returns the value of the given attribute from the backend.
-	 *
-	 * @param attribute
-	 *            The name of the attribute
-	 * @return The string representation of the value
-	 * @throws ConfigurationException
-	 *             if the attribute could not be found
-	 */
-	public String getValue(String attribute) throws ConfigurationException;
-
-	/**
-	 * Sets the value of the given attribute within the backend.
-	 *
-	 * @param attribute
-	 *            The name of the attribute to set
-	 * @param value
-	 *            The string representation of the value
-	 * @throws ConfigurationException
-	 *             if the value could not be set
-	 */
-	public void putValue(String attribute, String value) throws ConfigurationException;
-
-	/**
-	 * Saves the configuration.
-	 *
-	 * @throws ConfigurationException
-	 *             if the configuration could not be saved
-	 */
-	public void save() throws ConfigurationException;
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/ConfigurationException.java b/alien/src/net/pterodactylus/util/config/ConfigurationException.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/ConfigurationException.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * utils - ConfigurationException.java - Copyright © 2007-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-/**
- * Parent exception for all exceptions that can occur during configuration file
- * parsing.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ConfigurationException extends Exception {
-
-	/**
-	 * Constructs a new configuration exception.
-	 */
-	public ConfigurationException() {
-		super();
-	}
-
-	/**
-	 * Constructs a new configuration exception with the specified message
-	 *
-	 * @param message
-	 *            The message of the exception
-	 */
-	public ConfigurationException(String message) {
-		super(message);
-	}
-
-	/**
-	 * Constructs a new configuration exception with the specified message and
-	 * cause.
-	 *
-	 * @param message
-	 *            The message of the exception
-	 * @param cause
-	 *            The cause of the exception
-	 */
-	public ConfigurationException(String message, Throwable cause) {
-		super(message, cause);
-	}
-
-	/**
-	 * Constructs a new configuration exception with the specified cause.
-	 *
-	 * @param cause
-	 *            The cause of the exception
-	 */
-	public ConfigurationException(Throwable cause) {
-		super(cause);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/ConfigurationTest.xml b/alien/src/net/pterodactylus/util/config/ConfigurationTest.xml
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/ConfigurationTest.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<configuration>
-	<test>10</test>
-</configuration>
\ No newline at end of file
diff --git a/alien/src/net/pterodactylus/util/config/DoubleValue.java b/alien/src/net/pterodactylus/util/config/DoubleValue.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/DoubleValue.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * utils - DoubleValue.java - Copyright © 2007-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-/**
- * A wrapper around a double value.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class DoubleValue extends AbstractValue<Double> {
-
-	/**
-	 * Creates a new double value that updates its value to the given attribute
-	 * from the given configuration.
-	 *
-	 * @param configuration
-	 *            The configuration that created this value
-	 * @param attribute
-	 *            The name of this value’s attribute name
-	 */
-	public DoubleValue(Configuration configuration, String attribute) {
-		super(configuration, attribute);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.Value#getValue()
-	 */
-	@Override
-	public Double getValue() throws ConfigurationException {
-		if (configuration.configurationBackend instanceof ExtendedConfigurationBackend) {
-			return ((ExtendedConfigurationBackend) configuration.configurationBackend).getDoubleValue(attribute);
-		}
-		String value = null;
-		try {
-			value = configuration.configurationBackend.getValue(attribute);
-			double doubleValue = Double.valueOf(value);
-			return doubleValue;
-		} catch (NumberFormatException nfe1) {
-			throw new ValueFormatException("could not parse attribute \"" + value + "\".", nfe1);
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.Value#getValue(java.lang.Object)
-	 */
-	@Override
-	public Double getValue(Double defaultValue) {
-		String value = null;
-		try {
-			if (configuration.configurationBackend instanceof ExtendedConfigurationBackend) {
-				return ((ExtendedConfigurationBackend) configuration.configurationBackend).getDoubleValue(attribute);
-			}
-			value = configuration.configurationBackend.getValue(attribute);
-			double doubleValue = Double.valueOf(value);
-			return doubleValue;
-		} catch (NumberFormatException nfe1) {
-			return defaultValue;
-		} catch (ConfigurationException ce1) {
-			return defaultValue;
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.Value#setValue(java.lang.Object)
-	 */
-	@Override
-	public void setValue(Double newValue) throws ConfigurationException {
-		if (configuration.configurationBackend instanceof ExtendedConfigurationBackend) {
-			((ExtendedConfigurationBackend) configuration.configurationBackend).setDoubleValue(attribute, newValue);
-		}
-		configuration.configurationBackend.putValue(attribute, (newValue != null) ? String.valueOf(newValue) : null);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/ExtendedConfigurationBackend.java b/alien/src/net/pterodactylus/util/config/ExtendedConfigurationBackend.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/ExtendedConfigurationBackend.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * utils - ExtendedConfigurationBackend.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-/**
- * The extended configuration backend allows a backend to specify ways to
- * retrieve other types than strings. Defined in this backend are all types are
- * used in {@link Configuration}, too: {@link Boolean}, {@link Double},
- * {@link Integer}, {@link Long}, and {@link String}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface ExtendedConfigurationBackend extends ConfigurationBackend {
-
-	/**
-	 * Returns the value of the given attribute from the backend.
-	 *
-	 * @param attribute
-	 *            The name of the attribute
-	 * @return The stored value
-	 * @throws ConfigurationException
-	 *             if the attribute could not be found
-	 */
-	public Boolean getBooleanValue(String attribute) throws ConfigurationException;
-
-	/**
-	 * Sets the value of the given attribute within the backend.
-	 *
-	 * @param attribute
-	 *            The name of the attribute to set
-	 * @param value
-	 *            The value to store
-	 * @throws ConfigurationException
-	 *             if the value could not be set
-	 */
-	public void setBooleanValue(String attribute, Boolean value) throws ConfigurationException;
-
-	/**
-	 * Returns the value of the given attribute from the backend.
-	 *
-	 * @param attribute
-	 *            The name of the attribute
-	 * @return The stored value
-	 * @throws ConfigurationException
-	 *             if the attribute could not be found
-	 */
-	public Double getDoubleValue(String attribute) throws ConfigurationException;
-
-	/**
-	 * Sets the value of the given attribute within the backend.
-	 *
-	 * @param attribute
-	 *            The name of the attribute to set
-	 * @param value
-	 *            The value to store
-	 * @throws ConfigurationException
-	 *             if the value could not be set
-	 */
-	public void setDoubleValue(String attribute, Double value) throws ConfigurationException;
-
-	/**
-	 * Returns the value of the given attribute from the backend.
-	 *
-	 * @param attribute
-	 *            The name of the attribute
-	 * @return The stored value
-	 * @throws ConfigurationException
-	 *             if the attribute could not be found
-	 */
-	public Integer getIntegerValue(String attribute) throws ConfigurationException;
-
-	/**
-	 * Sets the value of the given attribute within the backend.
-	 *
-	 * @param attribute
-	 *            The name of the attribute to set
-	 * @param value
-	 *            The value to store
-	 * @throws ConfigurationException
-	 *             if the value could not be set
-	 */
-	public void setIntegerValue(String attribute, Integer value) throws ConfigurationException;
-
-	/**
-	 * Returns the value of the given attribute from the backend.
-	 *
-	 * @param attribute
-	 *            The name of the attribute
-	 * @return The stored value
-	 * @throws ConfigurationException
-	 *             if the attribute could not be found
-	 */
-	public Long getLongValue(String attribute) throws ConfigurationException;
-
-	/**
-	 * Sets the value of the given attribute within the backend.
-	 *
-	 * @param attribute
-	 *            The name of the attribute to set
-	 * @param value
-	 *            The value to store
-	 * @throws ConfigurationException
-	 *             if the value could not be set
-	 */
-	public void setLongValue(String attribute, Long value) throws ConfigurationException;
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/IntegerValue.java b/alien/src/net/pterodactylus/util/config/IntegerValue.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/IntegerValue.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * utils - IntegerValue.java - Copyright © 2007-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-/**
- * A wrapper around an integer value.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class IntegerValue extends AbstractValue<Integer> {
-
-	/**
-	 * Creates a new integer value that updates its value to the given attribute
-	 * from the given configuration.
-	 *
-	 * @param configuration
-	 *            The configuration that created this value
-	 * @param attribute
-	 *            The name of this value’s attribute name
-	 */
-	public IntegerValue(Configuration configuration, String attribute) {
-		super(configuration, attribute);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.Value#getValue()
-	 */
-	@Override
-	public Integer getValue() throws ConfigurationException {
-		if (configuration.configurationBackend instanceof ExtendedConfigurationBackend) {
-			return ((ExtendedConfigurationBackend) configuration.configurationBackend).getIntegerValue(attribute);
-		}
-		String value = null;
-		try {
-			value = configuration.configurationBackend.getValue(attribute);
-			int integerValue = Integer.valueOf(value);
-			return integerValue;
-		} catch (NumberFormatException nfe1) {
-			throw new ValueFormatException("could not parse attribute \"" + value + "\".", nfe1);
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.Value#getValue(java.lang.Object)
-	 */
-	@Override
-	public Integer getValue(Integer defaultValue) {
-		String value = null;
-		try {
-			if (configuration.configurationBackend instanceof ExtendedConfigurationBackend) {
-				return ((ExtendedConfigurationBackend) configuration.configurationBackend).getIntegerValue(attribute);
-			}
-			value = configuration.configurationBackend.getValue(attribute);
-			int integerValue = Integer.valueOf(value);
-			return integerValue;
-		} catch (NumberFormatException nfe1) {
-			return defaultValue;
-		} catch (ConfigurationException ce1) {
-			return defaultValue;
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.Value#setValue(java.lang.Object)
-	 */
-	@Override
-	public void setValue(Integer newValue) throws ConfigurationException {
-		if (configuration.configurationBackend instanceof ExtendedConfigurationBackend) {
-			((ExtendedConfigurationBackend) configuration.configurationBackend).setIntegerValue(attribute, newValue);
-		}
-		configuration.configurationBackend.putValue(attribute, (newValue != null) ? String.valueOf(newValue) : null);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/LongValue.java b/alien/src/net/pterodactylus/util/config/LongValue.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/LongValue.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * utils - LongValue.java - Copyright © 2007-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-/**
- * A wrapper around a long value.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class LongValue extends AbstractValue<Long> {
-
-	/**
-	 * Creates a new long value that updates its value to the given attribute
-	 * from the given configuration.
-	 *
-	 * @param configuration
-	 *            The configuration that created this value
-	 * @param attribute
-	 *            The name of this value’s attribute name
-	 */
-	public LongValue(Configuration configuration, String attribute) {
-		super(configuration, attribute);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.Value#getValue()
-	 */
-	@Override
-	public Long getValue() throws ConfigurationException {
-		if (configuration.configurationBackend instanceof ExtendedConfigurationBackend) {
-			return ((ExtendedConfigurationBackend) configuration.configurationBackend).getLongValue(attribute);
-		}
-		String value = null;
-		try {
-			value = configuration.configurationBackend.getValue(attribute);
-			long longValue = Long.valueOf(value);
-			return longValue;
-		} catch (NumberFormatException nfe1) {
-			throw new ValueFormatException("could not parse attribute \"" + value + "\".", nfe1);
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.Value#getValue(java.lang.Object)
-	 */
-	@Override
-	public Long getValue(Long defaultValue) {
-		String value = null;
-		try {
-			if (configuration.configurationBackend instanceof ExtendedConfigurationBackend) {
-				return ((ExtendedConfigurationBackend) configuration.configurationBackend).getLongValue(attribute);
-			}
-			value = configuration.configurationBackend.getValue(attribute);
-			long longValue = Long.valueOf(value);
-			return longValue;
-		} catch (NumberFormatException nfe1) {
-			return defaultValue;
-		} catch (ConfigurationException ce1) {
-			return defaultValue;
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.Value#setValue(java.lang.Object)
-	 */
-	@Override
-	public void setValue(Long newValue) throws ConfigurationException {
-		if (configuration.configurationBackend instanceof ExtendedConfigurationBackend) {
-			((ExtendedConfigurationBackend) configuration.configurationBackend).setLongValue(attribute, newValue);
-		}
-		configuration.configurationBackend.putValue(attribute, (newValue != null) ? String.valueOf(newValue) : null);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/MapConfigurationBackend.java b/alien/src/net/pterodactylus/util/config/MapConfigurationBackend.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/MapConfigurationBackend.java
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * utils - MapConfigurationBackend.java - Copyright © 2007-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import net.pterodactylus.util.io.Closer;
-import net.pterodactylus.util.logging.Logging;
-import net.pterodactylus.util.text.StringEscaper;
-import net.pterodactylus.util.text.TextException;
-
-/**
- * Configuration backend that is backed by a {@link Map}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class MapConfigurationBackend implements ConfigurationBackend {
-
-	/** The logger. */
-	private static final Logger logger = Logging.getLogger(MapConfigurationBackend.class);
-
-	/** The backing file, if any. */
-	private final File configurationFile;
-
-	/** The backing map. */
-	private final Map<String, String> values = new HashMap<String, String>();
-
-	/**
-	 * Creates a new configuration backend.
-	 */
-	public MapConfigurationBackend() {
-		this(Collections.<String, String> emptyMap());
-	}
-
-	/**
-	 * Creates a new configuration backend that contains the values from the
-	 * given map.
-	 *
-	 * @param values
-	 *            The initial values
-	 */
-	public MapConfigurationBackend(Map<String, String> values) {
-		configurationFile = null;
-		this.values.putAll(values);
-	}
-
-	/**
-	 * Creates a new configuration backend that loads and stores its
-	 * configuration in the given file.
-	 *
-	 * @param configurationFile
-	 *            The file to store the configuration in
-	 * @throws ConfigurationException
-	 *             if the configuration can not be loaded from the file
-	 */
-	public MapConfigurationBackend(File configurationFile) throws ConfigurationException {
-		this(configurationFile, false);
-	}
-
-	/**
-	 * Creates a new configuration backend from the given file that also
-	 * contains the given values.
-	 *
-	 * @param configurationFile
-	 *            The file to store the configuration in
-	 * @param values
-	 *            Additional initial values
-	 * @throws ConfigurationException
-	 *             if the configuration can not be loaded from the file
-	 */
-	public MapConfigurationBackend(File configurationFile, Map<String, String> values) throws ConfigurationException {
-		this(configurationFile, false, values);
-	}
-
-	/**
-	 * Creates a new configuration backend from the given file.
-	 *
-	 * @param configurationFile
-	 *            The file to store the configuration in
-	 * @param ignoreMissing
-	 *            {@code true} to ignore a missing configuration file when
-	 *            loading the configuration
-	 * @throws ConfigurationException
-	 *             if the configuration can not be loaded from the file
-	 */
-	public MapConfigurationBackend(File configurationFile, boolean ignoreMissing) throws ConfigurationException {
-		this(configurationFile, ignoreMissing, null);
-	}
-
-	/**
-	 * Creates a new configuration backend from the given file that also
-	 * contains the given values.
-	 *
-	 * @param configurationFile
-	 *            The file to store the configuration in
-	 * @param ignoreMissing
-	 *            {@code true} to ignore a missing configuration file when
-	 *            loading the configuration
-	 * @param values
-	 *            Additional initial values
-	 * @throws ConfigurationException
-	 *             if the configuration can not be loaded from the file
-	 */
-	public MapConfigurationBackend(File configurationFile, boolean ignoreMissing, Map<String, String> values) throws ConfigurationException {
-		this.configurationFile = configurationFile;
-		if (configurationFile != null) {
-			loadValues(ignoreMissing);
-		}
-		if (values != null) {
-			this.values.putAll(values);
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.ConfigurationBackend#getValue(java.lang.String)
-	 */
-	@Override
-	public String getValue(String attribute) {
-		synchronized (values) {
-			return values.get(attribute);
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.ConfigurationBackend#putValue(java.lang.String,
-	 *      java.lang.String)
-	 */
-	@Override
-	public void putValue(String attribute, String value) throws ConfigurationException {
-		synchronized (values) {
-			values.put(attribute, value);
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void save() throws ConfigurationException {
-		synchronized (values) {
-			saveValues();
-		}
-	}
-
-	//
-	// PRIVATE METHODS
-	//
-
-	/**
-	 * Loads the configuration from the {@link #configurationFile}. If
-	 * {@code ignoreMissing} is {@code false} a {@link ConfigurationException}
-	 * will be thrown if the file does not exist.
-	 *
-	 * @param ignoreMissing
-	 *            {@code true} to ignore a missing configuration file,
-	 *            {@code false} to throw a {@link ConfigurationException}
-	 * @throws ConfigurationException
-	 *             if the file can not be found or read, or the values can not
-	 *             be parsed
-	 */
-	private void loadValues(boolean ignoreMissing) throws ConfigurationException {
-		if (!configurationFile.exists()) {
-			if (!ignoreMissing) {
-				throw new ConfigurationException("Configuration file “" + configurationFile.getName() + "” is missing!");
-			}
-			return;
-		}
-		FileInputStream configurationInputStream = null;
-		InputStreamReader inputStreamReader = null;
-		BufferedReader bufferedReader = null;
-		try {
-			configurationInputStream = new FileInputStream(configurationFile);
-			inputStreamReader = new InputStreamReader(configurationInputStream, "UTF-8");
-			bufferedReader = new BufferedReader(inputStreamReader);
-			Map<String, String> values = new HashMap<String, String>();
-			String line;
-			while ((line = bufferedReader.readLine()) != null) {
-				if (line.startsWith("#") || line.startsWith(";") || (line.trim().length() == 0)) {
-					continue;
-				}
-				int colon = line.indexOf(':');
-				int equals = line.indexOf('=');
-				if ((colon == -1) && (equals == -1)) {
-					throw new ConfigurationException("Line without “:” or “=” found: " + line);
-				}
-				String key;
-				if (colon != -1) {
-					if (equals != -1) {
-						key = line.substring(0, Math.min(colon, equals));
-					} else {
-						key = line.substring(0, colon);
-					}
-				} else {
-					key = line.substring(0, equals);
-				}
-				if (line.substring(key.length() + 1).trim().length() == 0) {
-					values.put(key, null);
-				} else {
-					key = StringEscaper.parseLine(key).get(0);
-					List<String> words = StringEscaper.parseLine(line.substring(key.length() + 1).trim());
-					StringBuilder value = new StringBuilder();
-					for (String word : words) {
-						if (value.length() > 0) {
-							value.append(' ');
-						}
-						value.append(word);
-					}
-					values.put(key, value.toString());
-				}
-			}
-			this.values.putAll(values);
-		} catch (FileNotFoundException fnfe1) {
-			if (!ignoreMissing) {
-				throw new ConfigurationException("Could not find configuration file “" + configurationFile.getName() + "”!", fnfe1);
-			}
-		} catch (UnsupportedEncodingException uee1) {
-			/* impossible, I’d say. */
-			logger.log(Level.SEVERE, "JVM does not support UTF-8!");
-		} catch (IOException ioe1) {
-			throw new ConfigurationException("Could not read configuration from “" + configurationFile.getName() + "”!", ioe1);
-		} catch (TextException te1) {
-			throw new ConfigurationException("Could not parse configuration value!", te1);
-		} finally {
-			Closer.close(bufferedReader);
-			Closer.close(inputStreamReader);
-			Closer.close(configurationInputStream);
-		}
-	}
-
-	/**
-	 * Saves the configuration to the configuration file, if it is not
-	 * {@code null}. If no configuration file has been set, this method simply
-	 * returns.
-	 *
-	 * @throws ConfigurationException
-	 *             if there was an error when writing the configuration
-	 */
-	public void saveValues() throws ConfigurationException {
-		if (configurationFile == null) {
-			return;
-		}
-		FileOutputStream configurationOutputStream = null;
-		OutputStreamWriter outputStreamWriter = null;
-		BufferedWriter bufferedWriter = null;
-		try {
-			configurationOutputStream = new FileOutputStream(configurationFile);
-			outputStreamWriter = new OutputStreamWriter(configurationOutputStream, "UTF-8");
-			bufferedWriter = new BufferedWriter(outputStreamWriter);
-			for (Entry<String, String> value : values.entrySet()) {
-				bufferedWriter.write(StringEscaper.escapeWord(value.getKey()));
-				bufferedWriter.write(": ");
-				bufferedWriter.write(StringEscaper.escapeWord(value.getValue()));
-				bufferedWriter.newLine();
-			}
-		} catch (FileNotFoundException fnfe1) {
-			throw new ConfigurationException("Could not create configuration file “" + configurationFile.getName() + "”!", fnfe1);
-		} catch (UnsupportedEncodingException uee1) {
-			/* impossible, I’d say. */
-			logger.log(Level.SEVERE, "JVM does not support UTF-8!");
-		} catch (IOException ioe1) {
-			throw new ConfigurationException("Could not write to configuration file!", ioe1);
-		} finally {
-			Closer.close(bufferedWriter);
-			Closer.close(outputStreamWriter);
-			Closer.close(configurationOutputStream);
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/Parser.java b/alien/src/net/pterodactylus/util/config/Parser.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/Parser.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * utils - Parser.java - Copyright © 2007-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-/**
- * Interface for abstract object parsers. Since you are free to implement
- * methods
- *
- * @param <T>
- *            The type of the object to parse from a {@link Configuration}
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface Parser<T> {
-
-	/**
-	 * Parses an abstract object from a {@link Configuration}.
-	 *
-	 * @param attribute
-	 *            The name of the attribute of the abstract object
-	 * @return The abstract object
-	 * @throws ConfigurationException
-	 *             if a configuration error occured
-	 */
-	public Value<T> parse(String attribute) throws ConfigurationException;
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/ReadOnlyValue.java b/alien/src/net/pterodactylus/util/config/ReadOnlyValue.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/ReadOnlyValue.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * utils - ReadOnlyValue.java - Copyright © 2007-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-/**
- * Implementation of a read-only value that never changes.
- *
- * @param <T>
- *            The real type of the value
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ReadOnlyValue<T> implements Value<T> {
-
-	/** The wrapped value. */
-	private final T value;
-
-	/**
-	 * Creates a new read-only value.
-	 *
-	 * @param value
-	 *            The value to wrap
-	 */
-	public ReadOnlyValue(T value) {
-		this.value = value;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.Value#getValue()
-	 */
-	@Override
-	public T getValue() throws ConfigurationException {
-		return value;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.Value#getValue(java.lang.Object)
-	 */
-	@Override
-	public T getValue(T defaultValue) {
-		return value;
-	}
-
-	/**
-	 * {@inheritDoc} This method does nothing.
-	 *
-	 * @see net.pterodactylus.util.config.Value#setValue(java.lang.Object)
-	 */
-	@Override
-	public void setValue(T newValue) throws ConfigurationException {
-		/* ignore. */
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/StringValue.java b/alien/src/net/pterodactylus/util/config/StringValue.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/StringValue.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * utils - StringValue.java - Copyright © 2007-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-/**
- * A wrapper around a string value.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class StringValue extends AbstractValue<String> {
-
-	/**
-	 * Creates a new string value that updates its value to the given attribute
-	 * from the given configuration.
-	 *
-	 * @param configuration
-	 *            The configuration that created this value
-	 * @param attribute
-	 *            The name of this value’s attribute name
-	 */
-	public StringValue(Configuration configuration, String attribute) {
-		super(configuration, attribute);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.Value#getValue()
-	 */
-	@Override
-	public String getValue() throws ConfigurationException {
-		return configuration.configurationBackend.getValue(attribute);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.Value#getValue(java.lang.Object)
-	 */
-	@Override
-	public String getValue(String defaultValue) {
-		try {
-			return configuration.configurationBackend.getValue(attribute);
-		} catch (ConfigurationException ce1) {
-			return defaultValue;
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.Value#setValue(java.lang.Object)
-	 */
-	@Override
-	public void setValue(String newValue) throws ConfigurationException {
-		configuration.configurationBackend.putValue(attribute, newValue);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/Value.java b/alien/src/net/pterodactylus/util/config/Value.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/Value.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * utils - Value.java - Copyright © 2007-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-/**
- * Wrapper for a configuration value. Returning this wrapper instead of the
- * integral types allows the value to be updated (e.g. when the configuration
- * file changes) or written back to the underlying configuraiton backend (which
- * might in turn support persisting itself).
- *
- * @param <T>
- *            The type of the wrapped data
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface Value<T> {
-
-	/**
-	 * Returns the wrapped value.
-	 *
-	 * @return The wrapped value
-	 * @throws ConfigurationException
-	 *             if a configuration error occurs
-	 */
-	public T getValue() throws ConfigurationException;
-
-	/**
-	 * Returns the wrapped value, if possible. If the value can not be retrieved
-	 * or parsed, the default value is returned instead.
-	 *
-	 * @param defaultValue
-	 *            The default value to return in case of an error
-	 * @return The wrapped value, or the default value if the wrapped value can
-	 *         not be retrieved or parsed
-	 */
-	public T getValue(T defaultValue);
-
-	/**
-	 * Sets a new wrapped value.
-	 *
-	 * @param newValue
-	 *            The new wrapped value
-	 * @throws ConfigurationException
-	 *             if a configuration error occurs
-	 */
-	public void setValue(T newValue) throws ConfigurationException;
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/ValueFormatException.java b/alien/src/net/pterodactylus/util/config/ValueFormatException.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/ValueFormatException.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * utils - ValueFormatException.java - Copyright © 2007-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-/**
- * Exception that signals a conversion error if a specified format for a value
- * is requested.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ValueFormatException extends ConfigurationException {
-
-	/**
-	 * Constructs a new value format exception.
-	 */
-	public ValueFormatException() {
-		super();
-	}
-
-	/**
-	 * Constructs a new value format exception with the given message.
-	 *
-	 * @param message
-	 *            The message of the exception
-	 */
-	public ValueFormatException(String message) {
-		super(message);
-	}
-
-	/**
-	 * Constructs a new value format exception with the given cause.
-	 *
-	 * @param cause
-	 *            The cause of the exception
-	 */
-	public ValueFormatException(Throwable cause) {
-		super(cause);
-	}
-
-	/**
-	 * Constructs a new value format exception with the given message and cause.
-	 *
-	 * @param message
-	 *            The message of the exception
-	 * @param cause
-	 *            The cause of the exception
-	 */
-	public ValueFormatException(String message, Throwable cause) {
-		super(message, cause);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/XMLConfigurationBackend.java b/alien/src/net/pterodactylus/util/config/XMLConfigurationBackend.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/XMLConfigurationBackend.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * utils - XMLConfigurationBackend.java - Copyright © 2007-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.config;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import net.pterodactylus.util.io.Closer;
-import net.pterodactylus.util.logging.Logging;
-import net.pterodactylus.util.xml.SimpleXML;
-import net.pterodactylus.util.xml.XML;
-
-import org.w3c.dom.Document;
-
-/**
- * Configuration backend that reads and writes its configuration from/to an XML
- * file.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class XMLConfigurationBackend implements ConfigurationBackend {
-
-	/** The logger. */
-	private static final Logger logger = Logging.getLogger(XMLConfigurationBackend.class.getName());
-
-	/** The node cache. */
-	private final Map<String, SimpleXML> nodeCache = new HashMap<String, SimpleXML>();
-
-	/** The configuration file. */
-	private final File configurationFile;
-
-	/** The last modification time of the configuration file. */
-	private long lastModified;
-
-	/** The root node of the document. */
-	private final SimpleXML rootNode;
-
-	/**
-	 * Creates a new backend backed by the given file.
-	 *
-	 * @param configurationFile
-	 *            The XML file to read the configuration from
-	 * @throws ConfigurationException
-	 *             if the XML can not be read or parsed
-	 */
-	public XMLConfigurationBackend(File configurationFile) throws ConfigurationException {
-		this(configurationFile, false);
-	}
-
-	/**
-	 * Creates a new backend backed by the given file.
-	 *
-	 * @param configurationFile
-	 *            The XML file to read the configuration from
-	 * @param create
-	 *            {@code true} to create a new configuration when loading the
-	 *            configuration from the given file fails, {@code false} to
-	 *            throw a {@link ConfigurationException}
-	 * @throws ConfigurationException
-	 *             if the XML can not be read or parsed
-	 */
-	public XMLConfigurationBackend(File configurationFile, boolean create) throws ConfigurationException {
-		this.configurationFile = configurationFile;
-		rootNode = readConfigurationFile(create);
-	}
-
-	/**
-	 * Reads and parses the configuration file.
-	 *
-	 * @param create
-	 *            {@code true} to create a new configuration if loading the
-	 *            configuration file fails, {@code false} to throw a
-	 *            {@link ConfigurationException}
-	 * @return The created root node
-	 * @throws ConfigurationException
-	 *             if the file can not be read or parsed
-	 */
-	private synchronized SimpleXML readConfigurationFile(boolean create) throws ConfigurationException {
-		FileInputStream configFileInputStream = null;
-		try {
-			configFileInputStream = new FileInputStream(configurationFile);
-			Document configurationDocument = XML.transformToDocument(configFileInputStream);
-			if (configurationDocument == null) {
-				if (!create) {
-					throw new ConfigurationException("can not parse XML document");
-				}
-				configurationDocument = new SimpleXML("config").getDocument();
-			}
-			nodeCache.clear();
-			return SimpleXML.fromDocument(configurationDocument);
-		} catch (FileNotFoundException fnfe1) {
-			if (!create) {
-				throw new ConfigurationException(fnfe1);
-			}
-			return new SimpleXML("config");
-		} finally {
-			Closer.close(configFileInputStream);
-		}
-	}
-
-	/**
-	 * Writes the current document (including changes) back to the
-	 * {@link #configurationFile}.
-	 *
-	 * @throws ConfigurationException
-	 *             if the document could not be written
-	 */
-	private synchronized void writeConfigurationFile() throws ConfigurationException {
-		FileOutputStream configurationFileOutputStream = null;
-		OutputStreamWriter configurationOutputStreamWriter = null;
-		try {
-			configurationFileOutputStream = new FileOutputStream(configurationFile);
-			configurationOutputStreamWriter = new OutputStreamWriter(configurationFileOutputStream, "UTF-8");
-			XML.writeToOutputStream(rootNode.getDocument(), configurationOutputStreamWriter);
-		} catch (IOException ioe1) {
-			throw new ConfigurationException(ioe1.getMessage(), ioe1);
-		} finally {
-			Closer.close(configurationOutputStreamWriter);
-			Closer.close(configurationFileOutputStream);
-		}
-	}
-
-	//
-	// INTERFACE ConfigurationBackend
-	//
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.ConfigurationBackend#getValue(java.lang.String)
-	 */
-	@Override
-	public String getValue(String attribute) throws ConfigurationException {
-		if (configurationFile.lastModified() > lastModified) {
-			logger.info("reloading configuration file " + configurationFile.getAbsolutePath());
-			readConfigurationFile(false);
-			lastModified = configurationFile.lastModified();
-		}
-		SimpleXML node = getNode(attribute);
-		String value = node.getValue();
-		logger.log(Level.FINEST, "attribute: “%1$s”, value: “%2$s”", new Object[] { attribute, value });
-		return value;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.config.ConfigurationBackend#putValue(java.lang.String,
-	 *      java.lang.String)
-	 */
-	@Override
-	public void putValue(String attribute, String value) throws ConfigurationException {
-		SimpleXML node = getNode(attribute, true);
-		node.setValue(value);
-		writeConfigurationFile();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void save() throws ConfigurationException {
-		writeConfigurationFile();
-	}
-
-	//
-	// PRIVATE METHODS
-	//
-
-	/**
-	 * Searches for the node with the given name and returns it. The given
-	 * attribute may contain several nodes, separated by a pipe character (“|”),
-	 * that describe where in the document hierarchy the node can be found.
-	 *
-	 * @param attribute
-	 *            The complete name of the node
-	 * @return The node, if found
-	 * @throws ConfigurationException
-	 *             if the node could not be found
-	 */
-	private SimpleXML getNode(String attribute) throws ConfigurationException {
-		return getNode(attribute, false);
-	}
-
-	/**
-	 * Searches for the node with the given name and returns it. The given
-	 * attribute may contain several nodes, separated by a pipe character (“|”),
-	 * that describe where in the document hierarchy the node can be found.
-	 *
-	 * @param attribute
-	 *            The complete name of the node
-	 * @param create
-	 *            {@code true} to create the node if it doesn’t exist,
-	 *            {@code false} to throw a {@link ConfigurationException} if it
-	 *            doesn’t exist
-	 * @return The node, if found
-	 * @throws ConfigurationException
-	 *             if the node could not be found
-	 */
-	private SimpleXML getNode(String attribute, boolean create) throws ConfigurationException {
-		if (nodeCache.containsKey(attribute)) {
-			return nodeCache.get(attribute);
-		}
-		StringTokenizer attributes = new StringTokenizer(attribute, "|/");
-		SimpleXML node = rootNode;
-		while (attributes.hasMoreTokens()) {
-			String nodeName = attributes.nextToken();
-			if (node.hasNode(nodeName)) {
-				node = node.getNode(nodeName);
-			} else {
-				if (!create) {
-					throw new AttributeNotFoundException(attribute);
-				}
-				node = node.append(nodeName);
-			}
-		}
-		nodeCache.put(attribute, node);
-		return node;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/config/package-info.java b/alien/src/net/pterodactylus/util/config/package-info.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/config/package-info.java
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * API for handling application configurations. <h2>Using a Configuration</h2>
- * Using the Configuration API consists of only three small steps. First, you
- * need to create a {@link net.pterodactylus.util.config.ConfigurationBackend} for the
- * configuration you want to access. Using the configuration backend you can
- * then create the {@link net.pterodactylus.util.config.Configuration} and start reading
- * integral data types from it. By writing specialized parsers you can handle
- * more abstract objects (e.g. for databases or message connectors) as well.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-package net.pterodactylus.util.config;
-
diff --git a/alien/src/net/pterodactylus/util/data/DefaultNode.java b/alien/src/net/pterodactylus/util/data/DefaultNode.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/data/DefaultNode.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * utils - DefaultNode.java - Copyright © 2009-2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.data;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Default implementation of the {@link Node} interface.
- *
- * @param <E>
- *            The type of the element to store
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-class DefaultNode<E extends Comparable<E>> implements Node<E> {
-
-	/** The parent node of this node. */
-	private final Node<E> parentNode;
-
-	/** The element contained in this node. */
-	private final E element;
-
-	/** The child nodes of this node. */
-	private final List<Node<E>> children = new ArrayList<Node<E>>();
-
-	/**
-	 * Creates a new root node.
-	 */
-	DefaultNode() {
-		this.parentNode = null;
-		this.element = null;
-	}
-
-	/**
-	 * Creates a new node with the given parent and element.
-	 *
-	 * @param parentNode
-	 *            The parent of this node
-	 * @param element
-	 *            The element of this node
-	 */
-	DefaultNode(Node<E> parentNode, E element) {
-		if ((parentNode == null) || (element == null)) {
-			throw new NullPointerException("null is not allowed as parent or element");
-		}
-		this.parentNode = parentNode;
-		this.element = element;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Node<E> getParent() {
-		return parentNode;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public E getElement() {
-		return element;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Node<E> addChild(E child) {
-		Node<E> childNode = new DefaultNode<E>(this, child);
-		children.add(childNode);
-		return childNode;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int size() {
-		return children.size();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Node<E> getChild(int childIndex) {
-		return children.get(childIndex);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Node<E> getChild(E element) {
-		for (Node<E> childNode : children) {
-			if (childNode.getElement().equals(element)) {
-				return childNode;
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean hasChild(Node<E> childNode) {
-		return children.contains(childNode);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean hasChild(E element) {
-		for (Node<E> childNode : children) {
-			if (childNode.getElement().equals(element)) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int getIndexOfChild(Node<E> childNode) {
-		int childIndex = 0;
-		for (Node<E> node : children) {
-			if (node.equals(childNode)) {
-				return childIndex;
-			}
-			childIndex++;
-		}
-		return -1;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int getIndexOfChild(E element) {
-		int childIndex = 0;
-		for (Node<E> node : children) {
-			if (node.getElement().equals(element)) {
-				return childIndex;
-			}
-			childIndex++;
-		}
-		return -1;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void removeChild(Node<E> childNode) {
-		children.remove(childNode);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void removeChild(E child) {
-		for (Node<E> childNode : children) {
-			if (child.equals(childNode.getElement())) {
-				children.remove(childNode);
-				break;
-			}
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void removeChild(int childIndex) {
-		children.remove(childIndex);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void removeAllChildren() {
-		children.clear();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Iterator<Node<E>> iterator() {
-		return children.iterator();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Node<E> findChild(E element) {
-		for (Node<E> childNode : children) {
-			Node<E> wantedNode = childNode.findChild(element);
-			if (wantedNode != null) {
-				return wantedNode;
-			}
-		}
-		if (this.element.equals(element)) {
-			return this;
-		}
-		return null;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void sortChildren() {
-		Collections.sort(children);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void sortChildren(Comparator<Node<E>> comparator) {
-		Collections.sort(children, comparator);
-	}
-
-	//
-	// INTERFACE Comparable
-	//
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int compareTo(Node<E> otherNode) {
-		return element.compareTo(otherNode.getElement());
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/data/Node.java b/alien/src/net/pterodactylus/util/data/Node.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/data/Node.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * utils - Node.java - Copyright © 2009-2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.data;
-
-import java.util.Comparator;
-import java.util.Iterator;
-
-/**
- * A node that can be stored in a {@link Tree}. A node has exactly one parent
- * (which is <code>null</code> if the node is the {@link Tree#getRootNode()} of
- * the tree) and an arbitrary amount of child nodes.
- *
- * @param <E>
- *            The type of the element to store
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface Node<E extends Comparable<E>> extends Iterable<Node<E>>, Comparable<Node<E>> {
-
-	/**
-	 * Returns the parent node of the node.
-	 *
-	 * @return The parent node
-	 */
-	public Node<E> getParent();
-
-	/**
-	 * Returns the element that is stored in the node.
-	 *
-	 * @return The node’s element
-	 */
-	public E getElement();
-
-	/**
-	 * Adds an element as a child to this node and returns the created node.
-	 *
-	 * @param child
-	 *            The child node’s element
-	 * @return The created child node
-	 */
-	public Node<E> addChild(E child);
-
-	/**
-	 * Returns the number of children this node has.
-	 *
-	 * @return The number of children
-	 */
-	public int size();
-
-	/**
-	 * Returns the child at the given index.
-	 *
-	 * @param index
-	 *            The index of the child
-	 * @return The child at the given index
-	 */
-	public Node<E> getChild(int index);
-
-	/**
-	 * Returns the direct child node that contains the given element.
-	 *
-	 * @param element
-	 *            The element
-	 * @return The direct child node containing the given element, or
-	 *         <code>null</code> if this node does not have a child node
-	 *         containing the given element
-	 */
-	public Node<E> getChild(E element);
-
-	/**
-	 * Returns whether the given node is a direct child of this node.
-	 *
-	 * @param childNode
-	 *            The child node
-	 * @return <code>true</code> if the given node is a direct child of this
-	 *         node, <code>false</code> otherwise
-	 */
-	public boolean hasChild(Node<E> childNode);
-
-	/**
-	 * Returns whether this node contains a child node containing the given
-	 * element.
-	 *
-	 * @param element
-	 *            The element
-	 * @return <code>true</code> if this node contains a direct child node
-	 *         containing the given element, <code>false</code> otherwise
-	 */
-	public boolean hasChild(E element);
-
-	/**
-	 * Returns the index of the given child node.
-	 *
-	 * @param childNode
-	 *            The child node
-	 * @return The index of the child node, or <code>-1</code> if the child node
-	 *         is not a child node of this node
-	 */
-	public int getIndexOfChild(Node<E> childNode);
-
-	/**
-	 * Returns the index of the child node containing the given element.
-	 *
-	 * @param element
-	 *            The element
-	 * @return The index of the child node, or <code>-1</code> if the child node
-	 *         is not a child node of this node
-	 */
-	public int getIndexOfChild(E element);
-
-	/**
-	 * Remove the given child node from this node. If the given node is not a
-	 * child of this node, nothing happens.
-	 *
-	 * @param childNode
-	 *            The child node to remove
-	 */
-	public void removeChild(Node<E> childNode);
-
-	/**
-	 * Removes the child node that contains the given element. The element in
-	 * the node is checked using {@link Object#equals(Object)}.
-	 *
-	 * @param child
-	 *            The child element to remove
-	 */
-	public void removeChild(E child);
-
-	/**
-	 * Removes the child at the given index.
-	 *
-	 * @param childIndex
-	 *            The index of the child to remove
-	 */
-	public void removeChild(int childIndex);
-
-	/**
-	 * Removes all children from this node.
-	 */
-	public void removeAllChildren();
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Iterator<Node<E>> iterator();
-
-	/**
-	 * Searches this node’s children recursively for a node that contains the
-	 * given element.
-	 *
-	 * @param element
-	 *            The element to search
-	 * @return The node that contains the given element, or <code>null</code> if
-	 *         no node could be found
-	 */
-	public Node<E> findChild(E element);
-
-	/**
-	 * Sorts all children according to their natural order.
-	 */
-	public void sortChildren();
-
-	/**
-	 * Sorts all children with the given comparator.
-	 *
-	 * @param comparator
-	 *            The comparator used to sort the children
-	 */
-	public void sortChildren(Comparator<Node<E>> comparator);
-
-}
diff --git a/alien/src/net/pterodactylus/util/data/Tree.java b/alien/src/net/pterodactylus/util/data/Tree.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/data/Tree.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * utils - Tree.java - Copyright © 2009-2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.data;
-
-/**
- * A tree structure in which every node can have an arbitrary amount of
- * children.
- *
- * @param <E>
- *            The type of the element to store
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Tree<E extends Comparable<E>> {
-
-	/** The root node of the tree. */
-	private final Node<E> rootNode = new DefaultNode<E>();
-
-	/**
-	 * Returns the root node of the tree.
-	 *
-	 * @return The root node of the tree
-	 */
-	public Node<E> getRootNode() {
-		return rootNode;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/AbstractDatabase.java b/alien/src/net/pterodactylus/util/database/AbstractDatabase.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/AbstractDatabase.java
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * utils - AbstractDatabase.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.sql.DataSource;
-
-import net.pterodactylus.util.io.Closer;
-
-/**
- * Abstract implementation of a {@link Database}. This already contains all the
- * heavy lifting, the only thing that is still left is the actual database
- * connection. This is done by overriding {@link #getConnection()} to return a
- * new connection to a database.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public abstract class AbstractDatabase implements Database {
-
-	//
-	// ACTIONS
-	//
-
-	/**
-	 * @see net.pterodactylus.util.database.Database#getSingle(net.pterodactylus.util.database.Query,
-	 *      net.pterodactylus.util.database.ObjectCreator)
-	 */
-	@Override
-	public <T> T getSingle(Query query, ObjectCreator<T> objectCreator) throws DatabaseException {
-		return new SingleDatabaseWorker<T>(query, objectCreator).work();
-	}
-
-	/**
-	 * @see net.pterodactylus.util.database.Database#getMultiple(net.pterodactylus.util.database.Query,
-	 *      net.pterodactylus.util.database.ObjectCreator)
-	 */
-	@Override
-	public <T> List<T> getMultiple(Query query, ObjectCreator<T> objectCreator) throws DatabaseException {
-		return new MultipleDatabaseWorker<T>(query, objectCreator).work();
-	}
-
-	/**
-	 * @see net.pterodactylus.util.database.Database#insert(net.pterodactylus.util.database.Query)
-	 */
-	@Override
-	public long insert(Query query) throws DatabaseException {
-		return new InsertDatabaseWorker(query).work();
-	}
-
-	/**
-	 * @see net.pterodactylus.util.database.Database#update(net.pterodactylus.util.database.Query)
-	 */
-	@Override
-	public int update(Query query) throws DatabaseException {
-		return new UpdateDatabaseWorker(query).work();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.database.Database#process(Query, ResultProcessor)
-	 */
-	@Override
-	public void process(Query query, ResultProcessor resultProcessor) throws DatabaseException {
-		new ProcessWorker(query, resultProcessor).work();
-	}
-
-	//
-	// STATIC METHODS
-	//
-
-	/**
-	 * Creates a database from a {@link DataSource}.
-	 *
-	 * @param dataSource
-	 *            The data source to create a database from
-	 * @return The database that uses the given data source
-	 */
-	public static Database fromDataSource(final DataSource dataSource) {
-		return new AbstractDatabase() {
-
-			@Override
-			protected void returnConnection(Connection connection) {
-				Closer.close(connection);
-			}
-
-			@Override
-			protected Connection getConnection() throws SQLException {
-				return dataSource.getConnection();
-			}
-		};
-	}
-
-	//
-	// ABSTRACT METHODS
-	//
-
-	/**
-	 * Creates a new connection to the database.
-	 *
-	 * @return The created connection
-	 * @throws SQLException
-	 *             if a database error occurs
-	 */
-	protected abstract Connection getConnection() throws SQLException;
-
-	/**
-	 * Returns the connection after it has been used. This method can be used to
-	 * simply close the connection, or to return it to a connection pool.
-	 *
-	 * @param connection
-	 *            The connection to return
-	 */
-	protected abstract void returnConnection(Connection connection);
-
-	/**
-	 * Abstract base class for database workers. A database worker executes a
-	 * query and returns a result that depends on the type of execute query.
-	 * <p>
-	 * This database worker contains several {@code run()} methods, each for
-	 * different “stages” of a normal JDBC interaction: {@link #run(Connection)}
-	 * is run with a {@link Connection} from
-	 * {@link AbstractDatabase#getConnection()}, {@link #run(PreparedStatement)}
-	 * with a {@link PreparedStatement} that was generated by
-	 * {@link Query#createStatement(Connection)}, and {@link #run(ResultSet)}
-	 * with a {@link ResultSet} that was obtained by
-	 * {@link PreparedStatement#executeQuery()}. When a resource object was
-	 * obtained by a not-overridden method of this class, the resource will be
-	 * closed after the “deeper” {@code run()} method returns. Each method can
-	 * be overridden if the default behaviour is not appropriate for the
-	 * implementing database worker.
-	 *
-	 * @param <T>
-	 *            The type of the result
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	private abstract class AbstractDatabaseWorker<T> {
-
-		/** The query to execute. */
-		protected final Query query;
-
-		/**
-		 * Creates a new abstract database worker that will execute the given
-		 * query.
-		 *
-		 * @param query
-		 *            The query to execute
-		 */
-		protected AbstractDatabaseWorker(Query query) {
-			this.query = query;
-		}
-
-		/**
-		 * Processes the given result set. The default implementation simply
-		 * returns {@code null} here.
-		 *
-		 * @param resultSet
-		 *            The result set to process
-		 * @return The worker’s result
-		 * @throws SQLException
-		 *             if an SQL error occurs
-		 */
-		protected T run(ResultSet resultSet) throws SQLException {
-			return null;
-		}
-
-		/**
-		 * Processes the given prepared statement. The default implementation
-		 * creates a {@link ResultSet} with
-		 * {@link PreparedStatement#executeQuery()} and hands it over to
-		 * {@link #run(ResultSet)}, closing it afterwards.
-		 *
-		 * @param preparedStatement
-		 *            The prepared statement to process
-		 * @return The worker’s result
-		 * @throws SQLException
-		 *             if an SQL error occurs
-		 */
-		protected T run(PreparedStatement preparedStatement) throws SQLException {
-			ResultSet resultSet = null;
-			try {
-				resultSet = preparedStatement.executeQuery();
-				return run(resultSet);
-			} finally {
-				Closer.close(resultSet);
-			}
-		}
-
-		/**
-		 * Processes the given connection. The default implementation uses the
-		 * {@link #query} to {@link Query#createStatement(Connection) create a
-		 * prepared statement} and hand it over to
-		 * {@link #run(PreparedStatement)}, closing the statement afterwards.
-		 *
-		 * @param connection
-		 *            The connection to interact with
-		 * @return The worker’s result
-		 * @throws SQLException
-		 *             if an SQL error occurs
-		 */
-		protected T run(Connection connection) throws SQLException {
-			PreparedStatement preparedStatement = null;
-			try {
-				preparedStatement = query.createStatement(connection);
-				return run(preparedStatement);
-			} finally {
-				Closer.close(preparedStatement);
-			}
-		}
-
-		/**
-		 * Performs the work of this database worker. The default database
-		 * worker retrieves a connection from
-		 * {@link AbstractDatabase#getConnection()} and processes it with
-		 * {@link #run(Connection)},
-		 * {@link AbstractDatabase#returnConnection(Connection) returning} it
-		 * afterwards.
-		 *
-		 * @return The result of the worker
-		 * @throws DatabaseException
-		 *             if a database error occurs
-		 */
-		public T work() throws DatabaseException {
-			Connection connection = null;
-			try {
-				connection = getConnection();
-				return run(connection);
-			} catch (SQLException sqle1) {
-				throw new DatabaseException(sqle1);
-			} finally {
-				returnConnection(connection);
-			}
-		}
-
-	}
-
-	/**
-	 * A database worker that reads a single row from a result and creates an
-	 * object from it.
-	 *
-	 * @param <T>
-	 *            The type of the created object
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	private class SingleDatabaseWorker<T> extends AbstractDatabaseWorker<T> {
-
-		/** The object creator. */
-		private final ObjectCreator<T> objectCreator;
-
-		/**
-		 * Creates a new database worker that returns a single result.
-		 *
-		 * @param query
-		 *            The query to execute
-		 * @param objectCreator
-		 *            The object creator
-		 */
-		public SingleDatabaseWorker(Query query, ObjectCreator<T> objectCreator) {
-			super(query);
-			this.objectCreator = objectCreator;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		protected T run(ResultSet resultSet) throws SQLException {
-			if (resultSet.next()) {
-				return objectCreator.createObject(resultSet);
-			}
-			return null;
-		}
-
-	}
-
-	/**
-	 * Database worker that returns multiple results of a query.
-	 *
-	 * @param <T>
-	 *            The type of the results
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	private class MultipleDatabaseWorker<T> extends AbstractDatabaseWorker<List<T>> {
-
-		/** The object creator. */
-		private final ObjectCreator<T> objectCreator;
-
-		/**
-		 * Creates a new database worker that returns multiple results.
-		 *
-		 * @param query
-		 *            The query to execute
-		 * @param objectCreator
-		 *            The object creator
-		 */
-		public MultipleDatabaseWorker(Query query, ObjectCreator<T> objectCreator) {
-			super(query);
-			this.objectCreator = objectCreator;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		protected List<T> run(ResultSet resultSet) throws SQLException {
-			List<T> results = new ArrayList<T>();
-			while (resultSet.next()) {
-				T object = objectCreator.createObject(resultSet);
-				results.add(object);
-			}
-			return results;
-		}
-
-	}
-
-	/**
-	 * A database worker that executes an insert and returns the automatically
-	 * generated ID.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	private class InsertDatabaseWorker extends AbstractDatabaseWorker<Long> {
-
-		/**
-		 * Creates a new database worker that performs an insert.
-		 *
-		 * @param query
-		 *            The query to execute
-		 */
-		public InsertDatabaseWorker(Query query) {
-			super(query);
-		}
-
-		/**
-		 * @see net.pterodactylus.util.database.AbstractDatabase.AbstractDatabaseWorker#run(java.sql.Connection)
-		 */
-		@Override
-		protected Long run(PreparedStatement preparedStatement) throws SQLException {
-			preparedStatement.executeUpdate();
-			ResultSet generatedKeys = null;
-			try {
-				generatedKeys = preparedStatement.getGeneratedKeys();
-				if (generatedKeys.next()) {
-					return generatedKeys.getLong(1);
-				}
-				return -1L;
-			} finally {
-				Closer.close(generatedKeys);
-			}
-		}
-
-	}
-
-	/**
-	 * Database worker that performs an update and returns the number of updated
-	 * or changed rows.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	private class UpdateDatabaseWorker extends AbstractDatabaseWorker<Integer> {
-
-		/**
-		 * Creates a new database worker that performs an update.
-		 *
-		 * @param query
-		 *            The query to execute
-		 */
-		public UpdateDatabaseWorker(Query query) {
-			super(query);
-		}
-
-		/**
-		 * @see net.pterodactylus.util.database.AbstractDatabase.AbstractDatabaseWorker#run(java.sql.PreparedStatement)
-		 */
-		@Override
-		protected Integer run(PreparedStatement preparedStatement) throws SQLException {
-			return preparedStatement.executeUpdate();
-		}
-
-	}
-
-	/**
-	 * A database worker that processes all result rows with an
-	 * {@link ObjectCreator} instance which does not need to return meaningful
-	 * values.
-	 *
-	 * @author <a href="mailto:david.roden@sysart.de">David Roden</a>
-	 */
-	private class ProcessWorker extends AbstractDatabaseWorker<Void> {
-
-		/** The object creator used as result processor. */
-		private final ResultProcessor resultProcessor;
-
-		/**
-		 * Creates a new process worker.
-		 *
-		 * @param query
-		 *            The query to execute
-		 * @param resultProcessor
-		 *            The result processor
-		 */
-		public ProcessWorker(Query query, ResultProcessor resultProcessor) {
-			super(query);
-			this.resultProcessor = resultProcessor;
-		}
-
-		/**
-		 * @see net.pterodactylus.util.database.AbstractDatabase.AbstractDatabaseWorker#run(java.sql.ResultSet)
-		 */
-		@Override
-		protected Void run(ResultSet resultSet) throws SQLException {
-			while (resultSet.next()) {
-				resultProcessor.processResult(resultSet);
-			}
-			return null;
-		}
-
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/AndWhereClause.java b/alien/src/net/pterodactylus/util/database/AndWhereClause.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/AndWhereClause.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * utils - AndWhereClause.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * {@link WhereClause} implementation that performs an AND conjunction of an
- * arbitrary amount of where clauses.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class AndWhereClause implements WhereClause {
-
-	/** The list of where clauses. */
-	private final List<WhereClause> whereClauses = new ArrayList<WhereClause>();
-
-	/**
-	 * Creates a new AND where clause.
-	 */
-	public AndWhereClause() {
-		/* do nothing. */
-	}
-
-	/**
-	 * Creates a new AND where clause.
-	 *
-	 * @param whereClauses
-	 *            The where clauses to connect
-	 */
-	public AndWhereClause(WhereClause... whereClauses) {
-		for (WhereClause whereClause : whereClauses) {
-			this.whereClauses.add(whereClause);
-		}
-	}
-
-	/**
-	 * Creates a new AND where clause.
-	 *
-	 * @param whereClauses
-	 *            The where clauses to connect
-	 */
-	public AndWhereClause(Collection<WhereClause> whereClauses) {
-		this.whereClauses.addAll(whereClauses);
-	}
-
-	/**
-	 * Adds the given WHERE clause.
-	 *
-	 * @param whereClause
-	 *            The WHERE clause to add
-	 * @return This WHERE clause (to allow method chaining)
-	 */
-	public AndWhereClause add(WhereClause whereClause) {
-		whereClauses.add(whereClause);
-		return this;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public List<Parameter<?>> getParameters() {
-		ArrayList<Parameter<?>> parameters = new ArrayList<Parameter<?>>();
-		for (WhereClause whereClause : whereClauses) {
-			parameters.addAll(whereClause.getParameters());
-		}
-		return parameters;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void render(Writer writer) throws IOException {
-		if (whereClauses.isEmpty()) {
-			writer.write("(1 = 1)");
-		}
-		boolean first = true;
-		for (WhereClause whereClause : whereClauses) {
-			if (!first) {
-				writer.write(" AND ");
-			}
-			writer.write("(");
-			whereClause.render(writer);
-			writer.write(")");
-			first = false;
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/CountField.java b/alien/src/net/pterodactylus/util/database/CountField.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/CountField.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * utils - CountField.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-/**
- * Convenience {@link Field} implementation that creates a field that returns
- * the count of all rows.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class CountField extends Field {
-
-	/**
-	 * Creates a new count field.
-	 */
-	public CountField() {
-		super("COUNT(*)");
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/DataObject.java b/alien/src/net/pterodactylus/util/database/DataObject.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/DataObject.java
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * utils - DataObject.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import net.pterodactylus.util.database.Parameter.LongParameter;
-import net.pterodactylus.util.database.Query.Type;
-
-/**
- * A data object represents a data row from a database table. The
- * {@link DataObject} class is intended to make it easier to read and write
- * objects from and to a database. In order to achieve this some restrictions
- * had to be posed upon the data object and its representation in the database.
- * <ul>
- * <li>A data object is required to have an ID of the type {@code long}.</li>
- * <li>Every data object is required to have a corresponding entry in the
- * database. It is not possible to create a data object in memory first and then
- * save it to the database.</li>
- * </ul>
- *
- * @param <D>
- *            The type of the data object
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public abstract class DataObject<D extends DataObject<D>> {
-
-	/** The data object factory that created this object. */
-	private final DataObjectFactory<D> dataObjectFactory;
-
-	/** The ID of the data object. */
-	private long id;
-
-	/** The properties of this data object. */
-	private final Map<String, Object> properties = new HashMap<String, Object>();
-
-	/** Whether the object has been written to. */
-	private boolean dirty;
-
-	/**
-	 * Creates a new data object.
-	 *
-	 * @param dataObjectFactory
-	 *            The data object factory that create this object
-	 * @param id
-	 *            The ID of the data object
-	 */
-	protected DataObject(DataObjectFactory<D> dataObjectFactory, long id) {
-		this.dataObjectFactory = dataObjectFactory;
-		this.id = id;
-	}
-
-	//
-	// ACCESSORS
-	//
-
-	/**
-	 * Returns the ID of the data object.
-	 *
-	 * @return The ID of the data object
-	 */
-	public final long getId() {
-		return id;
-	}
-
-	//
-	// PROTECTED METHODS
-	//
-
-	/**
-	 * Sets the property with the given name to the given value.
-	 *
-	 * @param name
-	 *            The name of the property
-	 * @param value
-	 *            The value of the property
-	 */
-	protected void setProperty(String name, Object value) {
-		properties.put(name, value);
-		dirty = true;
-	}
-
-	/**
-	 * Returns the value of the property with the given name.
-	 *
-	 * @param name
-	 *            The name of the property
-	 * @return The value of the property, or {@code null} if the property does
-	 *         not exist
-	 */
-	protected Object getProperty(String name) {
-		return properties.get(name);
-	}
-
-	/**
-	 * Clears the dirty flag.
-	 */
-	protected void clearDirtyFlag() {
-		dirty = false;
-	}
-
-	//
-	// METHODS FOR SUBCLASSES TO OVERRIDE
-	//
-
-	/**
-	 * Retuns the fields that need to be saved when the object has changed.
-	 *
-	 * @return The fields that need to be saved
-	 */
-	protected abstract Set<ValueField> getSaveFields();
-
-	//
-	// ACTIONS
-	//
-
-	/**
-	 * Saves this data object to the database if it is dirty.
-	 *
-	 * @param database
-	 *            The database to store the object to
-	 * @throws DatabaseException
-	 *             if a database error occurs
-	 */
-	public void save(Database database) throws DatabaseException {
-		save(database, false);
-	}
-
-	/**
-	 * Saves this data object to the database if it is dirty, or if the
-	 * {@code force} parameter is {@code true}.
-	 *
-	 * @param database
-	 *            The database to store the object to
-	 * @param force
-	 *            {@code true} to force saving to the database, {@code false} to
-	 *            not save if the object is not dirty
-	 * @throws DatabaseException
-	 *             if a database error occurs
-	 */
-	public void save(Database database, boolean force) throws DatabaseException {
-		if (id != -1 && !dirty && !force) {
-			return;
-		}
-		if (id == -1) {
-			Query query = new Query(Type.INSERT, dataObjectFactory.getTable());
-			for (ValueField saveField : getSaveFields()) {
-				query.addValueField(saveField);
-			}
-			id = database.insert(query);
-			clearDirtyFlag();
-			return;
-		}
-		Query query = new Query(Type.UPDATE, dataObjectFactory.getTable());
-		for (ValueField saveField : getSaveFields()) {
-			query.addValueField(saveField);
-		}
-		query.addWhereClause(new ValueFieldWhereClause(new ValueField(dataObjectFactory.getIdentityColumn(), new LongParameter(id))));
-		database.update(query);
-		clearDirtyFlag();
-	}
-
-	/**
-	 * Deletes this data object from the database. This object should not be
-	 * used afterwards, especially the {@link #save(Database)} methods should
-	 * NOT be called!
-	 *
-	 * @param database
-	 *            The database to delete the object from
-	 * @return {@code true} if the object was deleted, {@code false} otherwise
-	 * @throws DatabaseException
-	 *             if a database error occurs
-	 */
-	public boolean delete(Database database) throws DatabaseException {
-		return DataObject.deleteById(database, dataObjectFactory, getId());
-	}
-
-	//
-	// STATIC METHODS
-	//
-
-	/**
-	 * Loads a data object from the given database by the given ID.
-	 *
-	 * @param database
-	 *            The database to load the object from
-	 * @param dataObjectFactory
-	 *            The data object factory
-	 * @param id
-	 *            The ID to load
-	 * @param <D>
-	 *            The type of the object to load
-	 * @return The loaded object, or {@code null} if there was no object with
-	 *         the given ID
-	 * @throws DatabaseException
-	 *             if a database error occurs
-	 */
-	public static <D extends DataObject<D>> D loadById(Database database, DataObjectFactory<D> dataObjectFactory, long id) throws DatabaseException {
-		return loadByWhereClause(database, dataObjectFactory, new ValueFieldWhereClause(new ValueField(dataObjectFactory.getIdentityColumn(), new LongParameter(id))));
-	}
-
-	/**
-	 * Loads the first data object that matches the given where clause from the
-	 * given database.
-	 *
-	 * @param database
-	 *            The database to load the object from
-	 * @param dataObjectFactory
-	 *            The data object factory
-	 * @param whereClause
-	 *            The where clause to match the object
-	 * @param <D>
-	 *            The type of the object to load
-	 * @param orderFields
-	 *            The fields to order the results by
-	 * @return The first object that matched the wher clause, or {@code null} if
-	 *         there was no object that matched
-	 * @throws DatabaseException
-	 *             if a database error occurs
-	 */
-	public static <D extends DataObject<D>> D loadByWhereClause(Database database, DataObjectFactory<D> dataObjectFactory, WhereClause whereClause, OrderField... orderFields) throws DatabaseException {
-		Query query = new Query(Type.SELECT, dataObjectFactory.getTable());
-		query.addWhereClause(whereClause);
-		for (OrderField orderField : orderFields) {
-			query.addOrderField(orderField);
-		}
-		return database.getSingle(query, dataObjectFactory);
-	}
-
-	/**
-	 * Loads all data objects that match the given where clause from the given
-	 * database.
-	 *
-	 * @param database
-	 *            The database to load the objects from
-	 * @param dataObjectFactory
-	 *            The data object factory
-	 * @param whereClause
-	 *            The where clause to match the objects
-	 * @param <D>
-	 *            The type of the objects to load
-	 * @param orderFields
-	 *            The order fields to sort the results by
-	 * @return All objects that matched the wher clause, or an empty list if
-	 *         there was no object that matched
-	 * @throws DatabaseException
-	 *             if a database error occurs
-	 */
-	public static <D extends DataObject<D>> List<D> loadAllByWhereClause(Database database, DataObjectFactory<D> dataObjectFactory, WhereClause whereClause, OrderField... orderFields) throws DatabaseException {
-		Query query = new Query(Type.SELECT, dataObjectFactory.getTable());
-		query.addWhereClause(whereClause);
-		query.addOrderField(orderFields);
-		return database.getMultiple(query, dataObjectFactory);
-	}
-
-	/**
-	 * Creates a new data object with the given value fields.
-	 *
-	 * @param <D>
-	 *            The type of the data object
-	 * @param database
-	 *            The database to create the object in
-	 * @param dataObjectFactory
-	 *            The data object factory
-	 * @param valueFields
-	 *            The value fields
-	 * @return The created object
-	 * @throws DatabaseException
-	 *             if a database error occurs
-	 */
-	public static <D extends DataObject<D>> D create(Database database, DataObjectFactory<D> dataObjectFactory, ValueField... valueFields) throws DatabaseException {
-		Query query = new Query(Type.INSERT, dataObjectFactory.getTable());
-		query.addValueField(valueFields);
-		long id = database.insert(query);
-		return loadById(database, dataObjectFactory, id);
-	}
-
-	/**
-	 * Deletes the data object with the given ID from the database.
-	 *
-	 * @param <D>
-	 *            The type of the data object
-	 * @param database
-	 *            The database to delete the object from
-	 * @param dataObjectFactory
-	 *            The data object factory
-	 * @param id
-	 *            The ID of the object to delete
-	 * @return {@code true} if an object was deleted, {@code false} otherwise
-	 * @throws DatabaseException
-	 *             if a database error occurs
-	 */
-	public static <D extends DataObject<D>> boolean deleteById(Database database, DataObjectFactory<D> dataObjectFactory, long id) throws DatabaseException {
-		return deleteByWhereClause(database, dataObjectFactory, new ValueFieldWhereClause(new ValueField(dataObjectFactory.getIdentityColumn(), new LongParameter(id)))) == 1;
-	}
-
-	/**
-	 * Deletes all objects from the database that match the given WHERE clause.
-	 *
-	 * @param <D>
-	 *            The type of the data object
-	 * @param database
-	 *            The database to delete the objects from
-	 * @param dataObjectFactory
-	 *            The data object factory
-	 * @param whereClause
-	 *            The WHERE clause to match for deletion
-	 * @return The number of deleted objects
-	 * @throws DatabaseException
-	 *             if a database error occurs
-	 */
-	public static <D extends DataObject<D>> int deleteByWhereClause(Database database, DataObjectFactory<D> dataObjectFactory, WhereClause whereClause) throws DatabaseException {
-		Query query = new Query(Type.DELETE, dataObjectFactory.getTable());
-		query.addWhereClause(whereClause);
-		return database.update(query);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/DataObjectFactory.java b/alien/src/net/pterodactylus/util/database/DataObjectFactory.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/DataObjectFactory.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * utils - DataObjectFactory.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-
-/**
- * The data object factory knows details about the specifics of how a
- * {@link DataObject} is persisted to the database.
- *
- * @param <D>
- *            The type of the data object to create
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface DataObjectFactory<D extends DataObject<D>> extends ObjectCreator<D> {
-
-	/**
-	 * Returns the table the data object is stored in.
-	 *
-	 * @return The name of the table
-	 */
-	public String getTable();
-
-	/**
-	 * Returns the name of the column that holds the identity.
-	 *
-	 * @return The name of the identity column
-	 */
-	public String getIdentityColumn();
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/Database.java b/alien/src/net/pterodactylus/util/database/Database.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/Database.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * utils - Database.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-import java.util.List;
-
-/**
- * Interface for the database abstraction. This interface holds methods that
- * allow defined access to a database.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface Database {
-
-	/**
-	 * Returns a single object from a database.
-	 *
-	 * @param <T>
-	 *            The type of the object
-	 * @param query
-	 *            The query to execute
-	 * @param objectCreator
-	 *            The object creator
-	 * @return The created object, or {@code null} if the {@code query} did not
-	 *         yield any results
-	 * @throws DatabaseException
-	 *             if a database error occurs
-	 */
-	public <T> T getSingle(Query query, ObjectCreator<T> objectCreator) throws DatabaseException;
-
-	/**
-	 * Returns multiple query results.
-	 *
-	 * @param <T>
-	 *            The type of the results
-	 * @param query
-	 *            The query to execute
-	 * @param objectCreator
-	 *            The object creator
-	 * @return A list containing the objects from the database
-	 * @throws DatabaseException
-	 *             if a database error occurs
-	 */
-	public <T> List<T> getMultiple(Query query, ObjectCreator<T> objectCreator) throws DatabaseException;
-
-	/**
-	 * Inserts an object into the database and returns the automatically
-	 * generated ID, if any.
-	 *
-	 * @param query
-	 *            The query to execute
-	 * @return The automatically generated ID, or {@code -1} if no ID was
-	 *         generated
-	 * @throws DatabaseException
-	 *             if a database error occurs
-	 */
-	public long insert(Query query) throws DatabaseException;
-
-	/**
-	 * Updates objects in the database.
-	 *
-	 * @param query
-	 *            The query to execute
-	 * @return The number of changed objects in the database
-	 * @throws DatabaseException
-	 *             if a database error occurs
-	 */
-	public int update(Query query) throws DatabaseException;
-
-	/**
-	 * Processes the results of the given query with the given result processor.
-	 *
-	 * @param query
-	 *            The query to execute
-	 * @param resultProcessor
-	 *            The result processor used to process the result set
-	 * @throws DatabaseException
-	 *             if a database error occurs
-	 */
-	public void process(Query query, ResultProcessor resultProcessor) throws DatabaseException;
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/DatabaseException.java b/alien/src/net/pterodactylus/util/database/DatabaseException.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/DatabaseException.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * utils - DatabaseException.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-/**
- * Exception that signals a database error.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class DatabaseException extends Exception {
-
-	/**
-	 * Creates a new database exception.
-	 */
-	public DatabaseException() {
-		// TODO Auto-generated constructor stub
-	}
-
-	/**
-	 * Creates a new database exception.
-	 *
-	 * @param message
-	 *            The message of the exception
-	 */
-	public DatabaseException(String message) {
-		super(message);
-	}
-
-	/**
-	 * Creates a new database exception.
-	 *
-	 * @param cause
-	 *            The cause of the exception
-	 */
-	public DatabaseException(Throwable cause) {
-		super(cause);
-	}
-
-	/**
-	 * Creates a new database exception.
-	 *
-	 * @param message
-	 *            The message of the exception
-	 * @param cause
-	 *            The cause of the exception
-	 */
-	public DatabaseException(String message, Throwable cause) {
-		super(message, cause);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/Field.java b/alien/src/net/pterodactylus/util/database/Field.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/Field.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * utils - Field.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-/**
- * A field stores the name of a database column.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Field {
-
-	/** The name of the field. */
-	private final String name;
-
-	/**
-	 * Creates a new field.
-	 *
-	 * @param name
-	 *            The name of the field
-	 */
-	public Field(String name) {
-		this.name = name;
-	}
-
-	/**
-	 * Returns the name of the field.
-	 *
-	 * @return The name of the field
-	 */
-	public String getName() {
-		return name;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean equals(Object object) {
-		if (!(object instanceof Field)) {
-			return false;
-		}
-		Field field = (Field) object;
-		return field.name.equals(name);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int hashCode() {
-		return name.hashCode();
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/Limit.java b/alien/src/net/pterodactylus/util/database/Limit.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/Limit.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * utils - Limit.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-/**
- * A LIMIT clause limits the results that are returned.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Limit {
-
-	/** The index of the first result to retrieve, 0-based. */
-	private final long start;
-
-	/** The number of results to retrieve. */
-	private final long number;
-
-	/**
-	 * Creates a new limit clause that retrieves the given number of results.
-	 *
-	 * @param number
-	 *            The number of results to retrieve
-	 */
-	public Limit(long number) {
-		this(0, number);
-	}
-
-	/**
-	 * Creates a new limit clause that retrieves the given number of results,
-	 * starting at the given index.
-	 *
-	 * @param start
-	 *            The index of the first result to retrieve
-	 * @param number
-	 *            The number of results to retrieve
-	 */
-	public Limit(long start, long number) {
-		this.start = start;
-		this.number = number;
-	}
-
-	/**
-	 * Returns the index of the first result to retrieve.
-	 *
-	 * @return The index of the first result to retrieve
-	 */
-	public long getStart() {
-		return start;
-	}
-
-	/**
-	 * Returns the number of results to retreive.
-	 *
-	 * @return The number of results to retrieve
-	 */
-	public long getNumber() {
-		return number;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/MapCreator.java b/alien/src/net/pterodactylus/util/database/MapCreator.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/MapCreator.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * utils - MapCreator.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * {@link ObjectCreator} implementation that creates a {@link Map} from the
- * current row of a {@link ResultSet}. The display names of the columns are used
- * as keys, the values are mapped to objects of a fitting type.
- * <p>
- * The following {@link Types} are currently mapped:
- * <ul>
- * <li>{@link Types#INTEGER} is mapped to {@link Integer}.</li>
- * <li>{@link Types#BIGINT} is mapped to {@link Long}.</li>
- * <li>{@link Types#BOOLEAN} is mapped to {@link Boolean}.</li>
- * <li>{@link Types#VARCHAR} is mapped to {@link String}.</li>
- * </ul>
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class MapCreator implements ObjectCreator<Map<String, Object>> {
-
-	/**
-	 * @see net.pterodactylus.util.database.ObjectCreator#createObject(java.sql.ResultSet)
-	 */
-	@Override
-	public Map<String, Object> createObject(ResultSet resultSet) throws SQLException {
-		Map<String, Object> result = new HashMap<String, Object>();
-		ResultSetMetaData metadata = resultSet.getMetaData();
-		for (int column = 1; column <= metadata.getColumnCount(); column++) {
-			int columnType = metadata.getColumnType(column);
-			String columnLabel = metadata.getColumnLabel(column);
-			if (columnType == Types.INTEGER) {
-				result.put(columnLabel, resultSet.getInt(column));
-			} else if (columnType == Types.BIGINT) {
-				result.put(columnLabel, resultSet.getLong(column));
-			} else if (columnType == Types.DECIMAL) {
-				result.put(columnLabel, resultSet.getDouble(column));
-			} else if (columnType == Types.BOOLEAN) {
-				result.put(columnLabel, resultSet.getBoolean(column));
-			} else if (columnType == Types.VARCHAR) {
-				result.put(columnLabel, resultSet.getString(column));
-			} else if (columnType == Types.LONGVARCHAR) {
-				result.put(columnLabel, resultSet.getString(column));
-			} else if (columnType == Types.DATE) {
-				result.put(columnLabel, resultSet.getDate(column));
-			} else {
-				System.out.println("unknown type (" + columnType + ") for column “" + columnLabel + "”.");
-			}
-		}
-		return result;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/MatchAllWhereClause.java b/alien/src/net/pterodactylus/util/database/MatchAllWhereClause.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/MatchAllWhereClause.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * utils - MatchAllWhereClause.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * TODO
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class MatchAllWhereClause implements WhereClause {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public List<Parameter<?>> getParameters() {
-		return Collections.emptyList();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void render(Writer writer) throws IOException {
-		writer.write("(1 = 1)");
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/ObjectCreator.java b/alien/src/net/pterodactylus/util/database/ObjectCreator.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/ObjectCreator.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * utils - ObjectCreator.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-/**
- * An <em>object creator</em> is able to create a new object of type {@code T}
- * from the current row of a {@link ResultSet}.
- *
- * @param <T>
- *            The type of the created object
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface ObjectCreator<T> {
-
-	/** A default integer creator. */
-	public static final IntegerCreator INTEGER_CREATOR = new IntegerCreator();
-
-	/** A default string creator. */
-	public static final StringCreator STRING_CREATOR = new StringCreator();
-
-	/**
-	 * Creates a new object from the current row in the given result set.
-	 *
-	 * @param resultSet
-	 *            The result set to create a new object from
-	 * @return {@code null} if the result set is not on a valid row, i.e. if the
-	 *         result set is empty or there are no more rows left in it
-	 * @throws SQLException
-	 *             if an SQL error occurs
-	 */
-	public T createObject(ResultSet resultSet) throws SQLException;
-
-	/**
-	 * Creates a single integer from a result set. When the column contained the
-	 * SQL NULL value, {@code null} is returned instead of {@code 0}; this
-	 * differs from {@link ResultSet#getInt(int)}.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public static class IntegerCreator implements ObjectCreator<Integer> {
-
-		/** The index of the value. */
-		private final int index;
-
-		/**
-		 * Creates a new object creator that returns the integer value of the
-		 * first column of the result set.
-		 */
-		public IntegerCreator() {
-			this(1);
-		}
-
-		/**
-		 * Creates a new object creator that returns the integer value of the
-		 * given column.
-		 *
-		 * @param index
-		 *            The index of the column to return
-		 */
-		public IntegerCreator(int index) {
-			this.index = index;
-		}
-
-		/**
-		 * @see net.pterodactylus.util.database.ObjectCreator#createObject(java.sql.ResultSet)
-		 */
-		@Override
-		public Integer createObject(ResultSet resultSet) throws SQLException {
-			Integer result = resultSet.getInt(index);
-			if (resultSet.wasNull()) {
-				return null;
-			}
-			return result;
-		}
-
-	}
-
-	/**
-	 * Creates a single {@link String} from a result set.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public static class StringCreator implements ObjectCreator<String> {
-
-		/** The index of the value. */
-		private final int index;
-
-		/**
-		 * Creates a new object creator that returns the value of the result
-		 * set’s first column as a {@link String}.
-		 */
-		public StringCreator() {
-			this(1);
-		}
-
-		/**
-		 * Creates a new object creator that returns the value of the result
-		 * set’s given column as a {@link String}.
-		 *
-		 * @param index
-		 *            The index of the column
-		 */
-		public StringCreator(int index) {
-			this.index = index;
-		}
-
-		/**
-		 * @see net.pterodactylus.util.database.ObjectCreator#createObject(java.sql.ResultSet)
-		 */
-		@Override
-		public String createObject(ResultSet resultSet) throws SQLException {
-			return resultSet.getString(index);
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/OrderField.java b/alien/src/net/pterodactylus/util/database/OrderField.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/OrderField.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * utils - OrderField.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-/**
- * An order field stores the name of the field to order a query result by and
- * the direction of the sorting.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class OrderField {
-
-	/**
-	 * Defines the possible sort orders.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public enum Order {
-
-		/** Sort the results in ascending (smallest first) order. */
-		ASCENDING,
-
-		/** Sort the results in descending (largest first) order. */
-		DESCENDING
-
-	}
-
-	/** The field to sort by. */
-	private final Field field;
-
-	/** The sort direction. */
-	private final Order order;
-
-	/**
-	 * Creates a new order field, sorting ascending by the given field.
-	 *
-	 * @param field
-	 *            The field to sort by
-	 */
-	public OrderField(Field field) {
-		this(field, Order.ASCENDING);
-	}
-
-	/**
-	 * Creates a new order field, sorting in the given order by the given field.
-	 *
-	 * @param field
-	 *            The field to sort by
-	 * @param order
-	 *            The sort direction
-	 */
-	public OrderField(Field field, Order order) {
-		this.field = field;
-		this.order = order;
-	}
-
-	/**
-	 * Returns the name of the field to sort by.
-	 *
-	 * @return The name of the field to sort by
-	 */
-	public Field getField() {
-		return field;
-	}
-
-	/**
-	 * Returns the order of the sort.
-	 *
-	 * @return The sort order
-	 */
-	public Order getOrder() {
-		return order;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/PairCreator.java b/alien/src/net/pterodactylus/util/database/PairCreator.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/PairCreator.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * utils - PairCreator.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-import net.pterodactylus.util.collection.Pair;
-
-/**
- * Object creator implementation that creates a pair from two other object
- * creators.
- *
- * @param <L>
- *            The type of the left object
- * @param <R>
- *            The type of the right object
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class PairCreator<L, R> implements ObjectCreator<Pair<L, R>> {
-
-	/** The object creator for the left object. */
-	private final ObjectCreator<L> leftObjectCreator;
-
-	/** The object creator for the right object. */
-	private final ObjectCreator<R> rightObjectCreator;
-
-	/**
-	 * Creates a new pair object creator.
-	 *
-	 * @param leftObjectCreator
-	 *            The left object creator
-	 * @param rightObjectCreator
-	 *            The right object creator
-	 */
-	public PairCreator(ObjectCreator<L> leftObjectCreator, ObjectCreator<R> rightObjectCreator) {
-		this.leftObjectCreator = leftObjectCreator;
-		this.rightObjectCreator = rightObjectCreator;
-	}
-
-	/**
-	 * @see net.pterodactylus.util.database.ObjectCreator#createObject(java.sql.ResultSet)
-	 */
-	@Override
-	public Pair<L, R> createObject(ResultSet resultSet) throws SQLException {
-		return new Pair<L, R>(leftObjectCreator.createObject(resultSet), rightObjectCreator.createObject(resultSet));
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/Parameter.java b/alien/src/net/pterodactylus/util/database/Parameter.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/Parameter.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * utils - Parameter.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.Types;
-
-/**
- * A {@code Parameter} stores a parameter value in its native type and can set
- * it on a {@link PreparedStatement} using correct type information.
- *
- * @param <T>
- *            The type of the parameter value
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public abstract class Parameter<T> {
-
-	/** The value of the parameter. */
-	protected final T value;
-
-	/**
-	 * Creates a new parameter.
-	 *
-	 * @param value
-	 *            The value of the parameter
-	 */
-	protected Parameter(T value) {
-		this.value = value;
-	}
-
-	/**
-	 * Sets the value on the prepared statement.
-	 *
-	 * @param preparedStatement
-	 *            The prepared statement to set the value on
-	 * @param index
-	 *            The index of the parameter
-	 * @throws SQLException
-	 *             if an SQL error occurs
-	 */
-	public abstract void set(PreparedStatement preparedStatement, int index) throws SQLException;
-
-	/**
-	 * {@link Parameter} implemetation for a {@link Boolean} value that supports
-	 * NULL values.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public static class BooleanParameter extends Parameter<Boolean> {
-
-		/**
-		 * Creates a new parameter.
-		 *
-		 * @param value
-		 *            The value of the parameter (may be {@code null})
-		 */
-		public BooleanParameter(Boolean value) {
-			super(value);
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public void set(PreparedStatement preparedStatement, int index) throws SQLException {
-			if (value == null) {
-				preparedStatement.setNull(index, Types.BOOLEAN);
-			} else {
-				preparedStatement.setBoolean(index, value);
-			}
-		}
-
-	}
-
-	/**
-	 * {@link Parameter} implemetation for a {@link Integer} value that supports
-	 * NULL values.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public static class IntegerParameter extends Parameter<Integer> {
-
-		/**
-		 * Creates a new parameter.
-		 *
-		 * @param value
-		 *            The value of the parameter (may be {@code null})
-		 */
-		public IntegerParameter(Integer value) {
-			super(value);
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public void set(PreparedStatement preparedStatement, int index) throws SQLException {
-			if (value == null) {
-				preparedStatement.setNull(index, Types.INTEGER);
-			} else {
-				preparedStatement.setInt(index, value);
-			}
-		}
-
-	}
-
-	/**
-	 * {@link Parameter} implemetation for a {@link Long} value that supports
-	 * NULL values.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public static class LongParameter extends Parameter<Long> {
-
-		/**
-		 * Creates a new parameter.
-		 *
-		 * @param value
-		 *            The value of the parameter (may be {@code null})
-		 */
-		public LongParameter(Long value) {
-			super(value);
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public void set(PreparedStatement preparedStatement, int index) throws SQLException {
-			if (value == null) {
-				preparedStatement.setNull(index, Types.BIGINT);
-			} else {
-				preparedStatement.setLong(index, value);
-			}
-		}
-
-	}
-
-	/**
-	 * {@link Parameter} implemetation for a {@link String} value that supports
-	 * NULL values.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public static class StringParameter extends Parameter<String> {
-
-		/**
-		 * Creates a new parameter.
-		 *
-		 * @param value
-		 *            The value of the parameter (may be {@code null})
-		 */
-		public StringParameter(String value) {
-			super(value);
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public void set(PreparedStatement preparedStatement, int index) throws SQLException {
-			if (value == null) {
-				preparedStatement.setNull(index, Types.VARCHAR);
-			} else {
-				preparedStatement.setString(index, value);
-			}
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/PooledDataSource.java b/alien/src/net/pterodactylus/util/database/PooledDataSource.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/PooledDataSource.java
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * utils - PooledDataSource.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-import java.io.PrintWriter;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.CallableStatement;
-import java.sql.Clob;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.NClob;
-import java.sql.PreparedStatement;
-import java.sql.SQLClientInfoException;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.SQLXML;
-import java.sql.Savepoint;
-import java.sql.Statement;
-import java.sql.Struct;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import javax.sql.DataSource;
-
-import net.pterodactylus.util.collection.Pair;
-
-/**
- * A data source that uses an internal pool of opened connections. Whenever a
- * connection is requested with {@link #getConnection()} or
- * {@link #getConnection(String, String)} a new connection is created if there
- * is none available. This will allow the pool to grow on demand.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class PooledDataSource implements DataSource {
-
-	/** The original data source. */
-	private DataSource originalDataSource;
-
-	/** The pool of currently opened connections. */
-	private Set<Connection> currentConnections = new HashSet<Connection>();
-
-	/**
-	 * The pool of currently opened connections with custom username/password
-	 * combinations.
-	 */
-	private Map<Pair<String, String>, Set<Connection>> usernamePasswordConnections = new HashMap<Pair<String, String>, Set<Connection>>();
-
-	/**
-	 * Creates a new pooled data source that wraps the given data source.
-	 *
-	 * @param originalDataSource
-	 *            The original data source
-	 */
-	public PooledDataSource(DataSource originalDataSource) {
-		this.originalDataSource = originalDataSource;
-	}
-
-	/**
-	 * @see javax.sql.DataSource#getConnection()
-	 */
-	@Override
-	public Connection getConnection() throws SQLException {
-		synchronized (currentConnections) {
-			if (currentConnections.isEmpty()) {
-				Connection newConnection = new PooledConnection(originalDataSource.getConnection());
-				currentConnections.add(newConnection);
-			}
-			Connection connection = currentConnections.iterator().next();
-			currentConnections.remove(connection);
-			return connection;
-		}
-	}
-
-	/**
-	 * @see javax.sql.DataSource#getConnection(java.lang.String,
-	 *      java.lang.String)
-	 */
-	@Override
-	public Connection getConnection(String username, String password) throws SQLException {
-		Pair<String, String> usernamePasswordPair = new Pair<String, String>(username, password);
-		synchronized (usernamePasswordConnections) {
-			if (!usernamePasswordConnections.containsKey(usernamePasswordPair)) {
-				Set<Connection> connections = new HashSet<Connection>();
-				usernamePasswordConnections.put(usernamePasswordPair, connections);
-			}
-			Set<Connection> connections = usernamePasswordConnections.get(usernamePasswordPair);
-			if (usernamePasswordConnections.isEmpty()) {
-				Connection newConnection = new PooledUsernamePasswordConnection(originalDataSource.getConnection(username, password), username, password);
-				connections.add(newConnection);
-			}
-			Connection connection = connections.iterator().next();
-			connections.remove(connection);
-			return connection;
-		}
-	}
-
-	/**
-	 * @see javax.sql.CommonDataSource#getLogWriter()
-	 */
-	@Override
-	public PrintWriter getLogWriter() throws SQLException {
-		return originalDataSource.getLogWriter();
-	}
-
-	/**
-	 * @see javax.sql.CommonDataSource#getLoginTimeout()
-	 */
-	@Override
-	public int getLoginTimeout() throws SQLException {
-		return originalDataSource.getLoginTimeout();
-	}
-
-	/**
-	 * @see javax.sql.CommonDataSource#setLogWriter(java.io.PrintWriter)
-	 */
-	@Override
-	public void setLogWriter(PrintWriter out) throws SQLException {
-		originalDataSource.setLogWriter(out);
-	}
-
-	/**
-	 * @see javax.sql.CommonDataSource#setLoginTimeout(int)
-	 */
-	@Override
-	public void setLoginTimeout(int seconds) throws SQLException {
-		originalDataSource.setLoginTimeout(seconds);
-	}
-
-	/**
-	 * @see java.sql.Wrapper#isWrapperFor(java.lang.Class)
-	 */
-	@Override
-	public boolean isWrapperFor(Class<?> iface) throws SQLException {
-		return originalDataSource.isWrapperFor(iface);
-	}
-
-	/**
-	 * @see java.sql.Wrapper#unwrap(java.lang.Class)
-	 */
-	@Override
-	public <T> T unwrap(Class<T> iface) throws SQLException {
-		return originalDataSource.unwrap(iface);
-	}
-
-	/**
-	 * Wrapper around a connection that was created by the
-	 * {@link PooledDataSource#originalDataSource}. This wrapper only overrides
-	 * the {@link Connection#close()} method to not close the connection but to
-	 * return it to the connection pool instead.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	private class PooledConnection implements Connection {
-
-		/** The original connection. */
-		private final Connection originalConnection;
-
-		/**
-		 * Creates a new pooled connection.
-		 *
-		 * @param originalConnection
-		 *            The original connection to wrap
-		 */
-		public PooledConnection(Connection originalConnection) {
-			this.originalConnection = originalConnection;
-		}
-
-		//
-		// PROTECTED METHODS
-		//
-
-		/**
-		 * Returns the original connection that is wrapped by this pooled
-		 * connection.
-		 *
-		 * @return The original connection
-		 */
-		protected Connection getOriginalConnection() {
-			return originalConnection;
-		}
-
-		//
-		// INTERFACE Connection
-		//
-
-		/**
-		 * @see java.sql.Connection#clearWarnings()
-		 */
-		@Override
-		public void clearWarnings() throws SQLException {
-			originalConnection.clearWarnings();
-		}
-
-		/**
-		 * @see java.sql.Connection#close()
-		 */
-		@Override
-		@SuppressWarnings("synthetic-access")
-		public void close() throws SQLException {
-			if (!isValid(1)) {
-				originalConnection.close();
-				return;
-			}
-			synchronized (currentConnections) {
-				currentConnections.add(this);
-			}
-		}
-
-		/**
-		 * @see java.sql.Connection#commit()
-		 */
-		@Override
-		public void commit() throws SQLException {
-			originalConnection.commit();
-		}
-
-		/**
-		 * @see java.sql.Connection#createArrayOf(java.lang.String,
-		 *      java.lang.Object[])
-		 */
-		@Override
-		public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
-			return originalConnection.createArrayOf(typeName, elements);
-		}
-
-		/**
-		 * @see java.sql.Connection#createBlob()
-		 */
-		@Override
-		public Blob createBlob() throws SQLException {
-			return originalConnection.createBlob();
-		}
-
-		/**
-		 * @see java.sql.Connection#createClob()
-		 */
-		@Override
-		public Clob createClob() throws SQLException {
-			return originalConnection.createClob();
-		}
-
-		/**
-		 * @see java.sql.Connection#createNClob()
-		 */
-		@Override
-		public NClob createNClob() throws SQLException {
-			return originalConnection.createNClob();
-		}
-
-		/**
-		 * @see java.sql.Connection#createSQLXML()
-		 */
-		@Override
-		public SQLXML createSQLXML() throws SQLException {
-			return originalConnection.createSQLXML();
-		}
-
-		/**
-		 * @see java.sql.Connection#createStatement()
-		 */
-		@Override
-		public Statement createStatement() throws SQLException {
-			return originalConnection.createStatement();
-		}
-
-		/**
-		 * @see java.sql.Connection#createStatement(int, int, int)
-		 */
-		@Override
-		public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
-			return originalConnection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
-		}
-
-		/**
-		 * @see java.sql.Connection#createStatement(int, int)
-		 */
-		@Override
-		public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
-			return originalConnection.createStatement(resultSetType, resultSetConcurrency);
-		}
-
-		/**
-		 * @see java.sql.Connection#createStruct(java.lang.String,
-		 *      java.lang.Object[])
-		 */
-		@Override
-		public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
-			return originalConnection.createStruct(typeName, attributes);
-		}
-
-		/**
-		 * @see java.sql.Connection#getAutoCommit()
-		 */
-		@Override
-		public boolean getAutoCommit() throws SQLException {
-			return originalConnection.getAutoCommit();
-		}
-
-		/**
-		 * @see java.sql.Connection#getCatalog()
-		 */
-		@Override
-		public String getCatalog() throws SQLException {
-			return originalConnection.getCatalog();
-		}
-
-		/**
-		 * @see java.sql.Connection#getClientInfo()
-		 */
-		@Override
-		public Properties getClientInfo() throws SQLException {
-			return originalConnection.getClientInfo();
-		}
-
-		/**
-		 * @see java.sql.Connection#getClientInfo(java.lang.String)
-		 */
-		@Override
-		public String getClientInfo(String name) throws SQLException {
-			return originalConnection.getClientInfo(name);
-		}
-
-		/**
-		 * @see java.sql.Connection#getHoldability()
-		 */
-		@Override
-		public int getHoldability() throws SQLException {
-			return originalConnection.getHoldability();
-		}
-
-		/**
-		 * @see java.sql.Connection#getMetaData()
-		 */
-		@Override
-		public DatabaseMetaData getMetaData() throws SQLException {
-			return originalConnection.getMetaData();
-		}
-
-		/**
-		 * @see java.sql.Connection#getTransactionIsolation()
-		 */
-		@Override
-		public int getTransactionIsolation() throws SQLException {
-			return originalConnection.getTransactionIsolation();
-		}
-
-		/**
-		 * @see java.sql.Connection#getTypeMap()
-		 */
-		@Override
-		public Map<String, Class<?>> getTypeMap() throws SQLException {
-			return originalConnection.getTypeMap();
-		}
-
-		/**
-		 * @see java.sql.Connection#getWarnings()
-		 */
-		@Override
-		public SQLWarning getWarnings() throws SQLException {
-			return originalConnection.getWarnings();
-		}
-
-		/**
-		 * @see java.sql.Connection#isClosed()
-		 */
-		@Override
-		public boolean isClosed() throws SQLException {
-			return originalConnection.isClosed();
-		}
-
-		/**
-		 * @see java.sql.Connection#isReadOnly()
-		 */
-		@Override
-		public boolean isReadOnly() throws SQLException {
-			return originalConnection.isReadOnly();
-		}
-
-		/**
-		 * @see java.sql.Connection#isValid(int)
-		 */
-		@Override
-		public boolean isValid(int timeout) throws SQLException {
-			return originalConnection.isValid(timeout);
-		}
-
-		/**
-		 * @see java.sql.Wrapper#isWrapperFor(java.lang.Class)
-		 */
-		@Override
-		public boolean isWrapperFor(Class<?> iface) throws SQLException {
-			return originalConnection.isWrapperFor(iface);
-		}
-
-		/**
-		 * @see java.sql.Connection#nativeSQL(java.lang.String)
-		 */
-		@Override
-		public String nativeSQL(String sql) throws SQLException {
-			return originalConnection.nativeSQL(sql);
-		}
-
-		/**
-		 * @see java.sql.Connection#prepareCall(java.lang.String, int, int, int)
-		 */
-		@Override
-		public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
-			return originalConnection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
-		}
-
-		/**
-		 * @see java.sql.Connection#prepareCall(java.lang.String, int, int)
-		 */
-		@Override
-		public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
-			return originalConnection.prepareCall(sql, resultSetType, resultSetConcurrency);
-		}
-
-		/**
-		 * @see java.sql.Connection#prepareCall(java.lang.String)
-		 */
-		@Override
-		public CallableStatement prepareCall(String sql) throws SQLException {
-			return originalConnection.prepareCall(sql);
-		}
-
-		/**
-		 * @see java.sql.Connection#prepareStatement(java.lang.String, int, int,
-		 *      int)
-		 */
-		@Override
-		public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
-			return originalConnection.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
-		}
-
-		/**
-		 * @see java.sql.Connection#prepareStatement(java.lang.String, int, int)
-		 */
-		@Override
-		public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
-			return originalConnection.prepareStatement(sql, resultSetType, resultSetConcurrency);
-		}
-
-		/**
-		 * @see java.sql.Connection#prepareStatement(java.lang.String, int)
-		 */
-		@Override
-		public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
-			return originalConnection.prepareStatement(sql, autoGeneratedKeys);
-		}
-
-		/**
-		 * @see java.sql.Connection#prepareStatement(java.lang.String, int[])
-		 */
-		@Override
-		public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
-			return originalConnection.prepareStatement(sql, columnIndexes);
-		}
-
-		/**
-		 * @see java.sql.Connection#prepareStatement(java.lang.String,
-		 *      java.lang.String[])
-		 */
-		@Override
-		public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
-			return originalConnection.prepareStatement(sql, columnNames);
-		}
-
-		/**
-		 * @see java.sql.Connection#prepareStatement(java.lang.String)
-		 */
-		@Override
-		public PreparedStatement prepareStatement(String sql) throws SQLException {
-			return originalConnection.prepareStatement(sql);
-		}
-
-		/**
-		 * @see java.sql.Connection#releaseSavepoint(java.sql.Savepoint)
-		 */
-		@Override
-		public void releaseSavepoint(Savepoint savepoint) throws SQLException {
-			originalConnection.releaseSavepoint(savepoint);
-		}
-
-		/**
-		 * @see java.sql.Connection#rollback()
-		 */
-		@Override
-		public void rollback() throws SQLException {
-			originalConnection.rollback();
-		}
-
-		/**
-		 * @see java.sql.Connection#rollback(java.sql.Savepoint)
-		 */
-		@Override
-		public void rollback(Savepoint savepoint) throws SQLException {
-			originalConnection.rollback(savepoint);
-		}
-
-		/**
-		 * @see java.sql.Connection#setAutoCommit(boolean)
-		 */
-		@Override
-		public void setAutoCommit(boolean autoCommit) throws SQLException {
-			originalConnection.setAutoCommit(autoCommit);
-		}
-
-		/**
-		 * @see java.sql.Connection#setCatalog(java.lang.String)
-		 */
-		@Override
-		public void setCatalog(String catalog) throws SQLException {
-			originalConnection.setCatalog(catalog);
-		}
-
-		/**
-		 * @see java.sql.Connection#setClientInfo(java.util.Properties)
-		 */
-		@Override
-		public void setClientInfo(Properties properties) throws SQLClientInfoException {
-			originalConnection.setClientInfo(properties);
-		}
-
-		/**
-		 * @see java.sql.Connection#setClientInfo(java.lang.String,
-		 *      java.lang.String)
-		 */
-		@Override
-		public void setClientInfo(String name, String value) throws SQLClientInfoException {
-			originalConnection.setClientInfo(name, value);
-		}
-
-		/**
-		 * @see java.sql.Connection#setHoldability(int)
-		 */
-		@Override
-		public void setHoldability(int holdability) throws SQLException {
-			originalConnection.setHoldability(holdability);
-		}
-
-		/**
-		 * @see java.sql.Connection#setReadOnly(boolean)
-		 */
-		@Override
-		public void setReadOnly(boolean readOnly) throws SQLException {
-			originalConnection.setReadOnly(readOnly);
-		}
-
-		/**
-		 * @see java.sql.Connection#setSavepoint()
-		 */
-		@Override
-		public Savepoint setSavepoint() throws SQLException {
-			return originalConnection.setSavepoint();
-		}
-
-		/**
-		 * @see java.sql.Connection#setSavepoint(java.lang.String)
-		 */
-		@Override
-		public Savepoint setSavepoint(String name) throws SQLException {
-			return originalConnection.setSavepoint(name);
-		}
-
-		/**
-		 * @see java.sql.Connection#setTransactionIsolation(int)
-		 */
-		@Override
-		public void setTransactionIsolation(int level) throws SQLException {
-			originalConnection.setTransactionIsolation(level);
-		}
-
-		/**
-		 * @see java.sql.Connection#setTypeMap(java.util.Map)
-		 */
-		@Override
-		public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
-			originalConnection.setTypeMap(map);
-		}
-
-		/**
-		 * @see java.sql.Wrapper#unwrap(java.lang.Class)
-		 */
-		@Override
-		public <T> T unwrap(Class<T> iface) throws SQLException {
-			return originalConnection.unwrap(iface);
-		}
-
-	}
-
-	/**
-	 * Wrapper around a connection that was created with a username and a
-	 * password. This wrapper also only overrides the {@link Connection#close}
-	 * method but returns the connection to the appropriate connection pool in
-	 * {@link PooledDataSource#usernamePasswordConnections}.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	private class PooledUsernamePasswordConnection extends PooledConnection {
-
-		/** The username of the connection. */
-		private final String username;
-
-		/** The password of the connection. */
-		private final String password;
-
-		/**
-		 * Creates a new pooled connection that was created with a username and
-		 * a password.
-		 *
-		 * @param originalConnection
-		 *            The original connection to wrap
-		 * @param username
-		 *            The username the connection was created with
-		 * @param password
-		 *            The password the connection was created with
-		 */
-		public PooledUsernamePasswordConnection(Connection originalConnection, String username, String password) {
-			super(originalConnection);
-			this.username = username;
-			this.password = password;
-		}
-
-		/**
-		 * @see net.pterodactylus.util.database.PooledDataSource.PooledConnection#close()
-		 */
-		@Override
-		@SuppressWarnings("synthetic-access")
-		public void close() throws SQLException {
-			if (!isValid(1)) {
-				getOriginalConnection().close();
-				return;
-			}
-			synchronized (usernamePasswordConnections) {
-				usernamePasswordConnections.get(new Pair<String, String>(username, password)).add(this);
-			}
-		}
-
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/Query.java b/alien/src/net/pterodactylus/util/database/Query.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/Query.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * utils - Query.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.List;
-
-import net.pterodactylus.util.database.OrderField.Order;
-
-/**
- * Container for SQL queries and their parameters.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Query {
-
-	/**
-	 * The type of the query.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public enum Type {
-
-		/** Query is a SELECT. */
-		SELECT,
-
-		/** Query is an INSERT. */
-		INSERT,
-
-		/** Query is an UPDATE. */
-		UPDATE,
-
-		/** Query is a DELETE. */
-		DELETE
-
-	}
-
-	/** The type of the query. */
-	private final Type type;
-
-	/** The fields for a select query. */
-	private final List<Field> fields = new ArrayList<Field>();
-
-	/** The value fields for an insert or update query. */
-	private final List<ValueField> valueFields = new ArrayList<ValueField>();
-
-	/** The name of the table. */
-	private final String table;
-
-	/** The WHERE clauses. */
-	private final List<WhereClause> whereClauses = new ArrayList<WhereClause>();
-
-	/** The order fields for select queries. */
-	private final List<OrderField> orderFields = new ArrayList<OrderField>();
-
-	/** The limit, if any. */
-	private Limit limit;
-
-	/**
-	 * Creates a new query.
-	 *
-	 * @param type
-	 *            The type of the query
-	 * @param table
-	 *            The table that is processed
-	 */
-	public Query(Type type, String table) {
-		this.type = type;
-		this.table = table;
-	}
-
-	/**
-	 * Adds one or more fields to this query.
-	 *
-	 * @param fields
-	 *            The fields to add
-	 */
-	public void addField(Field... fields) {
-		for (Field field : fields) {
-			this.fields.add(field);
-		}
-	}
-
-	/**
-	 * Adds one or more value fields to this query.
-	 *
-	 * @param valueFields
-	 *            The value fields to add
-	 */
-	public void addValueField(ValueField... valueFields) {
-		for (ValueField valueField : valueFields) {
-			this.valueFields.add(valueField);
-		}
-	}
-
-	/**
-	 * Adds one or more WHERE clauses to this query.
-	 *
-	 * @param whereClauses
-	 *            The WHERE clauses to add
-	 */
-	public void addWhereClause(WhereClause... whereClauses) {
-		for (WhereClause whereClause : whereClauses) {
-			this.whereClauses.add(whereClause);
-		}
-	}
-
-	/**
-	 * Adds one or more order fields to this query.
-	 *
-	 * @param orderFields
-	 *            The order fields to add
-	 */
-	public void addOrderField(OrderField... orderFields) {
-		if (type != Type.SELECT) {
-			throw new IllegalStateException("Order fields are only allowed in SELECT queries.");
-		}
-		for (OrderField orderField : orderFields) {
-			this.orderFields.add(orderField);
-		}
-	}
-
-	/**
-	 * Sets the limit for this query.
-	 *
-	 * @param limit
-	 *            The limit for this query
-	 */
-	public void setLimit(Limit limit) {
-		this.limit = limit;
-	}
-
-	/**
-	 * Creates an SQL statement from the given connection and prepares it for
-	 * execution.
-	 *
-	 * @param connection
-	 *            The connection to create a statement from
-	 * @return The prepared statement, ready for execution
-	 * @throws SQLException
-	 *             if an SQL error occurs
-	 */
-	public PreparedStatement createStatement(Connection connection) throws SQLException {
-		StringWriter queryWriter = new StringWriter();
-		try {
-			render(queryWriter);
-		} catch (IOException ioe1) {
-			/* ignore. */
-		}
-		String query = queryWriter.toString();
-		PreparedStatement preparedStatement = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
-		int index = 0;
-		if ((type == Type.UPDATE) || (type == Type.INSERT)) {
-			for (ValueField valueField : valueFields) {
-				valueField.getParameter().set(preparedStatement, ++index);
-			}
-		}
-		if ((type == Type.SELECT) || (type == Type.UPDATE) || (type == Type.DELETE)) {
-			for (WhereClause whereClause : whereClauses) {
-				for (Parameter<?> parameter : whereClause.getParameters()) {
-					parameter.set(preparedStatement, ++index);
-				}
-			}
-		}
-		return preparedStatement;
-	}
-
-	/**
-	 * Renders this query to the given writer.
-	 *
-	 * @param writer
-	 *            The writer to render the query to
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public void render(Writer writer) throws IOException {
-		writer.write(type.name());
-		if (type == Type.SELECT) {
-			writer.write(' ');
-			if (fields.isEmpty()) {
-				writer.write('*');
-			} else {
-				boolean first = true;
-				for (Field field : fields) {
-					if (!first) {
-						writer.write(", ");
-					}
-					writer.write(field.getName());
-					first = false;
-				}
-			}
-			writer.write(" FROM ");
-			writer.write(table);
-			renderWhereClauses(writer);
-			if (!orderFields.isEmpty()) {
-				writer.write(" ORDER BY ");
-				boolean first = true;
-				for (OrderField orderField : orderFields) {
-					if (!first) {
-						writer.write(", ");
-					}
-					writer.write(orderField.getField().getName());
-					writer.write((orderField.getOrder() == Order.ASCENDING) ? " ASC" : " DESC");
-					first = false;
-				}
-			}
-			if (limit != null) {
-				writer.write(" LIMIT ");
-				if (limit.getStart() != 0) {
-					writer.write(String.valueOf(limit.getStart()));
-					writer.write(", ");
-				}
-				writer.write(String.valueOf(limit.getNumber()));
-			}
-		} else if (type == Type.UPDATE) {
-			writer.write(' ');
-			writer.write(table);
-			writer.write(" SET ");
-			boolean first = true;
-			for (ValueField valueField : valueFields) {
-				if (!first) {
-					writer.write(", ");
-				}
-				writer.write(valueField.getName());
-				writer.write(" = ?");
-				first = false;
-			}
-			renderWhereClauses(writer);
-		} else if (type == Type.INSERT) {
-			writer.write(" INTO ");
-			writer.write(table);
-			writer.write(" (");
-			boolean first = true;
-			for (ValueField valueField : valueFields) {
-				if (!first) {
-					writer.write(", ");
-				}
-				writer.write(valueField.getName());
-				first = false;
-			}
-			writer.write(") VALUES (");
-			first = true;
-			for (int fieldIndex = 0; fieldIndex < valueFields.size(); ++fieldIndex) {
-				if (!first) {
-					writer.write(", ");
-				}
-				writer.write('?');
-				first = false;
-			}
-			writer.write(')');
-		} else if (type == Type.DELETE) {
-			writer.write(" FROM ");
-			writer.write(table);
-			renderWhereClauses(writer);
-		}
-	}
-
-	/**
-	 * Renders the WHERE clauses, prepending a “WHERE” if there are WHERE
-	 * clauses to render.
-	 *
-	 * @param writer
-	 *            The writer to render the WHERE clauses to
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	private void renderWhereClauses(Writer writer) throws IOException {
-		if (whereClauses.isEmpty()) {
-			return;
-		}
-		writer.write(" WHERE ");
-		if (whereClauses.size() == 1) {
-			whereClauses.get(0).render(writer);
-			return;
-		}
-		AndWhereClause whereClause = new AndWhereClause(whereClauses);
-		whereClause.render(writer);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/ResultProcessor.java b/alien/src/net/pterodactylus/util/database/ResultProcessor.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/ResultProcessor.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * utils - ResultProcessor.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-/**
- * A result processor is similar to an {@link ObjectCreator} but it does not
- * return created objects but processes results in an arbitrary way.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface ResultProcessor {
-
-	/**
-	 * Processes the current row of the result set.
-	 *
-	 * @param resultSet
-	 *            The result set to process
-	 * @throws SQLException
-	 *             if an SQL error occurs
-	 */
-	public void processResult(ResultSet resultSet) throws SQLException;
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/URLDataSource.java b/alien/src/net/pterodactylus/util/database/URLDataSource.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/URLDataSource.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * utils - URLDataSource.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-import java.io.PrintWriter;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.util.Properties;
-
-import javax.sql.DataSource;
-
-/**
- * {@link DataSource} implementation that creates connections from a JDBC URL
- * using {@link DriverManager#getConnection(String)}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class URLDataSource implements DataSource {
-
-	/** The URL to connect to. */
-	private final String connectionUrl;
-
-	/** The log writer. */
-	private PrintWriter logWriter;
-
-	/** The login timeout. */
-	private int loginTimeout;
-
-	/** The login properties. */
-	private final Properties loginProperties = new Properties();
-
-	/**
-	 * Creates a URL data source.
-	 *
-	 * @param connectionUrl
-	 *            The URL to connect to
-	 */
-	public URLDataSource(String connectionUrl) {
-		this.connectionUrl = connectionUrl;
-		loginProperties.setProperty("connectTimeout", "0");
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public PrintWriter getLogWriter() throws SQLException {
-		return logWriter;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void setLogWriter(PrintWriter logWriter) throws SQLException {
-		this.logWriter = logWriter;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void setLoginTimeout(int loginTimeout) throws SQLException {
-		this.loginTimeout = loginTimeout;
-		loginProperties.setProperty("connectTimeout", String.valueOf(loginTimeout * 1000L));
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int getLoginTimeout() throws SQLException {
-		return loginTimeout;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public <T> T unwrap(Class<T> iface) throws SQLException {
-		throw new SQLException("No wrapped object found for " + iface.getClass().getName() + ".");
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean isWrapperFor(Class<?> iface) throws SQLException {
-		return false;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Connection getConnection() throws SQLException {
-		return DriverManager.getConnection(connectionUrl, loginProperties);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Connection getConnection(String username, String password) throws SQLException {
-		Properties userProperties = new Properties(loginProperties);
-		userProperties.setProperty("user", username);
-		userProperties.setProperty("password", password);
-		return DriverManager.getConnection(connectionUrl, username, password);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/ValueField.java b/alien/src/net/pterodactylus/util/database/ValueField.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/ValueField.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright © 2010 knorpelfisk.de
- */
-
-package net.pterodactylus.util.database;
-
-
-/**
- * A value field stores its name and its value.
- *
- * @author <a href="mailto:dr@knorpelfisk.de">David Roden</a>
- */
-public class ValueField extends Field {
-
-	/** The value of the field */
-	private final Parameter<?> parameter;
-
-	/**
-	 * Creates a new value field.
-	 *
-	 * @param name
-	 *            The name of the field
-	 * @param parameter
-	 *            The value of the field
-	 */
-	public ValueField(String name, Parameter<?> parameter) {
-		super(name);
-		this.parameter = parameter;
-	}
-
-	/**
-	 * Returns the value of this field.
-	 *
-	 * @return The value of this field
-	 */
-	public Parameter<?> getParameter() {
-		return parameter;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/ValueFieldWhereClause.java b/alien/src/net/pterodactylus/util/database/ValueFieldWhereClause.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/ValueFieldWhereClause.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * utils - ValueFieldWhereClause.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * A WHERE clause that requires a field to match a value.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ValueFieldWhereClause implements WhereClause {
-
-	/** The field and the value to match. */
-	private final ValueField valueField;
-
-	/** Whether to invert the result. */
-	private final boolean invert;
-
-	/**
-	 * Creates a new WHERE clause that checks a field for the given value.
-	 *
-	 * @param valueField
-	 *            The field and the value to check for
-	 */
-	public ValueFieldWhereClause(ValueField valueField) {
-		this(valueField, false);
-	}
-
-	/**
-	 * Creates a new WHERE clause that checks a field for the given value.
-	 *
-	 * @param valueField
-	 *            The field and the value to check for
-	 * @param invert
-	 *            {@code true} to invert the result
-	 */
-	public ValueFieldWhereClause(ValueField valueField, boolean invert) {
-		this.valueField = valueField;
-		this.invert = invert;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public List<Parameter<?>> getParameters() {
-		return Arrays.<Parameter<?>> asList(valueField.getParameter());
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void render(Writer writer) throws IOException {
-		writer.write("(" + valueField.getName() + " " + (invert ? "!=" : "=") + " ?)");
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/WhereClause.java b/alien/src/net/pterodactylus/util/database/WhereClause.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/WhereClause.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * utils - WhereClause.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.database;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.List;
-
-/**
- * Interface for a WHERE clause that can be used to specify criteria for
- * matching {@link DataObject}s.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface WhereClause {
-
-	/**
-	 * Returns all parameters of this WHERE clause, in the same order as
-	 * placeholders are specified.
-	 *
-	 * @return The parameters of this WHERE clause
-	 */
-	public List<Parameter<?>> getParameters();
-
-	/**
-	 * Writes this WHERE clause to the given writer.
-	 *
-	 * @param writer
-	 *            The writer to write to
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public void render(Writer writer) throws IOException;
-
-}
diff --git a/alien/src/net/pterodactylus/util/database/package-info.java b/alien/src/net/pterodactylus/util/database/package-info.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/database/package-info.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * <p>
- * Helper and abstraction classes for database interaction.
- * </p>
- * <h1>Database Backends</h1>
- * <p>
- * The {@link net.pterodactylus.util.database.Database} interface defines data
- * manipulation methods that can be used to perform 95% of all necessary
- * interaction with the database.
- * </p>
- * <h2>Getting a Single Value from the Database</h2>
- * <p>
- * The {@link net.pterodactylus.util.database.Database#getSingle(Query, ObjectCreator)}
- * method is used to return a single value or object from the database. This
- * method delegates the work of actually creating the return value to the given
- * {@link net.pterodactylus.util.database.ObjectCreator} instance which uses the first
- * row that is returned by the given query to create the appropriate object.
- * </p>
- * <h2>Getting Multiple Values from the Database</h2>
- * <p>
- * The
- * {@link net.pterodactylus.util.database.Database#getMultiple(Query, ObjectCreator)}
- * method is used to return multiple values or objects from the database. Again,
- * the actual creation process is delegated to the given object creator which
- * will be used for every row the query returns.
- * </p>
- * <h2>Inserting Values into the Database</h2>
- * <p>
- * Use the {@link net.pterodactylus.util.database.Database#insert(Query)} method to
- * execute a query that will insert one new record into a database. It will
- * return the first auto-generated ID, or <code>-1</code> if no ID was
- * generated.
- * </p>
- * <h2>Updating Values in the Database</h2>
- * <p>
- * Finally, the {@link net.pterodactylus.util.database.Database#update(Query)} method
- * will let you execute a query that updates values in the database. It will
- * return the number of changed records.
- * </p>
- * <h1>The {@link net.pterodactylus.util.database.AbstractDatabase} Implementation</h1>
- * <p>
- * This class introduces some helper classes the perform the actual SQL queries
- * and reduces the cost of writing new database backends to the implementation
- * of two methods:
- * {@link net.pterodactylus.util.database.AbstractDatabase#getConnection()
- * getConnection()} and
- * {@link net.pterodactylus.util.database.AbstractDatabase#returnConnection(java.sql.Connection)
- * returnConnection()} . It also contains a method to create a database from a
- * {@link javax.sql.DataSource} (
- * {@link net.pterodactylus.util.database.AbstractDatabase#fromDataSource(javax.sql.DataSource)}
- * ).
- * </p>
- * <h1>The {@link net.pterodactylus.util.database.Query} Class</h1>
- * <p>
- * This class stores an SQL query string and its parameters. It is able to
- * create a {@link java.sql.PreparedStatement} from the parameters and it can be
- * persisted easily.
- * </p>
- * <h1>The {@link net.pterodactylus.util.database.ObjectCreator} Class</h1>
- * <p>
- * An object creator is responsible for creating objects from the current row of
- * a {@link java.sql.ResultSet}. It is used by the helper classes in
- * {@link net.pterodactylus.util.database.AbstractDatabase} to allow the user to control
- * the conversion from a result set to a domain-specific object.
- * </p>
- */
-
-package net.pterodactylus.util.database;
-
diff --git a/alien/src/net/pterodactylus/util/i18n/I18n.java b/alien/src/net/pterodactylus/util/i18n/I18n.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/i18n/I18n.java
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * utils - I18n.java - Copyright © 2006-2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.i18n;
-
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Field;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Formatter;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Properties;
-import java.util.StringTokenizer;
-import java.util.Map.Entry;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.swing.KeyStroke;
-
-import net.pterodactylus.util.logging.Logging;
-
-/**
- * Handles internationalization.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class I18n {
-
-	/** The logger. */
-	private static final Logger logger = Logging.getLogger(I18n.class);
-
-	/** Whether to log access to unknown keys. */
-	public static boolean LOG_UNKNOWN_KEYS = true;
-
-	/** The main source for l10n. */
-	private final Source mainSource;
-
-	/** Additional l10n sources. */
-	private final List<Source> additionalSources = Collections.synchronizedList(new ArrayList<Source>());
-
-	/** List of I18nable listeners. */
-	private final List<I18nable> i18nables = new ArrayList<I18nable>();
-
-	/** Mapping from remove reference to list of I18nables. */
-	private final Map<RemovalReference, List<I18nable>> removalReferenceI18nables = new HashMap<RemovalReference, List<I18nable>>();
-
-	/** The current locale. */
-	private Locale locale;
-
-	/** The current translation values. */
-	private Map<String, String> values = new HashMap<String, String>();
-
-	/** Whether to use {@link MessageFormat} for formatting. */
-	private boolean useMessageFormat = false;
-
-	/**
-	 * Creates a new i18n handler.
-	 *
-	 * @param name
-	 *            The name of the application
-	 * @param propertiesPath
-	 *            The path of the properties
-	 * @param defaultLocale
-	 *            The default locale of the application
-	 */
-	public I18n(String name, String propertiesPath, Locale defaultLocale) {
-		this(name, propertiesPath, defaultLocale, Thread.currentThread().getContextClassLoader(), Locale.getDefault());
-	}
-
-	/**
-	 * Creates a new i18n handler.
-	 *
-	 * @param name
-	 *            The name of the application
-	 * @param propertiesPath
-	 *            The path of the properties
-	 * @param defaultLocale
-	 *            The default locale of the application
-	 * @param classLoader
-	 *            The class loader used to load the properties
-	 * @param currentLocale
-	 *            The current locale
-	 */
-	public I18n(String name, String propertiesPath, Locale defaultLocale, ClassLoader classLoader, Locale currentLocale) {
-		this(new Source(name, propertiesPath, defaultLocale, classLoader), currentLocale);
-	}
-
-	/**
-	 * Creates a new i18n handler.
-	 *
-	 * @param source
-	 *            The l10n source
-	 */
-	public I18n(Source source) {
-		this(source, Locale.getDefault());
-	}
-
-	/**
-	 * Creates a new i18n handler.
-	 *
-	 * @param source
-	 *            The l10n source
-	 * @param currentLocale
-	 *            The current locale
-	 */
-	public I18n(Source source, Locale currentLocale) {
-		mainSource = source;
-		locale = currentLocale;
-		reload();
-	}
-
-	//
-	// LISTENER MANAGEMENT
-	//
-
-	/**
-	 * Adds an i18n listener that is notified when the language is changed or
-	 * additional sources add added or removed.
-	 *
-	 * @param i18nable
-	 *            The i18n listener to add
-	 */
-	public void addI18nable(I18nable i18nable) {
-		addI18nable(i18nable, null);
-	}
-
-	/**
-	 * Adds an i18n listener that is notified when the language is changed or
-	 * additional sources add added or removed.
-	 *
-	 * @param i18nable
-	 *            The i18n listener to add
-	 * @param removalReference
-	 *            Removal reference (optional)
-	 */
-	public void addI18nable(I18nable i18nable, RemovalReference removalReference) {
-		i18nables.add(i18nable);
-		if (removalReference != null) {
-			List<I18nable> i18nableList = removalReferenceI18nables.get(removalReference);
-			if (i18nableList == null) {
-				i18nableList = new ArrayList<I18nable>();
-				removalReferenceI18nables.put(removalReference, i18nableList);
-			}
-			i18nableList.add(i18nable);
-		}
-	}
-
-	/**
-	 * Removes an i18n listener.
-	 *
-	 * @param i18nable
-	 *            The i18n listener to remove
-	 */
-	public void removeI18nable(I18nable i18nable) {
-		i18nables.remove(i18nable);
-	}
-
-	/**
-	 * Removes all i18n listeners that have been
-	 * {@link #addI18nable(I18nable, RemovalReference)} using the given object
-	 * as removal reference.
-	 *
-	 * @param removalReference
-	 *            The removal reference
-	 */
-	public void removeI18nables(RemovalReference removalReference) {
-		List<I18nable> i18nableList = removalReferenceI18nables.remove(removalReference);
-		if (i18nableList != null) {
-			for (I18nable i18nable : i18nableList) {
-				i18nables.remove(i18nable);
-			}
-		}
-	}
-
-	//
-	// ACCESSORS
-	//
-
-	/**
-	 * Sets whether to use {@link MessageFormat} for formatting values with
-	 * parameters.
-	 *
-	 * @param useMessageFormat
-	 *            {@code true} to use {@link MessageFormat}, {@code false} to
-	 *            use {@link String#format(String, Object...)}
-	 */
-	public void useMessageFormat(boolean useMessageFormat) {
-		this.useMessageFormat = useMessageFormat;
-	}
-
-	/**
-	 * Returns the current locale.
-	 *
-	 * @return The current locale
-	 */
-	public Locale getLocale() {
-		return locale;
-	}
-
-	/**
-	 * Sets the current locale.
-	 *
-	 * @param locale
-	 *            The new locale
-	 */
-	public void setLocale(Locale locale) {
-		this.locale = locale;
-		reload();
-	}
-
-	/**
-	 * Adds an additional l10n source.
-	 *
-	 * @param source
-	 *            The l10n source to add
-	 */
-	public void addSource(Source source) {
-		additionalSources.add(source);
-		reload();
-	}
-
-	/**
-	 * Removes an additional l10n source.
-	 *
-	 * @param source
-	 *            The l10n source to remove
-	 */
-	public void removeSource(Source source) {
-		if (additionalSources.remove(source)) {
-			reload();
-		}
-	}
-
-	/**
-	 * Returns whether the current translation contains the given key.
-	 *
-	 * @param key
-	 *            The key to check for
-	 * @return {@code true} if there is a translation for the given key, {@code
-	 *         false} otherwise
-	 */
-	public boolean has(String key) {
-		synchronized (values) {
-			return values.containsKey(key);
-		}
-	}
-
-	/**
-	 * Returns the translated value for the given key. If no translation is
-	 * found, the name of the key is returned.
-	 *
-	 * @see Formatter
-	 * @param key
-	 *            The key to get the translation for
-	 * @param parameters
-	 *            Parameters to substitute in the value of the key
-	 * @return The translated value, or the key
-	 */
-	public String get(String key, Object... parameters) {
-		String value;
-		synchronized (values) {
-			value = values.get(key);
-		}
-		if (value == null) {
-			if (LOG_UNKNOWN_KEYS) {
-				logger.log(Level.WARNING, String.format("Please supply a value for “%1$s”!", key), new Exception());
-			}
-			return key;
-		}
-		if ((parameters != null) && (parameters.length > 0)) {
-			return useMessageFormat ? MessageFormat.format(value, parameters) : String.format(value, parameters);
-		}
-		return value;
-	}
-
-	/**
-	 * Returns the keycode from the value of the given key. You can specify the
-	 * constants in {@link KeyEvent} in the properties file, e.g. VK_S for the
-	 * keycode ‘s’ when used for mnemonics.
-	 *
-	 * @param key
-	 *            The key under which the keycode is stored
-	 * @return The keycode
-	 */
-	public int getKey(String key) {
-		String value;
-		synchronized (values) {
-			value = values.get(key);
-		}
-		if ((value != null) && value.startsWith("VK_")) {
-			try {
-				Field field = KeyEvent.class.getField(value);
-				return field.getInt(null);
-			} catch (SecurityException e) {
-				/* ignore. */
-			} catch (NoSuchFieldException e) {
-				/* ignore. */
-			} catch (IllegalArgumentException e) {
-				/* ignore. */
-			} catch (IllegalAccessException e) {
-				/* ignore. */
-			}
-		}
-		if (LOG_UNKNOWN_KEYS) {
-			logger.log(Level.WARNING, "please fix “" + key + "”!", new Throwable());
-		}
-		return KeyEvent.VK_UNDEFINED;
-	}
-
-	/**
-	 * Returns a key stroke for use with swing accelerators.
-	 *
-	 * @param key
-	 *            The key of the key stroke
-	 * @return The key stroke, or <code>null</code> if no key stroke could be
-	 *         created from the translated value
-	 */
-	public KeyStroke getKeyStroke(String key) {
-		String value;
-		synchronized (values) {
-			value = values.get(key);
-		}
-		if (value == null) {
-			return null;
-		}
-		StringTokenizer keyTokens = new StringTokenizer(value, "+- ");
-		int modifierMask = 0;
-		while (keyTokens.hasMoreTokens()) {
-			String keyToken = keyTokens.nextToken();
-			if ("ctrl".equalsIgnoreCase(keyToken)) {
-				modifierMask |= InputEvent.CTRL_DOWN_MASK;
-			} else if ("alt".equalsIgnoreCase(keyToken)) {
-				modifierMask |= InputEvent.ALT_DOWN_MASK;
-			} else if ("shift".equalsIgnoreCase(keyToken)) {
-				modifierMask |= InputEvent.SHIFT_DOWN_MASK;
-			} else {
-				if (keyToken.startsWith("VK_")) {
-					if (keyToken.equals("VK_UNDEFINED")) {
-						return null;
-					}
-					try {
-						Field field = KeyEvent.class.getField(keyToken);
-						return KeyStroke.getKeyStroke(field.getInt(null), modifierMask);
-					} catch (SecurityException e) {
-						/* ignore. */
-					} catch (NoSuchFieldException e) {
-						/* ignore. */
-					} catch (IllegalArgumentException e) {
-						/* ignore. */
-					} catch (IllegalAccessException e) {
-						/* ignore. */
-					}
-				}
-				return KeyStroke.getKeyStroke(keyToken.charAt(0), modifierMask);
-			}
-		}
-		return null;
-	}
-
-	//
-	// PRIVATE METHODS
-	//
-
-	/**
-	 * Reloads translation values for the current locale and l10n sources.
-	 */
-	private void reload() {
-		Properties currentValues = new Properties();
-		loadSource(currentValues, mainSource, mainSource.getDefaultLocale());
-		loadSource(currentValues, mainSource, locale);
-		for (Source additionalSource : additionalSources) {
-			loadSource(currentValues, additionalSource, additionalSource.getDefaultLocale());
-			loadSource(currentValues, additionalSource, locale);
-		}
-		synchronized (values) {
-			values.clear();
-			for (Entry<Object, Object> valueEntry : currentValues.entrySet()) {
-				values.put((String) valueEntry.getKey(), (String) valueEntry.getValue());
-			}
-		}
-		for (I18nable i18nable : i18nables) {
-			i18nable.updateI18n();
-		}
-	}
-
-	/**
-	 * Loads the translation values from a given source.
-	 *
-	 * @param currentValues
-	 *            The current translation values
-	 * @param source
-	 *            The l10n source to load
-	 * @param locale
-	 *            The locale to load from the source
-	 */
-	private void loadSource(Properties currentValues, Source source, Locale locale) {
-		for (String variant : buildResourceNames(locale)) {
-			loadResource(currentValues, source.getClassLoader(), source.getPropertiesPath() + "/" + source.getName() + "_" + variant + ".properties");
-		}
-	}
-
-	/**
-	 * Builds up to three resource names. The first resource name is always the
-	 * language (“en”), the (optional) second one consists of the language and
-	 * the country (“en_GB”) and the (optional) third one includes a variant
-	 * (“en_GB_MAC”).
-	 *
-	 * @param locale
-	 *            The locale to build variant names from
-	 * @return The variant names
-	 */
-	private String[] buildResourceNames(Locale locale) {
-		List<String> variants = new ArrayList<String>();
-		String currentVariant = locale.getLanguage();
-		variants.add(currentVariant);
-		if (!locale.getCountry().equals("")) {
-			currentVariant += "_" + locale.getCountry();
-			variants.add(currentVariant);
-		}
-		if ((locale.getVariant() != null) && (!locale.getVariant().equals(""))) {
-			if (locale.getCountry().equals("")) {
-				currentVariant += "_";
-			}
-			currentVariant += "_" + locale.getVariant();
-			variants.add(locale.getVariant());
-		}
-		return variants.toArray(new String[variants.size()]);
-	}
-
-	/**
-	 * Loads a resource from the given class loader.
-	 *
-	 * @param currentValues
-	 *            The current translation values to load the resource into
-	 * @param classLoader
-	 *            The class loader used to load the resource
-	 * @param resourceName
-	 *            The name of the resource
-	 */
-	private void loadResource(Properties currentValues, ClassLoader classLoader, String resourceName) {
-		logger.log(Level.FINEST, "Trying to load resources from " + resourceName + "…");
-		InputStream inputStream = classLoader.getResourceAsStream(resourceName);
-		if (inputStream != null) {
-			try {
-				logger.log(Level.FINEST, "Loading resources from " + resourceName + "…");
-				currentValues.load(inputStream);
-				logger.log(Level.FINEST, "Resources successfully loaded.");
-			} catch (IOException ioe1) {
-				logger.log(Level.WARNING, String.format("Could not read properties from “%1$s”.", resourceName), ioe1);
-			} catch (IllegalArgumentException iae1) {
-				logger.log(Level.WARNING, String.format("Could not parse properties from “%1$s”.", resourceName), iae1);
-			}
-		}
-	}
-
-	/**
-	 * A localization (l10n) source.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public static class Source {
-
-		/** The name of the application. */
-		private final String name;
-
-		/** The path of the properties. */
-		private final String propertiesPath;
-
-		/** The default locale of the application. */
-		private final Locale defaultLocale;
-
-		/** The class loader for loading resources. */
-		private final ClassLoader classLoader;
-
-		/**
-		 * Creates a new l10n source.
-		 *
-		 * @param name
-		 *            The name of the application
-		 * @param propertiesPath
-		 *            The path of the properties
-		 * @param defaultLocale
-		 *            The default locale of the source
-		 * @param classLoader
-		 *            The class loader for the source’s resources
-		 */
-		public Source(String name, String propertiesPath, Locale defaultLocale, ClassLoader classLoader) {
-			this.name = name;
-			this.propertiesPath = propertiesPath;
-			this.defaultLocale = defaultLocale;
-			this.classLoader = classLoader;
-		}
-
-		/**
-		 * Returns the name of the application.
-		 *
-		 * @return The name of the application
-		 */
-		public String getName() {
-			return name;
-		}
-
-		/**
-		 * Returns the path of the properties.
-		 *
-		 * @return The path of the properties
-		 */
-		public String getPropertiesPath() {
-			return propertiesPath;
-		}
-
-		/**
-		 * Returns the default locale of the source.
-		 *
-		 * @return The default locale of the source
-		 */
-		public Locale getDefaultLocale() {
-			return defaultLocale;
-		}
-
-		/**
-		 * Returns the source’s class loader.
-		 *
-		 * @return The class loader of the source
-		 */
-		public ClassLoader getClassLoader() {
-			return classLoader;
-		}
-
-	}
-
-	/**
-	 * Identifying container for a removal reference.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public static class RemovalReference {
-
-		/* nothing here. */
-
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/i18n/I18nable.java b/alien/src/net/pterodactylus/util/i18n/I18nable.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/i18n/I18nable.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * utils - I18nable.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.i18n;
-
-/**
- * Interface for objects that want to be notified when the language is changed.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface I18nable {
-
-	/**
-	 * Notifies the object that the language in {@link I18n} was changed.
-	 */
-	public void updateI18n();
-
-}
diff --git a/alien/src/net/pterodactylus/util/i18n/gui/I18nAction.java b/alien/src/net/pterodactylus/util/i18n/gui/I18nAction.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/i18n/gui/I18nAction.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * utils - I18nAction.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.i18n.gui;
-
-import javax.swing.AbstractAction;
-import javax.swing.Action;
-import javax.swing.Icon;
-
-import net.pterodactylus.util.i18n.I18n;
-import net.pterodactylus.util.i18n.I18nable;
-import net.pterodactylus.util.i18n.I18n.RemovalReference;
-
-/**
- * Helper class that initializes actions with values from {@link I18n}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public abstract class I18nAction extends AbstractAction implements I18nable {
-
-	/** The i18n handler. */
-	protected final I18n i18n;
-
-	/** The I18n basename. */
-	private final String i18nName;
-
-	/**
-	 * Creates a new action that uses the given name as base name to get values
-	 * from {@link I18n}.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param i18nName
-	 *            The base name of the action
-	 */
-	public I18nAction(I18n i18n, String i18nName) {
-		this(i18n, null, i18nName);
-	}
-
-	/**
-	 * Creates a new action that uses the given name as base name to get values
-	 * from {@link I18n}.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param removalReference
-	 *            Removal reference (optional)
-	 * @param i18nName
-	 *            The base name of the action
-	 */
-	public I18nAction(I18n i18n, RemovalReference removalReference, String i18nName) {
-		this(i18n, removalReference, i18nName, null);
-	}
-
-	/**
-	 * Creates a new action that uses the given name as base name to get values
-	 * from {@link I18n} and the given icon.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param i18nName
-	 *            The base name of the action
-	 * @param icon
-	 *            The icon for the action
-	 */
-	public I18nAction(I18n i18n, String i18nName, Icon icon) {
-		this(i18n, null, i18nName, icon);
-	}
-
-	/**
-	 * Creates a new action that uses the given name as base name to get values
-	 * from {@link I18n} and the given icon.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param removalReference
-	 *            Removal reference (optional)
-	 * @param i18nName
-	 *            The base name of the action
-	 * @param icon
-	 *            The icon for the action
-	 */
-	public I18nAction(I18n i18n, RemovalReference removalReference, String i18nName, Icon icon) {
-		this(i18n, removalReference, i18nName, true, icon);
-	}
-
-	/**
-	 * Creates a new action that uses the given name as base name to get values
-	 * from {@link I18n}.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param i18nName
-	 *            The base name of the action
-	 * @param enabled
-	 *            Whether the action should be enabled
-	 */
-	public I18nAction(I18n i18n, String i18nName, boolean enabled) {
-		this(i18n, null, i18nName, enabled);
-	}
-
-	/**
-	 * Creates a new action that uses the given name as base name to get values
-	 * from {@link I18n}.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param removalReference
-	 *            Removal reference (optional)
-	 * @param i18nName
-	 *            The base name of the action
-	 * @param enabled
-	 *            Whether the action should be enabled
-	 */
-	public I18nAction(I18n i18n, RemovalReference removalReference, String i18nName, boolean enabled) {
-		this(i18n, removalReference, i18nName, enabled, null);
-	}
-
-	/**
-	 * Creates a new action that uses the given name as base name to get values
-	 * from {@link I18n} and the given icon.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param i18nName
-	 *            The base name of the action
-	 * @param enabled
-	 *            Whether the action should be enabled
-	 * @param icon
-	 *            The icon for the action
-	 */
-	public I18nAction(I18n i18n, String i18nName, boolean enabled, Icon icon) {
-		this(i18n, null, i18nName, enabled, icon);
-	}
-
-	/**
-	 * Creates a new action that uses the given name as base name to get values
-	 * from {@link I18n} and the given icon.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param removalReference
-	 *            Removal reference (optional)
-	 * @param i18nName
-	 *            The base name of the action
-	 * @param enabled
-	 *            Whether the action should be enabled
-	 * @param icon
-	 *            The icon for the action
-	 */
-	public I18nAction(I18n i18n, RemovalReference removalReference, String i18nName, boolean enabled, Icon icon) {
-		this.i18n = i18n;
-		this.i18nName = i18nName;
-		if (icon != null) {
-			putValue(Action.SMALL_ICON, icon);
-		}
-		setEnabled(enabled);
-		i18n.addI18nable(this, removalReference);
-		updateI18n();
-	}
-
-	/**
-	 * Returns the i18n basename of this action.
-	 *
-	 * @return This action’s i18n basename
-	 */
-	String getI18nBasename() {
-		return i18nName;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void updateI18n() {
-		putValue(Action.NAME, i18n.get(i18nName + ".name"));
-		putValue(Action.MNEMONIC_KEY, i18n.getKey(i18nName + ".mnemonic"));
-		putValue(Action.ACCELERATOR_KEY, i18n.getKeyStroke(i18nName + ".accelerator"));
-		putValue(Action.SHORT_DESCRIPTION, i18n.get(i18nName + ".shortDescription"));
-		if (i18n.has(i18nName + ".longDescription")) {
-			putValue(Action.LONG_DESCRIPTION, i18n.get(i18nName + ".longDescription"));
-		} else {
-			putValue(Action.LONG_DESCRIPTION, i18n.get(i18nName + ".shortDescription"));
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/i18n/gui/I18nLabel.java b/alien/src/net/pterodactylus/util/i18n/gui/I18nLabel.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/i18n/gui/I18nLabel.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * utils - I18nLabel.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.i18n.gui;
-
-import java.awt.Component;
-
-import javax.swing.JLabel;
-
-import net.pterodactylus.util.i18n.I18n;
-import net.pterodactylus.util.i18n.I18nable;
-import net.pterodactylus.util.i18n.I18n.RemovalReference;
-
-/**
- * Label that can update itself from {@link I18n}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class I18nLabel extends JLabel implements I18nable {
-
-	/** The i18n handler. */
-	private final I18n i18n;
-
-	/** The I18n basename of the label. */
-	private final String i18nBasename;
-
-	/** Optional arguments for i18n replacement. */
-	private final Object[] arguments;
-
-	/**
-	 * Creates a new label with the given I18n basename.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param i18nBasename
-	 *            The I18n basename of the label
-	 */
-	public I18nLabel(I18n i18n, String i18nBasename) {
-		this(i18n, null, i18nBasename);
-	}
-
-	/**
-	 * Creates a new label with the given I18n basename.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param removalReference
-	 *            Removal reference (optional)
-	 * @param i18nBasename
-	 *            The I18n basename of the label
-	 */
-	public I18nLabel(I18n i18n, RemovalReference removalReference, String i18nBasename) {
-		this(i18n, removalReference, i18nBasename, (Component) null);
-	}
-
-	/**
-	 * Creates a new label with the given I18n basename that optionally is a
-	 * label for the given component.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param i18nBasename
-	 *            The I18n basename of the label
-	 * @param component
-	 *            The component that is activated by the label, or
-	 *            <code>null</code> if this label should not activate a
-	 *            component
-	 */
-	public I18nLabel(I18n i18n, String i18nBasename, Component component) {
-		this(i18n, null, i18nBasename, component);
-	}
-
-	/**
-	 * Creates a new label with the given I18n basename that optionally is a
-	 * label for the given component.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param removalReference
-	 *            Removal reference (optional)
-	 * @param i18nBasename
-	 *            The I18n basename of the label
-	 * @param component
-	 *            The component that is activated by the label, or
-	 *            <code>null</code> if this label should not activate a
-	 *            component
-	 */
-	public I18nLabel(I18n i18n, RemovalReference removalReference, String i18nBasename, Component component) {
-		this(i18n, removalReference, i18nBasename, component, (Object[]) null);
-	}
-
-	/**
-	 * Creates a new label with the given I18n basename that optionally is a
-	 * label for the given component.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param i18nBasename
-	 *            The I18n basename of the label
-	 * @param arguments
-	 *            Optional arguments that are handed in to
-	 *            {@link I18n#get(String, Object...)}
-	 */
-	public I18nLabel(I18n i18n, String i18nBasename, Object... arguments) {
-		this(i18n, (RemovalReference) null, i18nBasename, arguments);
-	}
-
-	/**
-	 * Creates a new label with the given I18n basename that optionally is a
-	 * label for the given component.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param removalReference
-	 *            Removal reference (optional)
-	 * @param i18nBasename
-	 *            The I18n basename of the label
-	 * @param arguments
-	 *            Optional arguments that are handed in to
-	 *            {@link I18n#get(String, Object...)}
-	 */
-	public I18nLabel(I18n i18n, RemovalReference removalReference, String i18nBasename, Object... arguments) {
-		this(i18n, removalReference, i18nBasename, (Component) null, arguments);
-	}
-
-	/**
-	 * Creates a new label with the given I18n basename that optionally is a
-	 * label for the given component.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param i18nBasename
-	 *            The I18n basename of the label
-	 * @param component
-	 *            The component that is activated by the label, or
-	 *            <code>null</code> if this label should not activate a
-	 *            component
-	 * @param arguments
-	 *            Optional arguments that are handed in to
-	 *            {@link I18n#get(String, Object...)}
-	 */
-	public I18nLabel(I18n i18n, String i18nBasename, Component component, Object... arguments) {
-		this(i18n, null, i18nBasename, component, arguments);
-	}
-
-	/**
-	 * Creates a new label with the given I18n basename that optionally is a
-	 * label for the given component.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param removalReference
-	 *            Removal reference (optional)
-	 * @param i18nBasename
-	 *            The I18n basename of the label
-	 * @param component
-	 *            The component that is activated by the label, or
-	 *            <code>null</code> if this label should not activate a
-	 *            component
-	 * @param arguments
-	 *            Optional arguments that are handed in to
-	 *            {@link I18n#get(String, Object...)}
-	 */
-	public I18nLabel(I18n i18n, RemovalReference removalReference, String i18nBasename, Component component, Object... arguments) {
-		super();
-		this.i18n = i18n;
-		this.i18nBasename = i18nBasename;
-		i18n.addI18nable(this, removalReference);
-		this.arguments = arguments;
-		if (component != null) {
-			setLabelFor(component);
-		}
-		updateI18n();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void updateI18n() {
-		setText(i18n.get(i18nBasename + ".name", arguments));
-		if (getLabelFor() != null) {
-			setDisplayedMnemonic(i18n.getKey(i18nBasename + ".mnemonic"));
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/i18n/gui/I18nMenu.java b/alien/src/net/pterodactylus/util/i18n/gui/I18nMenu.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/i18n/gui/I18nMenu.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * utils - I18nMenu.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.i18n.gui;
-
-import javax.swing.JMenu;
-
-import net.pterodactylus.util.i18n.I18n;
-import net.pterodactylus.util.i18n.I18nable;
-import net.pterodactylus.util.i18n.I18n.RemovalReference;
-
-/**
- * Menu that receives its properties from {@link I18n}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class I18nMenu extends JMenu implements I18nable {
-
-	/** The i18n handler. */
-	private final I18n i18n;
-
-	/** The {@link I18n} basename. */
-	private final String i18nBasename;
-
-	/**
-	 * Creates a new menu with the given {@link I18n} basename.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param i18nBasename
-	 *            The basename of the {@link I18n} properties
-	 */
-	public I18nMenu(I18n i18n, String i18nBasename) {
-		this(i18n, null, i18nBasename);
-	}
-
-	/**
-	 * Creates a new menu with the given {@link I18n} basename.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param removalReference
-	 *            Removal reference (optional)
-	 * @param i18nBasename
-	 *            The basename of the {@link I18n} properties
-	 */
-	public I18nMenu(I18n i18n, RemovalReference removalReference, String i18nBasename) {
-		this.i18n = i18n;
-		this.i18nBasename = i18nBasename;
-		i18n.addI18nable(this, removalReference);
-		updateI18n();
-	}
-
-	//
-	// INTERFACE I18nable
-	//
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void updateI18n() {
-		setText(i18n.get(i18nBasename + ".name"));
-		setMnemonic(i18n.getKey(i18nBasename + ".mnemonic"));
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/i18n/gui/I18nMenuItem.java b/alien/src/net/pterodactylus/util/i18n/gui/I18nMenuItem.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/i18n/gui/I18nMenuItem.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * utils - I18nMenuItem.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.i18n.gui;
-
-import java.awt.MenuItem;
-import java.awt.MenuShortcut;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-
-import javax.swing.Action;
-
-import net.pterodactylus.util.i18n.I18n;
-import net.pterodactylus.util.i18n.I18nable;
-import net.pterodactylus.util.i18n.I18n.RemovalReference;
-
-/**
- * {@link I18nable} wrapper around an AWT {@link MenuItem} that can also use an
- * {@link Action} to be performed when it is selected. This should not be used
- * for “normal” Swing applications!
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class I18nMenuItem extends MenuItem implements I18nable {
-
-	/** The i18n handler. */
-	private final I18n i18n;
-
-	/** The i18n basename of the menu item. */
-	private final String i18nBasename;
-
-	/** The action, if this menu item was derived from one. */
-	private final Action action;
-
-	/**
-	 * Creates a new i18nable menu item.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param i18nBasename
-	 *            The i18n basename of the menu item
-	 */
-	public I18nMenuItem(I18n i18n, String i18nBasename) {
-		this(i18n, null, i18nBasename);
-	}
-
-	/**
-	 * Creates a new i18nable menu item.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param removalReference
-	 *            Removal reference (optional)
-	 * @param i18nBasename
-	 *            The i18n basename of the menu item
-	 */
-	public I18nMenuItem(I18n i18n, RemovalReference removalReference, String i18nBasename) {
-		this(i18n, removalReference, i18nBasename, null);
-	}
-
-	/**
-	 * Creates a new i18nable menu item that will perform the given action when
-	 * selected.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param i18nBasename
-	 *            The i18n base name of the menu item
-	 * @param action
-	 *            The action to perform when selected
-	 */
-	public I18nMenuItem(I18n i18n, String i18nBasename, Action action) {
-		this(i18n, null, i18nBasename, action);
-	}
-
-	/**
-	 * Creates a new i18nable menu item that will perform the given action when
-	 * selected.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param removalReference
-	 *            Removal reference (optional)
-	 * @param i18nBasename
-	 *            The i18n base name of the menu item
-	 * @param action
-	 *            The action to perform when selected
-	 */
-	public I18nMenuItem(I18n i18n, RemovalReference removalReference, String i18nBasename, final Action action) {
-		this.i18n = i18n;
-		this.i18nBasename = i18nBasename;
-		i18n.addI18nable(this, removalReference);
-		this.action = action;
-		if (action != null) {
-			addActionListener(new ActionListener() {
-
-				@Override
-				public void actionPerformed(ActionEvent actionEvent) {
-					action.actionPerformed(actionEvent);
-				}
-			});
-			action.addPropertyChangeListener(new PropertyChangeListener() {
-
-				@Override
-				public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
-					if ("enabled".equals(propertyChangeEvent.getPropertyName())) {
-						updateI18n();
-					}
-				}
-			});
-		}
-		updateI18n();
-	}
-
-	/**
-	 * Creates a new i18nable menu item that used the properties of the given
-	 * {@link I18nAction}.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param i18nAction
-	 *            The action to copy
-	 */
-	public I18nMenuItem(I18n i18n, I18nAction i18nAction) {
-		this(i18n, (RemovalReference) null, i18nAction);
-	}
-
-	/**
-	 * Creates a new i18nable menu item that used the properties of the given
-	 * {@link I18nAction}.
-	 *
-	 * @param i18n
-	 *            The i18n handler
-	 * @param removalReference
-	 *            Removal reference (optional)
-	 * @param i18nAction
-	 *            The action to copy
-	 */
-	public I18nMenuItem(I18n i18n, RemovalReference removalReference, I18nAction i18nAction) {
-		this(i18n, removalReference, i18nAction.getI18nBasename(), i18nAction);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void updateI18n() {
-		setLabel(i18n.get(i18nBasename + ".name"));
-		setShortcut(new MenuShortcut(i18n.getKey(i18nBasename + ".mnemonic"), false));
-		if (action != null) {
-			setEnabled(action.isEnabled());
-		}
-	}
-}
diff --git a/alien/src/net/pterodactylus/util/i18n/gui/package-info.java b/alien/src/net/pterodactylus/util/i18n/gui/package-info.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/i18n/gui/package-info.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * utils - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * Contains various i18n-related Swing helper classes.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-
-package net.pterodactylus.util.i18n.gui;
\ No newline at end of file
diff --git a/alien/src/net/pterodactylus/util/image/IconLoader.java b/alien/src/net/pterodactylus/util/image/IconLoader.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/image/IconLoader.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * utils - IconLoader.java - Copyright © 2008-2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.util.image;
-
-import java.awt.Image;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.swing.Icon;
-import javax.swing.ImageIcon;
-
-/**
- * Loads an {@link Icon} or an {@link Image} from the class path.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class IconLoader {
-
-	/**
-	 * Loads an icon from the class path.
-	 *
-	 * @param resourceName
-	 *            The name of the icon
-	 * @return The icon, or <code>null</code> if no icon was found
-	 */
-	public static Icon loadIcon(String resourceName) {
-		try {
-			InputStream resourceStream = IconLoader.class.getResourceAsStream(resourceName);
-			if (resourceStream == null) {
-				return null;
-			}
-			ByteArrayOutputStream imageOutput = new ByteArrayOutputStream();
-			byte[] buffer = new byte[16384];
-			int r = 0;
-			while ((r = resourceStream.read(buffer)) != -1) {
-				imageOutput.write(buffer, 0, r);
-			}
-			imageOutput.flush();
-			return new ImageIcon(imageOutput.toByteArray());
-		} catch (IOException e) {
-			/* ignore. */
-		}
-		return null;
-	}
-
-	/**
-	 * Loads an image from the class path.
-	 *
-	 * @param resourceName
-	 *            The name of the image
-	 * @return The image, or <code>null</code> if no image was found
-	 */
-	public static Image loadImage(String resourceName) {
-		ImageIcon imageIcon = (ImageIcon) loadIcon(resourceName);
-		if (imageIcon == null) {
-			return null;
-		}
-		return imageIcon.getImage();
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/io/BitShiftedInputStream.java b/alien/src/net/pterodactylus/util/io/BitShiftedInputStream.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/io/BitShiftedInputStream.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * utils - BitShiftedOutputStream.java - Copyright © 2006-2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.io;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import net.pterodactylus.util.number.Bits;
-
-/**
- * An InputStream that can read values with a bit size of other than 8.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class BitShiftedInputStream extends FilterInputStream {
-
-	/** The number of bits per value. */
-	protected int valueSize;
-
-	/** The current bit position in the underlying input stream. */
-	protected int currentBitPosition;
-
-	/** The current value from the underlying input stream. */
-	protected int currentValue;
-
-	/**
-	 * Creates a new bit-shifted input stream wrapped around the specified input
-	 * stream with the specified value size.
-	 *
-	 * @param in
-	 *            The input stream to wrap
-	 * @param valueSize
-	 *            The number of bits per value
-	 */
-	public BitShiftedInputStream(InputStream in, int valueSize) {
-		super(in);
-		if ((valueSize < 1) || (valueSize > 32)) {
-			throw new IllegalArgumentException("valueSize out of range 1-32");
-		}
-		this.valueSize = valueSize;
-		currentBitPosition = 8;
-	}
-
-	/**
-	 * Reads a value from the underlying input stream.
-	 *
-	 * @return A value from the underlying input stream
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	@Override
-	public int read() throws IOException {
-		return read(valueSize);
-	}
-
-	/**
-	 * Reads a value with the given number of bits from the underlying input
-	 * stream.
-	 *
-	 * @param valueSize
-	 *            The number of bits to read
-	 * @return A value from the underlying input stream
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public int read(int valueSize) throws IOException {
-		int bitsLeft = valueSize;
-		int value = 0;
-		while (bitsLeft > 0) {
-			if (currentBitPosition > 7) {
-				currentValue = super.read();
-				currentBitPosition = 0;
-			}
-			value = Bits.encodeBits(value, valueSize - bitsLeft, 1, currentValue);
-			currentValue >>>= 1;
-			currentBitPosition++;
-			bitsLeft--;
-		}
-		return value;
-	}
-
-	/**
-	 * Skips the specified number of bits. This can be used to re-align the bit
-	 * stream.
-	 *
-	 * @param numberOfBits
-	 *            The number of bits to skip
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public void skipBits(int numberOfBits) throws IOException {
-		int bitsLeft = numberOfBits;
-		while (bitsLeft > 0) {
-			if (currentBitPosition > 7) {
-				currentValue = super.read();
-				currentBitPosition = 0;
-			}
-			currentValue >>>= 1;
-			currentBitPosition++;
-			bitsLeft--;
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/io/BitShiftedOutputStream.java b/alien/src/net/pterodactylus/util/io/BitShiftedOutputStream.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/io/BitShiftedOutputStream.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * utils - BitShiftedOutputStream.java - Copyright © 2006-2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.io;
-
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-import net.pterodactylus.util.number.Bits;
-
-/**
- * A bit-shifted output stream can write an (almost) arbitrary amount of bits
- * for a value given to {@link #write(int)}. Due to implementation reasons the
- * amount of bits should be between 1 and 32, inclusive. Also note that you can
- * not use the {@link OutputStream#write(byte[])} or
- * {@link OutputStream#write(byte[], int, int)} methods because they will
- * truncate your value to the lowest eight bits which is of course only a
- * problem if you intend to write values larger than eight bits.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class BitShiftedOutputStream extends FilterOutputStream {
-
-	/** The number of bits to write for a value. */
-	private final int valueSize;
-
-	/** The current bit position. */
-	private int currentBitPosition;
-
-	/** The current value. */
-	private int currentValue;
-
-	/**
-	 * Creates a new bit-shifted output stream that writes
-	 * <code>valueSize</code> bits per value.
-	 *
-	 * @param outputStream
-	 *            The underlying output stream
-	 * @param valueSize
-	 *            The number of bits to write with one {@link #write(int)}
-	 *            instruction
-	 * @throws IllegalArgumentException
-	 *             if <code>valueSize</code> is not in the range of 1 to 32,
-	 *             inclusive
-	 */
-	public BitShiftedOutputStream(OutputStream outputStream, int valueSize) throws IllegalArgumentException {
-		super(outputStream);
-		if ((valueSize < 1) || (valueSize > 32)) {
-			throw new IllegalArgumentException("valueSize out of range [1-32]");
-		}
-		this.valueSize = valueSize;
-		this.currentBitPosition = 0;
-		this.currentValue = 0;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see java.io.FilterOutputStream#write(int)
-	 */
-	@Override
-	public void write(int value) throws IOException {
-		int valueLeft = value;
-		int bitsLeft = valueSize;
-		while (bitsLeft > 0) {
-			int bitsToEncode = Math.min(8, Math.min(bitsLeft, 8 - currentBitPosition));
-			currentValue = Bits.encodeBits(currentValue, currentBitPosition, bitsToEncode, valueLeft);
-			valueLeft >>>= bitsToEncode;
-			currentBitPosition += bitsToEncode;
-			bitsLeft -= bitsToEncode;
-			if (currentBitPosition == 8) {
-				super.write(currentValue & 0xff);
-				currentBitPosition = 0;
-				currentValue = -1;
-			}
-		}
-	}
-
-	/**
-	 * Writes the specified number of zero-bits to this stream.
-	 *
-	 * @param numberOfBits
-	 *            The number of zero-bits to write
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public void writePadding(int numberOfBits) throws IOException {
-		writePadding(numberOfBits, 0x00);
-	}
-
-	/**
-	 * Writes the specified number of bits to the stream. The bit used to pad
-	 * the stream is the lowest bit of <code>fillBit</code>.
-	 *
-	 * @param numberOfBits
-	 *            The number of padding bits to write
-	 * @param fillBit
-	 *            Contains at the lowest bit position the padding bit to write
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public void writePadding(int numberOfBits, int fillBit) throws IOException {
-		int bitsLeft = numberOfBits;
-		while (bitsLeft > 0) {
-			currentValue = Bits.encodeBits(currentValue, currentBitPosition, 1, fillBit);
-			currentBitPosition++;
-			bitsLeft--;
-			if (currentBitPosition == 8) {
-				super.write(currentValue & 0xff);
-				currentBitPosition = 0;
-				currentValue = -1;
-			}
-		}
-	}
-
-	/**
-	 * Flushes all unwritten data to the underlying output stream.
-	 * <p>
-	 * This is a convenience method for {@link #flush(int) flush(0x00)} which
-	 * will zero-pad the unused bits in the last byte.
-	 *
-	 * @see java.io.FilterOutputStream#flush()
-	 */
-	@Override
-	public void flush() throws IOException {
-		flush(0x00);
-	}
-
-	/**
-	 * Flushes this output stream, writing all unwritten values to the
-	 * underlying output stream.
-	 *
-	 * @param fillBit
-	 *            The lowest bit of this value will determine what the unused
-	 *            space in a byte is filled with
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public void flush(int fillBit) throws IOException {
-		if (currentBitPosition != 0) {
-			currentValue &= (0xff >> (8 - currentBitPosition));
-			for (int bit = currentBitPosition; bit < 8; bit++) {
-				currentValue = Bits.encodeBits(currentValue, bit, 1, fillBit & 0x01);
-			}
-			currentBitPosition = 0;
-			super.write(currentValue);
-			currentValue = -1;
-		}
-		super.flush();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see java.io.FilterOutputStream#close()
-	 */
-	@Override
-	public void close() throws IOException {
-		flush();
-		super.close();
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/io/Closer.java b/alien/src/net/pterodactylus/util/io/Closer.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/io/Closer.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * utils - Closer.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.io;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.Writer;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.jar.JarFile;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import net.pterodactylus.util.logging.Logging;
-
-/**
- * Helper class that can close all kinds of resources without throwing exception
- * so that clean-up code can be written with less code. All methods check that
- * the given resource is not <code>null</code> before invoking the close()
- * method of the respective type.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Closer {
-
-	/** The logger. */
-	private static final Logger logger = Logging.getLogger(Closer.class.getName());
-
-	/**
-	 * Closes the given result set.
-	 *
-	 * @param resultSet
-	 *            The result set to close
-	 * @see ResultSet#close()
-	 */
-	public static void close(ResultSet resultSet) {
-		if (resultSet != null) {
-			try {
-				resultSet.close();
-			} catch (SQLException ioe1) {
-				/* ignore. */
-			}
-		}
-	}
-
-	/**
-	 * Closes the given statement.
-	 *
-	 * @param statement
-	 *            The statement to close
-	 * @see Statement#close()
-	 */
-	public static void close(Statement statement) {
-		if (statement != null) {
-			try {
-				statement.close();
-			} catch (SQLException ioe1) {
-				/* ignore. */
-			}
-		}
-	}
-
-	/**
-	 * Closes the given connection.
-	 *
-	 * @param connection
-	 *            The connection to close
-	 * @see Connection#close()
-	 */
-	public static void close(Connection connection) {
-		if (connection != null) {
-			try {
-				connection.close();
-			} catch (SQLException ioe1) {
-				/* ignore. */
-			}
-		}
-	}
-
-	/**
-	 * Closes the given server socket.
-	 *
-	 * @param serverSocket
-	 *            The server socket to close
-	 * @see ServerSocket#close()
-	 */
-	public static void close(ServerSocket serverSocket) {
-		if (serverSocket != null) {
-			try {
-				serverSocket.close();
-			} catch (IOException ioe1) {
-				/* ignore. */
-			}
-		}
-	}
-
-	/**
-	 * Closes the given socket.
-	 *
-	 * @param socket
-	 *            The socket to close
-	 * @see Socket#close()
-	 */
-	public static void close(Socket socket) {
-		if (socket != null) {
-			try {
-				socket.close();
-			} catch (IOException ioe1) {
-				/* ignore. */
-			}
-		}
-	}
-
-	/**
-	 * Closes the given input stream.
-	 *
-	 * @param inputStream
-	 *            The input stream to close
-	 * @see InputStream#close()
-	 */
-	public static void close(InputStream inputStream) {
-		if (inputStream != null) {
-			try {
-				inputStream.close();
-			} catch (IOException ioe1) {
-				/* ignore. */
-			}
-		}
-	}
-
-	/**
-	 * Closes the given output stream.
-	 *
-	 * @param outputStream
-	 *            The output stream to close
-	 * @see OutputStream#close()
-	 */
-	public static void close(OutputStream outputStream) {
-		if (outputStream != null) {
-			try {
-				outputStream.close();
-			} catch (IOException ioe1) {
-				/* ignore. */
-			}
-		}
-	}
-
-	/**
-	 * Closes the given reader.
-	 *
-	 * @param reader
-	 *            The reader to close
-	 * @see Reader#close()
-	 */
-	public static void close(Reader reader) {
-		if (reader != null) {
-			try {
-				reader.close();
-			} catch (IOException ioe1) {
-				/* ignore. */
-			}
-		}
-	}
-
-	/**
-	 * Closes the given writer.
-	 *
-	 * @param writer
-	 *            The write to close
-	 * @see Writer#close()
-	 */
-	public static void close(Writer writer) {
-		if (writer != null) {
-			try {
-				writer.close();
-			} catch (IOException ioe1) {
-				/* ignore. */
-			}
-		}
-	}
-
-	/**
-	 * Closes the given jar file.
-	 *
-	 * @param jarFile
-	 *            The JAR file to close
-	 * @see JarFile#close()
-	 */
-	public static void close(JarFile jarFile) {
-		if (jarFile != null) {
-			try {
-				jarFile.close();
-			} catch (IOException ioe1) {
-				/* ignore. */
-			}
-		}
-	}
-
-	/**
-	 * Tries to call the close() method on the given object.
-	 *
-	 * @param object
-	 *            The object to call the close() method on
-	 */
-	public static void close(Object object) {
-		if (object == null) {
-			return;
-		}
-		try {
-			Method closeMethod = object.getClass().getMethod("close");
-			closeMethod.invoke(object);
-		} catch (SecurityException se1) {
-			logger.log(Level.WARNING, "Could not call close() method on " + object, se1);
-		} catch (NoSuchMethodException e1) {
-			/* ignore. */
-		} catch (IllegalArgumentException iae1) {
-			logger.log(Level.WARNING, "Illegal argument for close() method on " + object, iae1);
-		} catch (IllegalAccessException iae1) {
-			logger.log(Level.WARNING, "Could not call close() method on " + object, iae1);
-		} catch (InvocationTargetException e1) {
-			/* ignore. */
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/io/LimitedInputStream.java b/alien/src/net/pterodactylus/util/io/LimitedInputStream.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/io/LimitedInputStream.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * utils - LimitedInputStream.java - Copyright © 2008-2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.io;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * A wrapper around an {@link InputStream} that only supplies a limit number of
- * bytes from the underlying input stream.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class LimitedInputStream extends FilterInputStream {
-
-	/** The remaining number of bytes that can be read. */
-	private long remaining;
-
-	/**
-	 * Creates a new LimitedInputStream that supplies at most
-	 * <code>length</code> bytes from the given input stream.
-	 *
-	 * @param inputStream
-	 *            The input stream
-	 * @param length
-	 *            The number of bytes to read
-	 */
-	public LimitedInputStream(InputStream inputStream, long length) {
-		super(inputStream);
-		remaining = length;
-	}
-
-	/**
-	 * @see java.io.FilterInputStream#available()
-	 */
-	@Override
-	public synchronized int available() throws IOException {
-		if (remaining == 0) {
-			return 0;
-		}
-		return (int) Math.min(super.available(), Math.min(Integer.MAX_VALUE, remaining));
-	}
-
-	/**
-	 * @see java.io.FilterInputStream#read()
-	 */
-	@Override
-	public synchronized int read() throws IOException {
-		int read = -1;
-		if (remaining > 0) {
-			read = super.read();
-			remaining--;
-		}
-		return read;
-	}
-
-	/**
-	 * @see java.io.FilterInputStream#read(byte[], int, int)
-	 */
-	@Override
-	public synchronized int read(byte[] b, int off, int len) throws IOException {
-		if (remaining == 0) {
-			return -1;
-		}
-		int toCopy = (int) Math.min(len, Math.min(remaining, Integer.MAX_VALUE));
-		int read = super.read(b, off, toCopy);
-		remaining -= read;
-		return read;
-	}
-
-	/**
-	 * @see java.io.FilterInputStream#skip(long)
-	 */
-	@Override
-	public synchronized long skip(long n) throws IOException {
-		if ((n < 0) || (remaining == 0)) {
-			return 0;
-		}
-		long skipped = super.skip(Math.min(n, remaining));
-		remaining -= skipped;
-		return skipped;
-	}
-
-	/**
-	 * {@inheritDoc} This method does nothing, as {@link #mark(int)} and
-	 * {@link #reset()} are not supported.
-	 *
-	 * @see java.io.FilterInputStream#mark(int)
-	 */
-	@Override
-	public void mark(int readlimit) {
-		/* do nothing. */
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see java.io.FilterInputStream#markSupported()
-	 * @return <code>false</code>
-	 */
-	@Override
-	public boolean markSupported() {
-		return false;
-	}
-
-	/**
-	 * {@inheritDoc} This method does nothing, as {@link #mark(int)} and
-	 * {@link #reset()} are not supported.
-	 *
-	 * @see java.io.FilterInputStream#reset()
-	 */
-	@Override
-	public void reset() throws IOException {
-		/* do nothing. */
-	}
-
-	/**
-	 * Consumes the input stream, i.e. read all bytes until the limit is
-	 * reached.
-	 *
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public void consume() throws IOException {
-		while (remaining > 0) {
-			skip(remaining);
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/io/MimeTypes.java b/alien/src/net/pterodactylus/util/io/MimeTypes.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/io/MimeTypes.java
+++ /dev/null
@@ -1,834 +0,0 @@
-/*
- * utils - MimeTypes.java - Copyright © 2008-2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.io;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Handles MIME types and maps them to file extensions.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class MimeTypes {
-
-	/** The default MIME type for unknown extensions. */
-	public static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";
-
-	/** List of all MIME types. */
-	private static final List<String> mimeTypes = new ArrayList<String>();
-
-	/** Maps from MIME types to registered extensions. */
-	private static final Map<String, List<String>> mimeTypeExtensions = new HashMap<String, List<String>>();
-
-	/** Maps from extensions to registered MIME types. */
-	private static final Map<String, List<String>> extensionMimeTypes = new HashMap<String, List<String>>();
-
-	/* MIME type list generated from my /etc/mime.types. */
-	static {
-		addMimeType("application/activemessage");
-		addMimeType("application/andrew-inset", "ez");
-		addMimeType("application/applefile");
-		addMimeType("application/atomicmail");
-		addMimeType("application/batch-SMTP");
-		addMimeType("application/beep+xml");
-		addMimeType("application/cals-1840");
-		addMimeType("application/commonground");
-		addMimeType("application/cu-seeme", "cu");
-		addMimeType("application/cybercash");
-		addMimeType("application/dca-rft");
-		addMimeType("application/dec-dx");
-		addMimeType("application/docbook+xml");
-		addMimeType("application/dsptype", "tsp");
-		addMimeType("application/dvcs");
-		addMimeType("application/edi-consent");
-		addMimeType("application/edi-x12");
-		addMimeType("application/edifact");
-		addMimeType("application/eshop");
-		addMimeType("application/font-tdpfr");
-		addMimeType("application/futuresplash", "spl");
-		addMimeType("application/ghostview");
-		addMimeType("application/hta", "hta");
-		addMimeType("application/http");
-		addMimeType("application/hyperstudio");
-		addMimeType("application/iges");
-		addMimeType("application/index");
-		addMimeType("application/index.cmd");
-		addMimeType("application/index.obj");
-		addMimeType("application/index.response");
-		addMimeType("application/index.vnd");
-		addMimeType("application/iotp");
-		addMimeType("application/ipp");
-		addMimeType("application/isup");
-		addMimeType("application/java-archive", "jar");
-		addMimeType("application/java-serialized-object", "ser");
-		addMimeType("application/java-vm", "class");
-		addMimeType("application/mac-binhex40", "hqx");
-		addMimeType("application/mac-compactpro", "cpt");
-		addMimeType("application/macwriteii");
-		addMimeType("application/marc");
-		addMimeType("application/mathematica", "nb");
-		addMimeType("application/mathematica-old");
-		addMimeType("application/msaccess", "mdb");
-		addMimeType("application/msword", "doc", "dot");
-		addMimeType("application/news-message-id");
-		addMimeType("application/news-transmission");
-		addMimeType("application/ocsp-request");
-		addMimeType("application/ocsp-response");
-		addMimeType("application/octet-stream", "bin");
-		addMimeType("application/oda", "oda");
-		addMimeType("application/ogg", "ogg");
-		addMimeType("application/parityfec");
-		addMimeType("application/pdf", "pdf");
-		addMimeType("application/pgp-encrypted");
-		addMimeType("application/pgp-keys", "key");
-		addMimeType("application/pgp-signature", "pgp");
-		addMimeType("application/pics-rules", "prf");
-		addMimeType("application/pkcs10");
-		addMimeType("application/pkcs7-mime");
-		addMimeType("application/pkcs7-signature");
-		addMimeType("application/pkix-cert");
-		addMimeType("application/pkix-crl");
-		addMimeType("application/pkixcmp");
-		addMimeType("application/postscript", "ps", "ai", "eps");
-		addMimeType("application/prs.alvestrand.titrax-sheet");
-		addMimeType("application/prs.cww");
-		addMimeType("application/prs.nprend");
-		addMimeType("application/qsig");
-		addMimeType("application/rar", "rar");
-		addMimeType("application/rdf+xml", "rdf");
-		addMimeType("application/remote-printing");
-		addMimeType("application/riscos");
-		addMimeType("application/rss+xml", "rss");
-		addMimeType("application/rtf");
-		addMimeType("application/sdp");
-		addMimeType("application/set-payment");
-		addMimeType("application/set-payment-initiation");
-		addMimeType("application/set-registration");
-		addMimeType("application/set-registration-initiation");
-		addMimeType("application/sgml");
-		addMimeType("application/sgml-open-catalog");
-		addMimeType("application/sieve");
-		addMimeType("application/slate");
-		addMimeType("application/smil", "smi", "smil");
-		addMimeType("application/timestamp-query");
-		addMimeType("application/timestamp-reply");
-		addMimeType("application/vemmi");
-		addMimeType("application/whoispp-query");
-		addMimeType("application/whoispp-response");
-		addMimeType("application/wita");
-		addMimeType("application/wordperfect", "wpd");
-		addMimeType("application/wordperfect5.1", "wp5");
-		addMimeType("application/x400-bp");
-		addMimeType("application/xhtml+xml", "xhtml", "xht");
-		addMimeType("application/xml", "xml", "xsl");
-		addMimeType("application/xml-dtd");
-		addMimeType("application/xml-external-parsed-entity");
-		addMimeType("application/zip", "zip");
-		addMimeType("application/vnd.3M.Post-it-Notes");
-		addMimeType("application/vnd.accpac.simply.aso");
-		addMimeType("application/vnd.accpac.simply.imp");
-		addMimeType("application/vnd.acucobol");
-		addMimeType("application/vnd.aether.imp");
-		addMimeType("application/vnd.anser-web-certificate-issue-initiation");
-		addMimeType("application/vnd.anser-web-funds-transfer-initiation");
-		addMimeType("application/vnd.audiograph");
-		addMimeType("application/vnd.bmi");
-		addMimeType("application/vnd.businessobjects");
-		addMimeType("application/vnd.canon-cpdl");
-		addMimeType("application/vnd.canon-lips");
-		addMimeType("application/vnd.cinderella", "cdy");
-		addMimeType("application/vnd.claymore");
-		addMimeType("application/vnd.commerce-battelle");
-		addMimeType("application/vnd.commonspace");
-		addMimeType("application/vnd.comsocaller");
-		addMimeType("application/vnd.contact.cmsg");
-		addMimeType("application/vnd.cosmocaller");
-		addMimeType("application/vnd.ctc-posml");
-		addMimeType("application/vnd.cups-postscript");
-		addMimeType("application/vnd.cups-raster");
-		addMimeType("application/vnd.cups-raw");
-		addMimeType("application/vnd.cybank");
-		addMimeType("application/vnd.dna");
-		addMimeType("application/vnd.dpgraph");
-		addMimeType("application/vnd.dxr");
-		addMimeType("application/vnd.ecdis-update");
-		addMimeType("application/vnd.ecowin.chart");
-		addMimeType("application/vnd.ecowin.filerequest");
-		addMimeType("application/vnd.ecowin.fileupdate");
-		addMimeType("application/vnd.ecowin.series");
-		addMimeType("application/vnd.ecowin.seriesrequest");
-		addMimeType("application/vnd.ecowin.seriesupdate");
-		addMimeType("application/vnd.enliven");
-		addMimeType("application/vnd.epson.esf");
-		addMimeType("application/vnd.epson.msf");
-		addMimeType("application/vnd.epson.quickanime");
-		addMimeType("application/vnd.epson.salt");
-		addMimeType("application/vnd.epson.ssf");
-		addMimeType("application/vnd.ericsson.quickcall");
-		addMimeType("application/vnd.eudora.data");
-		addMimeType("application/vnd.fdf");
-		addMimeType("application/vnd.ffsns");
-		addMimeType("application/vnd.flographit");
-		addMimeType("application/vnd.framemaker");
-		addMimeType("application/vnd.fsc.weblaunch");
-		addMimeType("application/vnd.fujitsu.oasys");
-		addMimeType("application/vnd.fujitsu.oasys2");
-		addMimeType("application/vnd.fujitsu.oasys3");
-		addMimeType("application/vnd.fujitsu.oasysgp");
-		addMimeType("application/vnd.fujitsu.oasysprs");
-		addMimeType("application/vnd.fujixerox.ddd");
-		addMimeType("application/vnd.fujixerox.docuworks");
-		addMimeType("application/vnd.fujixerox.docuworks.binder");
-		addMimeType("application/vnd.fut-misnet");
-		addMimeType("application/vnd.grafeq");
-		addMimeType("application/vnd.groove-account");
-		addMimeType("application/vnd.groove-identity-message");
-		addMimeType("application/vnd.groove-injector");
-		addMimeType("application/vnd.groove-tool-message");
-		addMimeType("application/vnd.groove-tool-template");
-		addMimeType("application/vnd.groove-vcard");
-		addMimeType("application/vnd.hhe.lesson-player");
-		addMimeType("application/vnd.hp-HPGL");
-		addMimeType("application/vnd.hp-PCL");
-		addMimeType("application/vnd.hp-PCLXL");
-		addMimeType("application/vnd.hp-hpid");
-		addMimeType("application/vnd.hp-hps");
-		addMimeType("application/vnd.httphone");
-		addMimeType("application/vnd.hzn-3d-crossword");
-		addMimeType("application/vnd.ibm.MiniPay");
-		addMimeType("application/vnd.ibm.afplinedata");
-		addMimeType("application/vnd.ibm.modcap");
-		addMimeType("application/vnd.informix-visionary");
-		addMimeType("application/vnd.intercon.formnet");
-		addMimeType("application/vnd.intertrust.digibox");
-		addMimeType("application/vnd.intertrust.nncp");
-		addMimeType("application/vnd.intu.qbo");
-		addMimeType("application/vnd.intu.qfx");
-		addMimeType("application/vnd.irepository.package+xml");
-		addMimeType("application/vnd.is-xpr");
-		addMimeType("application/vnd.japannet-directory-service");
-		addMimeType("application/vnd.japannet-jpnstore-wakeup");
-		addMimeType("application/vnd.japannet-payment-wakeup");
-		addMimeType("application/vnd.japannet-registration");
-		addMimeType("application/vnd.japannet-registration-wakeup");
-		addMimeType("application/vnd.japannet-setstore-wakeup");
-		addMimeType("application/vnd.japannet-verification");
-		addMimeType("application/vnd.japannet-verification-wakeup");
-		addMimeType("application/vnd.koan");
-		addMimeType("application/vnd.lotus-1-2-3");
-		addMimeType("application/vnd.lotus-approach");
-		addMimeType("application/vnd.lotus-freelance");
-		addMimeType("application/vnd.lotus-notes");
-		addMimeType("application/vnd.lotus-organizer");
-		addMimeType("application/vnd.lotus-screencam");
-		addMimeType("application/vnd.lotus-wordpro");
-		addMimeType("application/vnd.mcd");
-		addMimeType("application/vnd.mediastation.cdkey");
-		addMimeType("application/vnd.meridian-slingshot");
-		addMimeType("application/vnd.mif");
-		addMimeType("application/vnd.minisoft-hp3000-save");
-		addMimeType("application/vnd.mitsubishi.misty-guard.trustweb");
-		addMimeType("application/vnd.mobius.daf");
-		addMimeType("application/vnd.mobius.dis");
-		addMimeType("application/vnd.mobius.msl");
-		addMimeType("application/vnd.mobius.plc");
-		addMimeType("application/vnd.mobius.txf");
-		addMimeType("application/vnd.motorola.flexsuite");
-		addMimeType("application/vnd.motorola.flexsuite.adsi");
-		addMimeType("application/vnd.motorola.flexsuite.fis");
-		addMimeType("application/vnd.motorola.flexsuite.gotap");
-		addMimeType("application/vnd.motorola.flexsuite.kmr");
-		addMimeType("application/vnd.motorola.flexsuite.ttc");
-		addMimeType("application/vnd.motorola.flexsuite.wem");
-		addMimeType("application/vnd.mozilla.xul+xml", "xul");
-		addMimeType("application/vnd.ms-artgalry");
-		addMimeType("application/vnd.ms-asf");
-		addMimeType("application/vnd.ms-excel", "xls", "xlb", "xlt");
-		addMimeType("application/vnd.ms-lrm");
-		addMimeType("application/vnd.ms-pki.seccat", "cat");
-		addMimeType("application/vnd.ms-pki.stl", "stl");
-		addMimeType("application/vnd.ms-powerpoint", "ppt", "pps");
-		addMimeType("application/vnd.ms-project");
-		addMimeType("application/vnd.ms-tnef");
-		addMimeType("application/vnd.ms-works");
-		addMimeType("application/vnd.mseq");
-		addMimeType("application/vnd.msign");
-		addMimeType("application/vnd.music-niff");
-		addMimeType("application/vnd.musician");
-		addMimeType("application/vnd.netfpx");
-		addMimeType("application/vnd.noblenet-directory");
-		addMimeType("application/vnd.noblenet-sealer");
-		addMimeType("application/vnd.noblenet-web");
-		addMimeType("application/vnd.novadigm.EDM");
-		addMimeType("application/vnd.novadigm.EDX");
-		addMimeType("application/vnd.novadigm.EXT");
-		addMimeType("application/vnd.oasis.opendocument.chart", "odc");
-		addMimeType("application/vnd.oasis.opendocument.database", "odb");
-		addMimeType("application/vnd.oasis.opendocument.formula", "odf");
-		addMimeType("application/vnd.oasis.opendocument.graphics", "odg");
-		addMimeType("application/vnd.oasis.opendocument.graphics-template", "otg");
-		addMimeType("application/vnd.oasis.opendocument.image", "odi");
-		addMimeType("application/vnd.oasis.opendocument.presentation", "odp");
-		addMimeType("application/vnd.oasis.opendocument.presentation-template", "otp");
-		addMimeType("application/vnd.oasis.opendocument.spreadsheet", "ods");
-		addMimeType("application/vnd.oasis.opendocument.spreadsheet-template", "ots");
-		addMimeType("application/vnd.oasis.opendocument.text", "odt");
-		addMimeType("application/vnd.oasis.opendocument.text-master", "odm");
-		addMimeType("application/vnd.oasis.opendocument.text-template", "ott");
-		addMimeType("application/vnd.oasis.opendocument.text-web", "oth");
-		addMimeType("application/vnd.osa.netdeploy");
-		addMimeType("application/vnd.palm");
-		addMimeType("application/vnd.pg.format");
-		addMimeType("application/vnd.pg.osasli");
-		addMimeType("application/vnd.powerbuilder6");
-		addMimeType("application/vnd.powerbuilder6-s");
-		addMimeType("application/vnd.powerbuilder7");
-		addMimeType("application/vnd.powerbuilder7-s");
-		addMimeType("application/vnd.powerbuilder75");
-		addMimeType("application/vnd.powerbuilder75-s");
-		addMimeType("application/vnd.previewsystems.box");
-		addMimeType("application/vnd.publishare-delta-tree");
-		addMimeType("application/vnd.pvi.ptid1");
-		addMimeType("application/vnd.pwg-xhtml-print+xml");
-		addMimeType("application/vnd.rapid");
-		addMimeType("application/vnd.rim.cod", "cod");
-		addMimeType("application/vnd.s3sms");
-		addMimeType("application/vnd.seemail");
-		addMimeType("application/vnd.shana.informed.formdata");
-		addMimeType("application/vnd.shana.informed.formtemplate");
-		addMimeType("application/vnd.shana.informed.interchange");
-		addMimeType("application/vnd.shana.informed.package");
-		addMimeType("application/vnd.smaf", "mmf");
-		addMimeType("application/vnd.sss-cod");
-		addMimeType("application/vnd.sss-dtf");
-		addMimeType("application/vnd.sss-ntf");
-		addMimeType("application/vnd.stardivision.calc", "sdc");
-		addMimeType("application/vnd.stardivision.draw", "sda");
-		addMimeType("application/vnd.stardivision.impress", "sdd", "sdp");
-		addMimeType("application/vnd.stardivision.math", "smf");
-		addMimeType("application/vnd.stardivision.writer", "sdw", "vor");
-		addMimeType("application/vnd.stardivision.writer-global", "sgl");
-		addMimeType("application/vnd.street-stream");
-		addMimeType("application/vnd.sun.xml.calc", "sxc");
-		addMimeType("application/vnd.sun.xml.calc.template", "stc");
-		addMimeType("application/vnd.sun.xml.draw", "sxd");
-		addMimeType("application/vnd.sun.xml.draw.template", "std");
-		addMimeType("application/vnd.sun.xml.impress", "sxi");
-		addMimeType("application/vnd.sun.xml.impress.template", "sti");
-		addMimeType("application/vnd.sun.xml.math", "sxm");
-		addMimeType("application/vnd.sun.xml.writer", "sxw");
-		addMimeType("application/vnd.sun.xml.writer.global", "sxg");
-		addMimeType("application/vnd.sun.xml.writer.template", "stw");
-		addMimeType("application/vnd.svd");
-		addMimeType("application/vnd.swiftview-ics");
-		addMimeType("application/vnd.symbian.install", "sis");
-		addMimeType("application/vnd.triscape.mxs");
-		addMimeType("application/vnd.trueapp");
-		addMimeType("application/vnd.truedoc");
-		addMimeType("application/vnd.tve-trigger");
-		addMimeType("application/vnd.ufdl");
-		addMimeType("application/vnd.uplanet.alert");
-		addMimeType("application/vnd.uplanet.alert-wbxml");
-		addMimeType("application/vnd.uplanet.bearer-choice");
-		addMimeType("application/vnd.uplanet.bearer-choice-wbxml");
-		addMimeType("application/vnd.uplanet.cacheop");
-		addMimeType("application/vnd.uplanet.cacheop-wbxml");
-		addMimeType("application/vnd.uplanet.channel");
-		addMimeType("application/vnd.uplanet.channel-wbxml");
-		addMimeType("application/vnd.uplanet.list");
-		addMimeType("application/vnd.uplanet.list-wbxml");
-		addMimeType("application/vnd.uplanet.listcmd");
-		addMimeType("application/vnd.uplanet.listcmd-wbxml");
-		addMimeType("application/vnd.uplanet.signal");
-		addMimeType("application/vnd.vcx");
-		addMimeType("application/vnd.vectorworks");
-		addMimeType("application/vnd.vidsoft.vidconference");
-		addMimeType("application/vnd.visio", "vsd");
-		addMimeType("application/vnd.vividence.scriptfile");
-		addMimeType("application/vnd.wap.sic");
-		addMimeType("application/vnd.wap.slc");
-		addMimeType("application/vnd.wap.wbxml", "wbxml");
-		addMimeType("application/vnd.wap.wmlc", "wmlc");
-		addMimeType("application/vnd.wap.wmlscriptc", "wmlsc");
-		addMimeType("application/vnd.webturbo");
-		addMimeType("application/vnd.wrq-hp3000-labelled");
-		addMimeType("application/vnd.wt.stf");
-		addMimeType("application/vnd.xara");
-		addMimeType("application/vnd.xfdl");
-		addMimeType("application/vnd.yellowriver-custom-menu");
-		addMimeType("application/x-123", "wk");
-		addMimeType("application/x-abiword", "abw");
-		addMimeType("application/x-apple-diskimage", "dmg");
-		addMimeType("application/x-bcpio", "bcpio");
-		addMimeType("application/x-bittorrent", "torrent");
-		addMimeType("application/x-cdf", "cdf");
-		addMimeType("application/x-cdlink", "vcd");
-		addMimeType("application/x-chess-pgn", "pgn");
-		addMimeType("application/x-core");
-		addMimeType("application/x-cpio", "cpio");
-		addMimeType("application/x-csh", "csh");
-		addMimeType("application/x-debian-package", "deb", "udeb");
-		addMimeType("application/x-director", "dcr", "dir", "dxr");
-		addMimeType("application/x-dms", "dms");
-		addMimeType("application/x-doom", "wad");
-		addMimeType("application/x-dvi", "dvi");
-		addMimeType("application/x-executable");
-		addMimeType("application/x-flac", "flac");
-		addMimeType("application/x-font", "pfa", "pfb", "gsf", "pcf", "pcf.Z");
-		addMimeType("application/x-freemind", "mm");
-		addMimeType("application/x-futuresplash", "spl");
-		addMimeType("application/x-gnumeric", "gnumeric");
-		addMimeType("application/x-go-sgf", "sgf");
-		addMimeType("application/x-graphing-calculator", "gcf");
-		addMimeType("application/x-gtar", "gtar", "tgz", "taz");
-		addMimeType("application/x-hdf", "hdf");
-		addMimeType("application/x-ica", "ica");
-		addMimeType("application/x-internet-signup", "ins", "isp");
-		addMimeType("application/x-iphone", "iii");
-		addMimeType("application/x-iso9660-image", "iso");
-		addMimeType("application/x-java-applet");
-		addMimeType("application/x-java-bean");
-		addMimeType("application/x-java-jnlp-file", "jnlp");
-		addMimeType("application/x-javascript", "js");
-		addMimeType("application/x-jmol", "jmz");
-		addMimeType("application/x-kchart", "chrt");
-		addMimeType("application/x-kdelnk");
-		addMimeType("application/x-killustrator", "kil");
-		addMimeType("application/x-koan", "skp", "skd", "skt", "skm");
-		addMimeType("application/x-kpresenter", "kpr", "kpt");
-		addMimeType("application/x-kspread", "ksp");
-		addMimeType("application/x-kword", "kwd", "kwt");
-		addMimeType("application/x-latex", "latex");
-		addMimeType("application/x-lha", "lha");
-		addMimeType("application/x-lzh", "lzh");
-		addMimeType("application/x-lzx", "lzx");
-		addMimeType("application/x-maker", "frm", "maker", "frame", "fm", "fb", "book", "fbdoc");
-		addMimeType("application/x-mif", "mif");
-		addMimeType("application/x-ms-wmd", "wmd");
-		addMimeType("application/x-ms-wmz", "wmz");
-		addMimeType("application/x-msdos-program", "com", "exe", "bat", "dll");
-		addMimeType("application/x-msi", "msi");
-		addMimeType("application/x-netcdf", "nc");
-		addMimeType("application/x-ns-proxy-autoconfig", "pac");
-		addMimeType("application/x-nwc", "nwc");
-		addMimeType("application/x-object", "o");
-		addMimeType("application/x-oz-application", "oza");
-		addMimeType("application/x-pkcs7-certreqresp", "p7r");
-		addMimeType("application/x-pkcs7-crl", "crl");
-		addMimeType("application/x-python-code", "pyc", "pyo");
-		addMimeType("application/x-quicktimeplayer", "qtl");
-		addMimeType("application/x-redhat-package-manager", "rpm");
-		addMimeType("application/x-rx");
-		addMimeType("application/x-sh", "sh");
-		addMimeType("application/x-shar", "shar");
-		addMimeType("application/x-shellscript");
-		addMimeType("application/x-shockwave-flash", "swf", "swfl");
-		addMimeType("application/x-stuffit", "sit");
-		addMimeType("application/x-sv4cpio", "sv4cpio");
-		addMimeType("application/x-sv4crc", "sv4crc");
-		addMimeType("application/x-tar", "tar");
-		addMimeType("application/x-tcl", "tcl");
-		addMimeType("application/x-tex-gf", "gf");
-		addMimeType("application/x-tex-pk", "pk");
-		addMimeType("application/x-texinfo", "texinfo", "texi");
-		addMimeType("application/x-trash", "~", "%", "bak", "old", "sik");
-		addMimeType("application/x-troff", "t", "tr", "roff");
-		addMimeType("application/x-troff-man", "man");
-		addMimeType("application/x-troff-me", "me");
-		addMimeType("application/x-troff-ms", "ms");
-		addMimeType("application/x-ustar", "ustar");
-		addMimeType("application/x-videolan");
-		addMimeType("application/x-wais-source", "src");
-		addMimeType("application/x-wingz", "wz");
-		addMimeType("application/x-x509-ca-cert", "crt");
-		addMimeType("application/x-xcf", "xcf");
-		addMimeType("application/x-xfig", "fig");
-		addMimeType("application/x-xpinstall", "xpi");
-		addMimeType("audio/32kadpcm");
-		addMimeType("audio/basic", "au", "snd");
-		addMimeType("audio/dvi4");
-		addMimeType("audio/g.722.1");
-		addMimeType("audio/g722");
-		addMimeType("audio/g723");
-		addMimeType("audio/g726-16");
-		addMimeType("audio/g726-24");
-		addMimeType("audio/g726-32");
-		addMimeType("audio/g726-40");
-		addMimeType("audio/g728");
-		addMimeType("audio/g729");
-		addMimeType("audio/g729d");
-		addMimeType("audio/g729e");
-		addMimeType("audio/gsm");
-		addMimeType("audio/gsm-efr");
-		addMimeType("audio/l8");
-		addMimeType("audio/l16");
-		addMimeType("audio/lpc");
-		addMimeType("audio/midi", "mid", "midi", "kar");
-		addMimeType("audio/mp4a-latm");
-		addMimeType("audio/mpa");
-		addMimeType("audio/mpa-robust");
-		addMimeType("audio/mpeg", "mpga", "mpega", "mp2", "mp3", "m4a");
-		addMimeType("audio/mpegurl", "m3u");
-		addMimeType("audio/parityfec");
-		addMimeType("audio/pcma");
-		addMimeType("audio/pcmu");
-		addMimeType("audio/prs.sid", "sid");
-		addMimeType("audio/qcelp");
-		addMimeType("audio/red");
-		addMimeType("audio/telephone-event");
-		addMimeType("audio/tone");
-		addMimeType("audio/vdvi");
-		addMimeType("audio/vnd.cisco.nse");
-		addMimeType("audio/vnd.cns.anp1");
-		addMimeType("audio/vnd.cns.inf1");
-		addMimeType("audio/vnd.digital-winds");
-		addMimeType("audio/vnd.everad.plj");
-		addMimeType("audio/vnd.lucent.voice");
-		addMimeType("audio/vnd.nortel.vbk");
-		addMimeType("audio/vnd.nuera.ecelp4800");
-		addMimeType("audio/vnd.nuera.ecelp7470");
-		addMimeType("audio/vnd.nuera.ecelp9600");
-		addMimeType("audio/vnd.octel.sbc");
-		addMimeType("audio/vnd.qcelp");
-		addMimeType("audio/vnd.rhetorex.32kadpcm");
-		addMimeType("audio/vnd.vmx.cvsd");
-		addMimeType("audio/x-aiff", "aif", "aiff", "aifc");
-		addMimeType("audio/x-gsm", "gsm");
-		addMimeType("audio/x-mpegurl", "m3u");
-		addMimeType("audio/x-ms-wma", "wma");
-		addMimeType("audio/x-ms-wax", "wax");
-		addMimeType("audio/x-pn-realaudio-plugin");
-		addMimeType("audio/x-pn-realaudio", "ra", "rm", "ram");
-		addMimeType("audio/x-realaudio", "ra");
-		addMimeType("audio/x-scpls", "pls");
-		addMimeType("audio/x-sd2", "sd2");
-		addMimeType("audio/x-wav", "wav");
-		addMimeType("chemical/x-alchemy", "alc");
-		addMimeType("chemical/x-cache", "cac", "cache");
-		addMimeType("chemical/x-cache-csf", "csf");
-		addMimeType("chemical/x-cactvs-binary", "cbin", "cascii", "ctab");
-		addMimeType("chemical/x-cdx", "cdx");
-		addMimeType("chemical/x-cerius", "cer");
-		addMimeType("chemical/x-chem3d", "c3d");
-		addMimeType("chemical/x-chemdraw", "chm");
-		addMimeType("chemical/x-cif", "cif");
-		addMimeType("chemical/x-cmdf", "cmdf");
-		addMimeType("chemical/x-cml", "cml");
-		addMimeType("chemical/x-compass", "cpa");
-		addMimeType("chemical/x-crossfire", "bsd");
-		addMimeType("chemical/x-csml", "csml", "csm");
-		addMimeType("chemical/x-ctx", "ctx");
-		addMimeType("chemical/x-cxf", "cxf", "cef");
-		addMimeType("chemical/x-embl-dl-nucleotide", "emb", "embl");
-		addMimeType("chemical/x-galactic-spc", "spc");
-		addMimeType("chemical/x-gamess-input", "inp", "gam", "gamin");
-		addMimeType("chemical/x-gaussian-checkpoint", "fch", "fchk");
-		addMimeType("chemical/x-gaussian-cube", "cub");
-		addMimeType("chemical/x-gaussian-input", "gau", "gjc", "gjf");
-		addMimeType("chemical/x-gaussian-log", "gal");
-		addMimeType("chemical/x-gcg8-sequence", "gcg");
-		addMimeType("chemical/x-genbank", "gen");
-		addMimeType("chemical/x-hin", "hin");
-		addMimeType("chemical/x-isostar", "istr", "ist");
-		addMimeType("chemical/x-jcamp-dx", "jdx", "dx");
-		addMimeType("chemical/x-kinemage", "kin");
-		addMimeType("chemical/x-macmolecule", "mcm");
-		addMimeType("chemical/x-macromodel-input", "mmd", "mmod");
-		addMimeType("chemical/x-mdl-molfile", "mol");
-		addMimeType("chemical/x-mdl-rdfile", "rd");
-		addMimeType("chemical/x-mdl-rxnfile", "rxn");
-		addMimeType("chemical/x-mdl-sdfile", "sd", "sdf");
-		addMimeType("chemical/x-mdl-tgf", "tgf");
-		addMimeType("chemical/x-mmcif", "mcif");
-		addMimeType("chemical/x-mol2", "mol2");
-		addMimeType("chemical/x-molconn-Z", "b");
-		addMimeType("chemical/x-mopac-graph", "gpt");
-		addMimeType("chemical/x-mopac-input", "mop", "mopcrt", "mpc", "dat", "zmt");
-		addMimeType("chemical/x-mopac-out", "moo");
-		addMimeType("chemical/x-mopac-vib", "mvb");
-		addMimeType("chemical/x-ncbi-asn1", "asn");
-		addMimeType("chemical/x-ncbi-asn1-ascii", "prt", "ent");
-		addMimeType("chemical/x-ncbi-asn1-binary", "val", "aso");
-		addMimeType("chemical/x-ncbi-asn1-spec", "asn");
-		addMimeType("chemical/x-pdb", "pdb", "ent");
-		addMimeType("chemical/x-rosdal", "ros");
-		addMimeType("chemical/x-swissprot", "sw");
-		addMimeType("chemical/x-vamas-iso14976", "vms");
-		addMimeType("chemical/x-vmd", "vmd");
-		addMimeType("chemical/x-xtel", "xtel");
-		addMimeType("chemical/x-xyz", "xyz");
-		addMimeType("image/cgm");
-		addMimeType("image/g3fax");
-		addMimeType("image/gif", "gif");
-		addMimeType("image/ief", "ief");
-		addMimeType("image/jpeg", "jpeg", "jpg", "jpe");
-		addMimeType("image/naplps");
-		addMimeType("image/pcx", "pcx");
-		addMimeType("image/png", "png");
-		addMimeType("image/prs.btif");
-		addMimeType("image/prs.pti");
-		addMimeType("image/svg+xml", "svg", "svgz");
-		addMimeType("image/tiff", "tiff", "tif");
-		addMimeType("image/vnd.cns.inf2");
-		addMimeType("image/vnd.djvu", "djvu", "djv");
-		addMimeType("image/vnd.dwg");
-		addMimeType("image/vnd.dxf");
-		addMimeType("image/vnd.fastbidsheet");
-		addMimeType("image/vnd.fpx");
-		addMimeType("image/vnd.fst");
-		addMimeType("image/vnd.fujixerox.edmics-mmr");
-		addMimeType("image/vnd.fujixerox.edmics-rlc");
-		addMimeType("image/vnd.mix");
-		addMimeType("image/vnd.net-fpx");
-		addMimeType("image/vnd.svf");
-		addMimeType("image/vnd.wap.wbmp", "wbmp");
-		addMimeType("image/vnd.xiff");
-		addMimeType("image/x-cmu-raster", "ras");
-		addMimeType("image/x-coreldraw", "cdr");
-		addMimeType("image/x-coreldrawpattern", "pat");
-		addMimeType("image/x-coreldrawtemplate", "cdt");
-		addMimeType("image/x-corelphotopaint", "cpt");
-		addMimeType("image/x-icon", "ico");
-		addMimeType("image/x-jg", "art");
-		addMimeType("image/x-jng", "jng");
-		addMimeType("image/x-ms-bmp", "bmp");
-		addMimeType("image/x-photoshop", "psd");
-		addMimeType("image/x-portable-anymap", "pnm");
-		addMimeType("image/x-portable-bitmap", "pbm");
-		addMimeType("image/x-portable-graymap", "pgm");
-		addMimeType("image/x-portable-pixmap", "ppm");
-		addMimeType("image/x-rgb", "rgb");
-		addMimeType("image/x-xbitmap", "xbm");
-		addMimeType("image/x-xpixmap", "xpm");
-		addMimeType("image/x-xwindowdump", "xwd");
-		addMimeType("inode/chardevice");
-		addMimeType("inode/blockdevice");
-		addMimeType("inode/directory-locked");
-		addMimeType("inode/directory");
-		addMimeType("inode/fifo");
-		addMimeType("inode/socket");
-		addMimeType("message/delivery-status");
-		addMimeType("message/disposition-notification");
-		addMimeType("message/external-body");
-		addMimeType("message/http");
-		addMimeType("message/s-http");
-		addMimeType("message/news");
-		addMimeType("message/partial");
-		addMimeType("message/rfc822");
-		addMimeType("model/iges", "igs", "iges");
-		addMimeType("model/mesh", "msh", "mesh", "silo");
-		addMimeType("model/vnd.dwf");
-		addMimeType("model/vnd.flatland.3dml");
-		addMimeType("model/vnd.gdl");
-		addMimeType("model/vnd.gs-gdl");
-		addMimeType("model/vnd.gtw");
-		addMimeType("model/vnd.mts");
-		addMimeType("model/vnd.vtu");
-		addMimeType("model/vrml", "wrl", "vrml");
-		addMimeType("multipart/alternative");
-		addMimeType("multipart/appledouble");
-		addMimeType("multipart/byteranges");
-		addMimeType("multipart/digest");
-		addMimeType("multipart/encrypted");
-		addMimeType("multipart/form-data");
-		addMimeType("multipart/header-set");
-		addMimeType("multipart/mixed");
-		addMimeType("multipart/parallel");
-		addMimeType("multipart/related");
-		addMimeType("multipart/report");
-		addMimeType("multipart/signed");
-		addMimeType("multipart/voice-message");
-		addMimeType("text/calendar", "ics", "icz");
-		addMimeType("text/comma-separated-values", "csv");
-		addMimeType("text/css", "css");
-		addMimeType("text/directory");
-		addMimeType("text/english");
-		addMimeType("text/enriched");
-		addMimeType("text/h323", "323");
-		addMimeType("text/html", "html", "htm", "shtml");
-		addMimeType("text/iuls", "uls");
-		addMimeType("text/mathml", "mml");
-		addMimeType("text/parityfec");
-		addMimeType("text/plain", "asc", "txt", "text", "diff", "pot");
-		addMimeType("text/prs.lines.tag");
-		addMimeType("text/x-psp", "psp");
-		addMimeType("text/rfc822-headers");
-		addMimeType("text/richtext", "rtx");
-		addMimeType("text/rtf", "rtf");
-		addMimeType("text/scriptlet", "sct", "wsc");
-		addMimeType("text/t140");
-		addMimeType("text/texmacs", "tm", "ts");
-		addMimeType("text/tab-separated-values", "tsv");
-		addMimeType("text/uri-list");
-		addMimeType("text/vnd.abc");
-		addMimeType("text/vnd.curl");
-		addMimeType("text/vnd.DMClientScript");
-		addMimeType("text/vnd.flatland.3dml");
-		addMimeType("text/vnd.fly");
-		addMimeType("text/vnd.fmi.flexstor");
-		addMimeType("text/vnd.in3d.3dml");
-		addMimeType("text/vnd.in3d.spot");
-		addMimeType("text/vnd.IPTC.NewsML");
-		addMimeType("text/vnd.IPTC.NITF");
-		addMimeType("text/vnd.latex-z");
-		addMimeType("text/vnd.motorola.reflex");
-		addMimeType("text/vnd.ms-mediapackage");
-		addMimeType("text/vnd.sun.j2me.app-descriptor", "jad");
-		addMimeType("text/vnd.wap.si");
-		addMimeType("text/vnd.wap.sl");
-		addMimeType("text/vnd.wap.wml", "wml");
-		addMimeType("text/vnd.wap.wmlscript", "wmls");
-		addMimeType("text/x-bibtex", "bib");
-		addMimeType("text/x-c++hdr", "h++", "hpp", "hxx", "hh");
-		addMimeType("text/x-c++src", "c++", "cpp", "cxx", "cc");
-		addMimeType("text/x-chdr", "h");
-		addMimeType("text/x-crontab");
-		addMimeType("text/x-csh", "csh");
-		addMimeType("text/x-csrc", "c");
-		addMimeType("text/x-haskell", "hs");
-		addMimeType("text/x-java", "java");
-		addMimeType("text/x-literate-haskell", "lhs");
-		addMimeType("text/x-makefile");
-		addMimeType("text/x-moc", "moc");
-		addMimeType("text/x-pascal", "p", "pas");
-		addMimeType("text/x-pcs-gcd", "gcd");
-		addMimeType("text/x-perl", "pl", "pm");
-		addMimeType("text/x-python", "py");
-		addMimeType("text/x-server-parsed-html");
-		addMimeType("text/x-setext", "etx");
-		addMimeType("text/x-sh", "sh");
-		addMimeType("text/x-tcl", "tcl", "tk");
-		addMimeType("text/x-tex", "tex", "ltx", "sty", "cls");
-		addMimeType("text/x-vcalendar", "vcs");
-		addMimeType("text/x-vcard", "vcf");
-		addMimeType("video/bmpeg");
-		addMimeType("video/bt656");
-		addMimeType("video/celb");
-		addMimeType("video/dl", "dl");
-		addMimeType("video/dv", "dif", "dv");
-		addMimeType("video/fli", "fli");
-		addMimeType("video/gl", "gl");
-		addMimeType("video/jpeg");
-		addMimeType("video/h261");
-		addMimeType("video/h263");
-		addMimeType("video/h263-1998");
-		addMimeType("video/h263-2000");
-		addMimeType("video/mp1s");
-		addMimeType("video/mp2p");
-		addMimeType("video/mp2t");
-		addMimeType("video/mp4", "mp4");
-		addMimeType("video/mp4v-es");
-		addMimeType("video/mpeg", "mpeg", "mpg", "mpe");
-		addMimeType("video/mpv");
-		addMimeType("video/nv");
-		addMimeType("video/parityfec");
-		addMimeType("video/pointer");
-		addMimeType("video/quicktime", "qt", "mov");
-		addMimeType("video/vnd.fvt");
-		addMimeType("video/vnd.motorola.video");
-		addMimeType("video/vnd.motorola.videop");
-		addMimeType("video/vnd.mpegurl", "mxu");
-		addMimeType("video/vnd.mts");
-		addMimeType("video/vnd.nokia.interleaved-multimedia");
-		addMimeType("video/vnd.vivo");
-		addMimeType("video/x-la-asf", "lsf", "lsx");
-		addMimeType("video/x-mng", "mng");
-		addMimeType("video/x-ms-asf", "asf", "asx");
-		addMimeType("video/x-ms-wm", "wm");
-		addMimeType("video/x-ms-wmv", "wmv");
-		addMimeType("video/x-ms-wmx", "wmx");
-		addMimeType("video/x-ms-wvx", "wvx");
-		addMimeType("video/x-msvideo", "avi");
-		addMimeType("video/x-sgi-movie", "movie");
-		addMimeType("video/x-flv", "flv");
-		addMimeType("x-conference/x-cooltalk", "ice");
-		addMimeType("x-world/x-vrml", "vrm", "vrml", "wrl");
-	}
-
-	/**
-	 * Returns a list of all known MIME types.
-	 *
-	 * @return All known MIME types
-	 */
-	public static List<String> getAllMimeTypes() {
-		return new ArrayList<String>(mimeTypes);
-	}
-
-	/**
-	 * Returns a list of MIME types that are registered for the given extension.
-	 *
-	 * @param extension
-	 *            The extension to get the MIME types for
-	 * @return A list of MIME types, or an empty list if there are no registered
-	 *         MIME types for the extension
-	 */
-	public static List<String> getMimeTypes(String extension) {
-		if (extensionMimeTypes.containsKey(extension)) {
-			return extensionMimeTypes.get(extension);
-		}
-		return Collections.emptyList();
-	}
-
-	/**
-	 * Returns a default MIME type for the given extension. If the extension
-	 * does not match a MIME type the default MIME typ
-	 * “application/octet-stream” is returned.
-	 *
-	 * @param extension
-	 *            The extension to get the MIME type for
-	 * @return The MIME type for the extension, or the default MIME type
-	 *         “application/octet-stream”
-	 */
-	public static String getMimeType(String extension) {
-		if (extensionMimeTypes.containsKey(extension)) {
-			return extensionMimeTypes.get(extension).get(0);
-		}
-		return DEFAULT_CONTENT_TYPE;
-	}
-
-	//
-	// PRIVATE METHODS
-	//
-
-	/**
-	 * Adds a MIME type and optional extensions.
-	 *
-	 * @param mimeType
-	 *            The MIME type to add
-	 * @param extensions
-	 *            The extension the MIME type is registered for
-	 */
-	private static void addMimeType(String mimeType, String... extensions) {
-		mimeTypes.add(mimeType);
-		for (String extension : extensions) {
-			if (!mimeTypeExtensions.containsKey(mimeType)) {
-				mimeTypeExtensions.put(mimeType, new ArrayList<String>());
-			}
-			mimeTypeExtensions.get(mimeType).add(extension);
-			if (!extensionMimeTypes.containsKey(extension)) {
-				extensionMimeTypes.put(extension, new ArrayList<String>());
-			}
-			extensionMimeTypes.get(extension).add(mimeType);
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/io/Renderable.java b/alien/src/net/pterodactylus/util/io/Renderable.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/io/Renderable.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * utils - Renderable.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.io;
-
-import java.io.IOException;
-import java.io.Writer;
-
-/**
- * Interface for objects that can render themselves to a {@link Writer}. It is
- * not suitable for objects that want to write binary output.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface Renderable {
-
-	/**
-	 * Renders this object to the given writer.
-	 *
-	 * @param writer
-	 *            The writer to render the object to
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public void render(Writer writer) throws IOException;
-
-}
diff --git a/alien/src/net/pterodactylus/util/io/StreamCopier.java b/alien/src/net/pterodactylus/util/io/StreamCopier.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/io/StreamCopier.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * utils - Closer.java - Copyright © 2006-2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.io;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * Helper class that copies bytes from an {@link InputStream} to an
- * {@link OutputStream}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class StreamCopier {
-
-	/** Default buffer size is 64k. */
-	private static final int DEFAULT_BUFFER_SIZE = 1 << 16;
-
-	/** The current buffer size. */
-	private static int bufferSize = DEFAULT_BUFFER_SIZE;
-
-	/**
-	 * Sets the buffer size for following transfers.
-	 *
-	 * @param bufferSize
-	 *            The new buffer size
-	 */
-	public static void setBufferSize(int bufferSize) {
-		StreamCopier.bufferSize = bufferSize;
-	}
-
-	/**
-	 * Copies <code>length</code> bytes from the source input stream to the
-	 * destination output stream. If <code>length</code> is <code>-1</code> as
-	 * much bytes as possible will be copied (i.e. until
-	 * {@link InputStream#read()} returns <code>-1</code> to signal the end of
-	 * the stream).
-	 *
-	 * @param source
-	 *            The input stream to read from
-	 * @param destination
-	 *            The output stream to write to
-	 * @param length
-	 *            The number of bytes to copy
-	 * @return The number of bytes that have been read from the input stream and
-	 *         written to the output stream
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public static long copy(InputStream source, OutputStream destination, long length) throws IOException {
-		long remaining = length;
-		byte[] buffer = new byte[bufferSize];
-		long total = 0;
-		int read = 0;
-		while ((remaining == -1) || (remaining > 0)) {
-			read = source.read(buffer, 0, ((remaining > bufferSize) || (remaining == -1)) ? bufferSize : (int) remaining);
-			if (read == -1) {
-				if (length == -1) {
-					return total;
-				}
-				throw new EOFException("stream reached eof");
-			}
-			destination.write(buffer, 0, read);
-			if (remaining > -1) {
-				remaining -= read;
-			}
-			total += read;
-		}
-		return total;
-	}
-
-	/**
-	 * Copies as much bytes as possible (i.e. until {@link InputStream#read()}
-	 * returns <code>-1</code>) from the source input stream to the destination
-	 * output stream.
-	 *
-	 * @param source
-	 *            The input stream to read from
-	 * @param destination
-	 *            The output stream to write to
-	 * @return The number of bytes that have been read from the input stream and
-	 *         written to the output stream
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public static long copy(InputStream source, OutputStream destination) throws IOException {
-		return copy(source, destination, -1);
-	}
-
-	/**
-	 * Finds the length of the input stream by reading until
-	 * {@link InputStream#read(byte[])} returns <code>-1</code>.
-	 *
-	 * @param source
-	 *            The input stream to measure
-	 * @return The length of the input stream in bytes
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public static long findLength(InputStream source) throws IOException {
-		long length = 0;
-		byte[] buffer = new byte[bufferSize];
-		int read = 0;
-		while (read != -1) {
-			read = source.read(buffer);
-			if (read != -1) {
-				length += read;
-			}
-		}
-		return length;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/io/TeeOutputStream.java b/alien/src/net/pterodactylus/util/io/TeeOutputStream.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/io/TeeOutputStream.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * utils - TeeOutputStream.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.io;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * {@link OutputStream} that sends all data it receives to multiple other output
- * streams. If an error occurs during a {@link #write(int)} to one of the
- * underlying output streams no guarantees are made about how much data is sent
- * to each stream, i.e. there is no good way to recover from such an error.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class TeeOutputStream extends OutputStream {
-
-	/** The output streams. */
-	private final OutputStream[] outputStreams;
-
-	/**
-	 * Creates a new tee output stream that sends all to all given output
-	 * streams.
-	 *
-	 * @param outputStreams
-	 *            The output streams to send all data to
-	 */
-	public TeeOutputStream(OutputStream... outputStreams) {
-		this.outputStreams = outputStreams;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void write(int data) throws IOException {
-		for (OutputStream outputStream : outputStreams) {
-			outputStream.write(data);
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void write(byte[] buffer) throws IOException {
-		for (OutputStream outputStream : outputStreams) {
-			outputStream.write(buffer);
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void write(byte[] buffer, int offset, int length) throws IOException {
-		for (OutputStream outputStream : outputStreams) {
-			outputStream.write(buffer, offset, length);
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 * <p>
-	 * An effort is made to flush all output streams. If multiple exceptions
-	 * occur, only the first exception is thrown after all output streams have
-	 * been tried to flush.
-	 */
-	@Override
-	public void flush() throws IOException {
-		IOException occuredException = null;
-		for (OutputStream outputStream : outputStreams) {
-			try {
-				outputStream.flush();
-			} catch (IOException ioe1) {
-				if (occuredException == null) {
-					occuredException = ioe1;
-				}
-			}
-		}
-		if (occuredException != null) {
-			throw occuredException;
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 * <p>
-	 * An effort is made to close all output streams. If multiple exceptions
-	 * occur, only the first exception is thrown after all output streams have
-	 * been tried to close.
-	 */
-	@Override
-	public void close() throws IOException {
-		IOException occuredException = null;
-		for (OutputStream outputStream : outputStreams) {
-			try {
-				outputStream.flush();
-			} catch (IOException ioe1) {
-				if (occuredException == null) {
-					occuredException = ioe1;
-				}
-			}
-		}
-		if (occuredException != null) {
-			throw occuredException;
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/io/TemporaryInputStream.java b/alien/src/net/pterodactylus/util/io/TemporaryInputStream.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/io/TemporaryInputStream.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * utils - TemporaryInputStream.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.io;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * An input stream implementation that copies a given input stream to a
- * temporary file and delivers the content of the temporary file at a later
- * time.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class TemporaryInputStream extends FilterInputStream {
-
-	/**
-	 * Maps input streams to temporary files, for deletion on {@link #close()}.
-	 */
-	private static final Map<InputStream, File> streamFiles = new HashMap<InputStream, File>();
-
-	/** Counter for streams per file. */
-	private static final Map<File, Integer> fileCounts = new HashMap<File, Integer>();
-
-	/**
-	 * Creates a new temporary input stream.
-	 *
-	 * @param sourceInputStream
-	 *            The input stream to copy to a temporary file
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public TemporaryInputStream(InputStream sourceInputStream) throws IOException {
-		super(createFileInputStream(sourceInputStream));
-	}
-
-	/**
-	 * Creates a new temporary input stream from the given temporary file.
-	 *
-	 * @param tempFile
-	 *            The temporary file
-	 * @throws FileNotFoundException
-	 *             if the file can not be found
-	 */
-	private TemporaryInputStream(File tempFile) throws FileNotFoundException {
-		super(new FileInputStream(tempFile));
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void close() throws IOException {
-		super.close();
-		synchronized (fileCounts) {
-			File tempFile = streamFiles.remove(in);
-			if (tempFile != null) {
-				if (fileCounts.get(tempFile) > 0) {
-					fileCounts.put(tempFile, fileCounts.get(tempFile) - 1);
-				} else {
-					fileCounts.remove(tempFile);
-					tempFile.delete();
-				}
-			}
-		}
-	}
-
-	/**
-	 * Creates a new input stream from the temporary file that is backing this
-	 * input stream. If the file has already been removed, this method will
-	 * throw an exception.
-	 *
-	 * @return A new input stream
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	public InputStream reopen() throws IOException {
-		synchronized (fileCounts) {
-			File tempFile = streamFiles.get(in);
-			if (tempFile != null) {
-				fileCounts.put(tempFile, fileCounts.get(tempFile) + 1);
-				return new TemporaryInputStream(tempFile);
-			}
-			throw new FileNotFoundException("Temporary file has already disappeared.");
-		}
-	}
-
-	/**
-	 * Creates a temporary file, copies the given input stream to the temporary
-	 * file, and creates an input stream reading from the temporary file. The
-	 * returned input stream will delete the temporary file when its
-	 * {@link #close()} method is called.
-	 *
-	 * @param sourceInputStream
-	 *            The input stream to copy
-	 * @return The copied input stream, ready for consumption
-	 * @throws IOException
-	 */
-	private static InputStream createFileInputStream(InputStream sourceInputStream) throws IOException {
-		File tempFile = File.createTempFile("utils-temp-", ".tmp");
-		tempFile.deleteOnExit();
-		FileOutputStream fileOutputStream = null;
-		try {
-			fileOutputStream = new FileOutputStream(tempFile);
-			StreamCopier.copy(sourceInputStream, fileOutputStream);
-		} catch (IOException ioe1) {
-			throw ioe1;
-		} finally {
-			Closer.close(fileOutputStream);
-		}
-		FileInputStream fileInputStream = null;
-		try {
-			fileInputStream = new FileInputStream(tempFile);
-			streamFiles.put(fileInputStream, tempFile);
-			synchronized (fileCounts) {
-				fileCounts.put(tempFile, 0);
-			}
-			return fileInputStream;
-		} catch (IOException ioe1) {
-			Closer.close(fileInputStream);
-			tempFile.delete();
-			throw ioe1;
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/notify/AbstractNotification.java b/alien/src/net/pterodactylus/util/notify/AbstractNotification.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/notify/AbstractNotification.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * utils - AbstractNotification.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.notify;
-
-import java.util.UUID;
-
-/**
- * Abstract base implementation of a {@link Notification} that takes care of
- * everything but creating the text of the notification, so only
- * {@link Notification#render(java.io.Writer)} needs to be override by
- * subclasses.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public abstract class AbstractNotification implements Notification {
-
-	/** The listener manager. */
-	private final NotificationListenerManager notificationListenerManager = new NotificationListenerManager(this);
-
-	/** The ID of this notification. */
-	private final String id;
-
-	/** The time when this notification was created. */
-	private final long createdTime;
-
-	/** The time when this notification was last updated. */
-	private volatile long lastUpdatedTime;
-
-	/** Whether this notification is dismissable. */
-	private volatile boolean dismissable;
-
-	/**
-	 * Creates a new notification with a random ID, the current time as creation
-	 * and last udpate time and is dismissable by the user.
-	 */
-	public AbstractNotification() {
-		this(UUID.randomUUID().toString());
-	}
-
-	/**
-	 * Creates a new notification with the current time as creation and last
-	 * udpate time and is dismissable by the user.
-	 *
-	 * @param id
-	 *            The ID of the notification
-	 */
-	public AbstractNotification(String id) {
-		this(id, System.currentTimeMillis());
-	}
-
-	/**
-	 * Creates a new notification with the given time as creation and last
-	 * update time and is dismissable by the user.
-	 *
-	 * @param id
-	 *            The ID of the notification
-	 * @param createdTime
-	 *            The time when this notification was created
-	 */
-	public AbstractNotification(String id, long createdTime) {
-		this(id, createdTime, createdTime);
-	}
-
-	/**
-	 * Creates a new notification with the given creation and last update time
-	 * and is dismissable by the user.
-	 *
-	 * @param id
-	 *            The ID of the notification
-	 * @param createdTime
-	 *            The time when this notification was created
-	 * @param lastUpdatedTime
-	 *            The time when this notification was last udpated
-	 */
-	public AbstractNotification(String id, long createdTime, long lastUpdatedTime) {
-		this(id, createdTime, lastUpdatedTime, true);
-	}
-
-	/**
-	 * Creates a new notification.
-	 *
-	 * @param id
-	 *            The ID of the notification
-	 * @param createdTime
-	 *            The time when this notification was created
-	 * @param lastUpdatedTime
-	 *            The time when this notification was last udpated
-	 * @param dismissable
-	 *            {@code true} if this notification is dismissable by the user
-	 */
-	public AbstractNotification(String id, long createdTime, long lastUpdatedTime, boolean dismissable) {
-		this.id = id;
-		this.createdTime = createdTime;
-		this.lastUpdatedTime = lastUpdatedTime;
-		this.dismissable = dismissable;
-	}
-
-	//
-	// LISTENER MANAGEMENT
-	//
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void addNotificationListener(NotificationListener notificationListener) {
-		notificationListenerManager.addListener(notificationListener);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void removeNotificationListener(NotificationListener notificationListener) {
-		notificationListenerManager.removeListener(notificationListener);
-	}
-
-	//
-	// ACCESSORS
-	//
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String getId() {
-		return id;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public long getCreatedTime() {
-		return createdTime;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public long getLastUpdatedTime() {
-		return lastUpdatedTime;
-	}
-
-	/**
-	 * Sets the last updated time.
-	 *
-	 * @param lastUpdateTime
-	 *            The time this notification was last updated
-	 */
-	public void setLastUpdateTime(long lastUpdateTime) {
-		this.lastUpdatedTime = lastUpdateTime;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean isDismissable() {
-		return dismissable;
-	}
-
-	/**
-	 * Sets whether this notification is dismissable.
-	 *
-	 * @param dismissable
-	 *            {@code true} if this notification is dismissable
-	 */
-	public void setDismissable(boolean dismissable) {
-		this.dismissable = dismissable;
-	}
-
-	//
-	// ACTIONS
-	//
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void dismiss() {
-		notificationListenerManager.fireNotificationDismissed();
-	}
-
-	/**
-	 * Updates the {@link #getLastUpdatedTime() last update time} to the current
-	 * time.
-	 */
-	protected void touch() {
-		setLastUpdateTime(System.currentTimeMillis());
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/notify/Notification.java b/alien/src/net/pterodactylus/util/notify/Notification.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/notify/Notification.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * utils - Notification.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.notify;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Comparator;
-
-import net.pterodactylus.util.io.Renderable;
-
-/**
- * A notification can be used to keep track of things that a user needs to be
- * notified about.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface Notification extends Renderable {
-
-	/** Sorts notifications by creation time, oldest first. */
-	public static final Comparator<Notification> CREATED_TIME_SORTER = new Comparator<Notification>() {
-
-		@Override
-		public int compare(Notification leftNotification, Notification rightNotification) {
-			return (int) Math.max(Integer.MIN_VALUE, Math.min(Integer.MAX_VALUE, leftNotification.getCreatedTime() - rightNotification.getCreatedTime()));
-		}
-
-	};
-
-	/** Sorts notifications by last update time, newest first. */
-	public static final Comparator<Notification> LAST_UPDATED_TIME_SORTER = new Comparator<Notification>() {
-
-		@Override
-		public int compare(Notification leftNotification, Notification rightNotification) {
-			return (int) Math.max(Integer.MIN_VALUE, Math.min(Integer.MAX_VALUE, rightNotification.getLastUpdatedTime() - leftNotification.getLastUpdatedTime()));
-		}
-
-	};
-
-	/**
-	 * Adds the given notification listener.
-	 *
-	 * @param notificationListener
-	 *            The listener to add
-	 */
-	public void addNotificationListener(NotificationListener notificationListener);
-
-	/**
-	 * Removes the given notification listener.
-	 *
-	 * @param notificationListener
-	 *            The listener to remove
-	 */
-	public void removeNotificationListener(NotificationListener notificationListener);
-
-	/**
-	 * Returns the unique ID of this notification.
-	 *
-	 * @return The unique ID of this notification
-	 */
-	public String getId();
-
-	/**
-	 * Returns the time when this notifiation was last updated.
-	 *
-	 * @return The time when this notification was last updated (in milliseconds
-	 *         since Jan 1 1970, UTC)
-	 */
-	public long getLastUpdatedTime();
-
-	/**
-	 * Returns the time when this notifiation was created.
-	 *
-	 * @return The time when this notification was created (in milliseconds
-	 *         since Jan 1 1970, UTC)
-	 */
-	public long getCreatedTime();
-
-	/**
-	 * Returns whether this notification may be dismissed by the user.
-	 *
-	 * @return {@code true} if this notification is dismissable by the user,
-	 *         {@code false} otherwise
-	 */
-	public boolean isDismissable();
-
-	/**
-	 * Dismisses this notification.
-	 */
-	public void dismiss();
-
-	/**
-	 * Renders this notification to the given writer.
-	 *
-	 * @param writer
-	 *            The writer to render this notification to
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	@Override
-	public void render(Writer writer) throws IOException;
-
-}
diff --git a/alien/src/net/pterodactylus/util/notify/NotificationListener.java b/alien/src/net/pterodactylus/util/notify/NotificationListener.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/notify/NotificationListener.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * utils - NotificationListener.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.notify;
-
-import java.util.EventListener;
-
-/**
- * Listener interface for objects that want to be notified on certain
- * {@link Notification} events, such as when the notification is dismissed.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface NotificationListener extends EventListener {
-
-	/**
-	 * Notifies a listener that the given notification was dismissed.
-	 *
-	 * @param notification
-	 *            The dismissed notification
-	 */
-	public void notificationDismissed(Notification notification);
-
-}
diff --git a/alien/src/net/pterodactylus/util/notify/NotificationListenerManager.java b/alien/src/net/pterodactylus/util/notify/NotificationListenerManager.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/notify/NotificationListenerManager.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * utils - NotificationListenerManager.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.notify;
-
-import net.pterodactylus.util.event.AbstractListenerManager;
-
-/**
- * Manager for {@link NotificationListener}s and {@link Notification} events.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class NotificationListenerManager extends AbstractListenerManager<Notification, NotificationListener> {
-
-	/**
-	 * Creates a new {@link NotificationListener} manager.
-	 *
-	 * @param source
-	 *            The notification that emits all events
-	 */
-	public NotificationListenerManager(Notification source) {
-		super(source);
-	}
-
-	//
-	// ACTIONS
-	//
-
-	/**
-	 * Notifies all listeners that a notification was dismissed.
-	 *
-	 * @see NotificationListener#notificationDismissed(Notification)
-	 */
-	void fireNotificationDismissed() {
-		for (NotificationListener notificationListener : getListeners()) {
-			notificationListener.notificationDismissed(getSource());
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/notify/NotificationManager.java b/alien/src/net/pterodactylus/util/notify/NotificationManager.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/notify/NotificationManager.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * utils - Notifications.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.notify;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Manager for all current notifications.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class NotificationManager implements NotificationListener {
-
-	/** All notifications. */
-	private final Map<String, Notification> notifications = new HashMap<String, Notification>();
-
-	/** Notifications removed since last retrieval. */
-	/* synchronize access on notifications. */
-	private final Map<String, Notification> removedNotifications = new HashMap<String, Notification>();
-
-	/** The time the notifications were last retrieved. */
-	/* synchronize access on {@link #notifications}. */
-	private long lastRetrievalTime;
-
-	//
-	// ACCESSORS
-	//
-
-	/**
-	 * Returns all current notifications.
-	 *
-	 * @return All current notifications
-	 */
-	public Set<Notification> getNotifications() {
-		synchronized (notifications) {
-			lastRetrievalTime = System.currentTimeMillis();
-			return new HashSet<Notification>(notifications.values());
-		}
-	}
-
-	/**
-	 * Returns all notifications that have been updated since the last
-	 * retrieval.
-	 *
-	 * @return All changed notifications
-	 */
-	public Set<Notification> getChangedNotifications() {
-		Set<Notification> changedNotifications = new HashSet<Notification>();
-		synchronized (notifications) {
-			for (Notification notification : notifications.values()) {
-				if (notification.getLastUpdatedTime() > lastRetrievalTime) {
-					changedNotifications.add(notification);
-				}
-			}
-			lastRetrievalTime = System.currentTimeMillis();
-		}
-		return changedNotifications;
-	}
-
-	/**
-	 * Returns all notifications that have been removed since the last retrieval
-	 * and clears the list of removed notifications.
-	 *
-	 * @return All removed notifications
-	 */
-	public Set<Notification> getRemovedNotifications() {
-		Set<Notification> notifications;
-		synchronized (this.notifications) {
-			notifications = new HashSet<Notification>(removedNotifications.values());
-			removedNotifications.clear();
-		}
-		return notifications;
-	}
-
-	/**
-	 * Returns the notification with the given ID.
-	 *
-	 * @param notificationId
-	 *            The ID of the notification
-	 * @return The notification, or {@code null} if there is no notification
-	 *         with the given ID
-	 */
-	public Notification getNotification(String notificationId) {
-		synchronized (notifications) {
-			return notifications.get(notificationId);
-		}
-	}
-
-	/**
-	 * Adds the given notification.
-	 *
-	 * @param notification
-	 *            The notification to add
-	 */
-	public void addNotification(Notification notification) {
-		synchronized (notifications) {
-			if (!notifications.containsKey(notification.getId())) {
-				notifications.put(notification.getId(), notification);
-				notification.addNotificationListener(this);
-				removedNotifications.remove(notification.getId());
-			}
-		}
-	}
-
-	/**
-	 * Removes the given notification.
-	 *
-	 * @param notification
-	 *            The notification to remove
-	 */
-	public void removeNotification(Notification notification) {
-		synchronized (notifications) {
-			if (notifications.containsKey(notification.getId())) {
-				notifications.remove(notification.getId());
-				notification.removeNotificationListener(this);
-				removedNotifications.put(notification.getId(), notification);
-			}
-		}
-	}
-
-	//
-	// NOTIFICATIONLISTENER METHODS
-	//
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void notificationDismissed(Notification notification) {
-		removeNotification(notification);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/notify/TemplateNotification.java b/alien/src/net/pterodactylus/util/notify/TemplateNotification.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/notify/TemplateNotification.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * utils - TemplateNotification.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.notify;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-
-import net.pterodactylus.util.io.Closer;
-import net.pterodactylus.util.template.Template;
-
-/**
- * {@link Template}-based implementation of a {@link Notification}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class TemplateNotification extends AbstractNotification {
-
-	/** The template to render. */
-	private final Template template;
-
-	/**
-	 * Creates a new notification.
-	 *
-	 * @param template
-	 *            The template to render
-	 */
-	public TemplateNotification(Template template) {
-		super();
-		this.template = template;
-	}
-
-	/**
-	 * Creates a new notification.
-	 *
-	 * @param id
-	 *            The ID of the notification
-	 * @param template
-	 *            The template to render
-	 */
-	public TemplateNotification(String id, Template template) {
-		super(id);
-		this.template = template;
-	}
-
-	/**
-	 * Creates a new notification.
-	 *
-	 * @param id
-	 *            The ID of the notification
-	 * @param creationTime
-	 *            The creation time of the notification
-	 * @param lastUpdatedTime
-	 *            The time the notification was last udpated
-	 * @param dismissable
-	 *            {@code true} if this notification is dismissable by the user
-	 * @param template
-	 *            The template to render
-	 */
-	public TemplateNotification(String id, long creationTime, long lastUpdatedTime, boolean dismissable, Template template) {
-		super(id, creationTime, lastUpdatedTime, dismissable);
-		this.template = template;
-	}
-
-	//
-	// ACCESSORS
-	//
-
-	/**
-	 * Returns the template that renders this notification.
-	 *
-	 * @return The template that renders this notification
-	 */
-	public Template getTemplate() {
-		return template;
-	}
-
-	//
-	// NOTIFICATION METHODS
-	//
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void render(Writer writer) throws IOException {
-		template.render(writer);
-	}
-
-	//
-	// OBJECT METHODS
-	//
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		StringWriter stringWriter = new StringWriter();
-		try {
-			render(stringWriter);
-		} catch (IOException ioe1) {
-			/* A StringWriter never throws. */
-		} finally {
-			Closer.close(stringWriter);
-		}
-		return stringWriter.toString();
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/number/Bits.java b/alien/src/net/pterodactylus/util/number/Bits.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/number/Bits.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * utils - Bits.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.number;
-
-/**
- * Utility class for bit manipulations.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Bits {
-
-	/**
-	 * Decodes <code>numberOfBits</code> bits from the specified start index.
-	 * The resulting value has the range <code>0</code> to
-	 * <code>2 ^ numberOfBits - 1</code>.
-	 *
-	 * @param value
-	 *            The value to decode bits from
-	 * @param bitIndex
-	 *            The index of the first bit to decode
-	 * @param numberOfBits
-	 *            The number of bits to decode
-	 * @return The decoded value
-	 */
-	public static int decodeBits(int value, int bitIndex, int numberOfBits) {
-		return (value >> bitIndex) & ((1 << numberOfBits) - 1);
-	}
-
-	/**
-	 * Changes <code>numberOfBits</code> bits starting from index
-	 * <code>bitIndex</code> in <code>octet</code> to the
-	 * <code>numberOfBits</code> lowest bits from <code>newValue</code>.
-	 *
-	 * @param oldValue
-	 *            The value to change
-	 * @param bitIndex
-	 *            The index of the lowest bit to change
-	 * @param numberOfBits
-	 *            The number of bits to change
-	 * @param newValue
-	 *            The new value of the changed bits
-	 * @return <code>octet</code> with the specified bits changed
-	 */
-	public static int encodeBits(int oldValue, int bitIndex, int numberOfBits, int newValue) {
-		return (oldValue & ~(((1 << numberOfBits) - 1) << bitIndex)) | ((newValue & ((1 << numberOfBits) - 1)) << bitIndex);
-	}
-
-	/**
-	 * Rotates the bits in the given value to the left.
-	 *
-	 * @param value
-	 *            The value to rotate
-	 * @param distance
-	 *            The distance of the rotation, in bits
-	 * @return The rotated value
-	 */
-	public static int rotateLeft(int value, int distance) {
-		return (value << (distance & 0x1f)) | (value >>> ((32 - distance) & 0x1f));
-	}
-
-	/**
-	 * Rotates the bits in the given value to the right.
-	 *
-	 * @param value
-	 *            The value to rotate
-	 * @param distance
-	 *            The distance of the rotation, in bits
-	 * @return The rotated value
-	 */
-	public static int rotateRight(int value, int distance) {
-		return (value >>> (distance & 0x1f)) | (value << ((32 - distance) & 0x1f));
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/number/Digits.java b/alien/src/net/pterodactylus/util/number/Digits.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/number/Digits.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * utils - Digits.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.number;
-
-/**
- * Utility class for decimal number strings.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Digits {
-
-	/**
-	 * Zero-pads the given value until it is at least the specified length in
-	 * digits. This will only work with positive values!
-	 *
-	 * @param value
-	 *            The value to pad
-	 * @param digits
-	 *            The number of digits for the padded value
-	 * @return The zero-padded value
-	 */
-	public static String format(long value, int digits) {
-		String formattedValue = String.valueOf(value);
-		while (formattedValue.length() < digits) {
-			formattedValue = "0" + formattedValue;
-		}
-		return formattedValue;
-	}
-
-	/**
-	 * Returns the given value formatted with the given number of fractional
-	 * digits, showing final zeroes as well.
-	 *
-	 * @param value
-	 *            The value to format
-	 * @param fractionDigits
-	 *            The number of fractional digits
-	 * @param round
-	 *            <code>true</code> to round the formatted value,
-	 *            <code>false</code> to truncate it
-	 * @return The formatted value
-	 */
-	public static String formatFractions(double value, int fractionDigits, boolean round) {
-		double factor = Math.pow(10, fractionDigits);
-		int tempValue = (int) (value * factor + (round ? 0.5 : 0));
-		String formattedValue = String.valueOf(tempValue / factor);
-		if (formattedValue.indexOf('.') == -1) {
-			formattedValue += ".";
-			for (int count = 0; count < fractionDigits; count++) {
-				formattedValue += "0";
-			}
-		} else {
-			while (formattedValue.length() - formattedValue.indexOf('.') <= fractionDigits) {
-				formattedValue += "0";
-			}
-		}
-		return formattedValue;
-	}
-
-	/**
-	 * Parses the given string into a long, throwing an exception if the string
-	 * contains invalid characters.
-	 *
-	 * @param digits
-	 *            The number string to parse
-	 * @return A long value representing the number string
-	 * @throws NumberFormatException
-	 *             if the number string contains invalid characters
-	 */
-	public static long parseLong(String digits) throws NumberFormatException {
-		return Long.parseLong(digits);
-	}
-
-	/**
-	 * Parses the given string into a long, returning the given default value if
-	 * the string contains invalid characters.
-	 *
-	 * @param digits
-	 *            The number string to parse
-	 * @param defaultValue
-	 *            The value to return if the string can not be parsed
-	 * @return The long value represented by the string, or the default value if
-	 *         the string can not be parsed
-	 */
-	public static long parseLong(String digits, long defaultValue) {
-		try {
-			return Long.parseLong(digits);
-		} catch (NumberFormatException nfe1) {
-			return defaultValue;
-		}
-	}
-
-	/**
-	 * Parses the given string into an int, throwing an exception if the string
-	 * contains invalid characters.
-	 *
-	 * @param digits
-	 *            The number string to parse
-	 * @return A int value representing the number string
-	 * @throws NumberFormatException
-	 *             if the number string contains invalid characters
-	 */
-	public static int parseInt(String digits) throws NumberFormatException {
-		return Integer.parseInt(digits);
-	}
-
-	/**
-	 * Parses the given string into an int, returning the given default value if
-	 * the string contains invalid characters.
-	 *
-	 * @param digits
-	 *            The number string to parse
-	 * @param defaultValue
-	 *            The value to return if the string can not be parsed
-	 * @return The int value represented by the string, or the default value if
-	 *         the string can not be parsed
-	 */
-	public static int parseInt(String digits, int defaultValue) {
-		try {
-			return Integer.parseInt(digits);
-		} catch (NumberFormatException nfe1) {
-			return defaultValue;
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/number/Hex.java b/alien/src/net/pterodactylus/util/number/Hex.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/number/Hex.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * utils - Hex.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.number;
-
-/**
- * Contains methods to convert byte arrays to hex strings and vice versa.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Hex {
-
-	/**
-	 * Converts the given string to a hexadecimal string.
-	 *
-	 * @param buffer
-	 *            The string to convert
-	 * @return A hexadecimal string
-	 * @see #toHex(byte[], int, int)
-	 */
-	public static String toHex(String buffer) {
-		return toHex(buffer.getBytes());
-	}
-
-	/**
-	 * Converts the given buffer to a hexadecimal string.
-	 *
-	 * @param buffer
-	 *            The buffer to convert
-	 * @return A hexadecimal string
-	 * @see #toHex(byte[], int, int)
-	 */
-	public static String toHex(byte[] buffer) {
-		return toHex(buffer, 0, buffer.length);
-	}
-
-	/**
-	 * Converts <code>length</code> bytes of the given buffer starting at index
-	 * <code>start</code> to a hexadecimal string.
-	 *
-	 * @param buffer
-	 *            The buffer to convert
-	 * @param start
-	 *            The index to start
-	 * @param length
-	 *            The length to convert
-	 * @return A hexadecimal string
-	 * @throws ArrayIndexOutOfBoundsException
-	 *             if <code>start</code> and/or <code>start + length</code> are
-	 *             outside the valid bounds of <code>buffer</code>
-	 * @see #toHex(byte[], int, int)
-	 */
-	public static String toHex(byte[] buffer, int start, int length) {
-		return toHex(buffer, start, length, false);
-	}
-
-	/**
-	 * Converts the given string to a hexadecimal string, using upper-case
-	 * characters for the digits ‘a’ to ‘f’, if desired.
-	 *
-	 * @param buffer
-	 *            The string to convert
-	 * @param upperCase
-	 *            if the digits 'a' to 'f' should be in upper-case characters
-	 * @return A hexadecimal string
-	 * @see #toHex(byte[], int, int, boolean)
-	 */
-	public static String toHex(String buffer, boolean upperCase) {
-		return toHex(buffer.getBytes(), upperCase);
-	}
-
-	/**
-	 * Converts the given buffer to a hexadecimal string, using upper-case
-	 * characters for the digits ‘a’ to ‘f’, if desired.
-	 *
-	 * @param buffer
-	 *            The buffer to convert
-	 * @param upperCase
-	 *            if the digits 'a' to 'f' should be in upper-case characters
-	 * @return A hexadecimal string
-	 * @see #toHex(byte[], int, int)
-	 */
-	public static String toHex(byte[] buffer, boolean upperCase) {
-		return toHex(buffer, 0, buffer.length, upperCase);
-	}
-
-	/**
-	 * Converts <code>length</code> bytes of the given buffer starting at index
-	 * <code>start</code> to a hexadecimal string, using upper-case characters
-	 * for the digits ‘a’ to ‘f’, if desired.
-	 *
-	 * @param buffer
-	 *            The buffer to convert
-	 * @param start
-	 *            The index to start
-	 * @param length
-	 *            The length to convert
-	 * @param upperCase
-	 *            if the digits 'a' to 'f' should be in upper-case characters
-	 * @return A hexadecimal string
-	 * @throws ArrayIndexOutOfBoundsException
-	 *             if <code>start</code> and/or <code>start + length</code> are
-	 *             outside the valid bounds of <code>buffer</code>
-	 * @see #toHex(byte[], int, int)
-	 */
-	public static String toHex(byte[] buffer, int start, int length, boolean upperCase) {
-		StringBuilder hexBuffer = new StringBuilder(length * 2);
-		for (int index = start; index < length; index++) {
-			String hexByte = Integer.toHexString(buffer[index] & 0xff);
-			if (upperCase) {
-				hexByte = hexByte.toUpperCase();
-			}
-			if (hexByte.length() < 2) {
-				hexBuffer.append('0');
-			}
-			hexBuffer.append(hexByte);
-		}
-		return hexBuffer.toString();
-	}
-
-	/**
-	 * Formats the given byte as a 2-digit hexadecimal value.
-	 *
-	 * @param value
-	 *            The byte to encode
-	 * @return The encoded 2-digit hexadecimal value
-	 */
-	public static String toHex(byte value) {
-		return toHex(value, 2);
-	}
-
-	/**
-	 * Formats the given shoirt as a 4-digit hexadecimal value.
-	 *
-	 * @param value
-	 *            The short to encode
-	 * @return The encoded 4-digit hexadecimal value
-	 */
-	public static String toHex(short value) {
-		return toHex(value, 4);
-	}
-
-	/**
-	 * Formats the given int as a 8-digit hexadecimal value.
-	 *
-	 * @param value
-	 *            The int to encode
-	 * @return The encoded 8-digit hexadecimal value
-	 */
-	public static String toHex(int value) {
-		return toHex(value, 8);
-	}
-
-	/**
-	 * Formats the given int as a 16-digit hexadecimal value.
-	 *
-	 * @param value
-	 *            The long to encode
-	 * @return The encoded 16-digit hexadecimal value
-	 */
-	public static String toHex(long value) {
-		return toHex(value, 16);
-	}
-
-	/**
-	 * Formats the given value with as a hexadecimal number with at least the
-	 * specified number of digits. The value will be padded with zeroes if it is
-	 * shorter than <code>digits</code>.
-	 *
-	 * @param value
-	 *            The value to encode
-	 * @param digits
-	 *            The minimum number of digits
-	 * @return The zero-padded hexadecimal value
-	 */
-	public static String toHex(long value, int digits) {
-		String hexValue = Long.toHexString(value);
-		if (hexValue.length() > digits) {
-			hexValue = hexValue.substring(hexValue.length() - digits, hexValue.length());
-		}
-		while (hexValue.length() < digits) {
-			hexValue = "0" + hexValue;
-		}
-		return hexValue;
-	}
-
-	/**
-	 * Decodes a hexadecimal string into a byte array.
-	 *
-	 * @param hexString
-	 *            The hexadecimal representation to decode
-	 * @return The decoded byte array
-	 * @see Integer#parseInt(java.lang.String, int)
-	 */
-	public static byte[] toByte(String hexString) {
-		if ((hexString.length() & 0x01) == 0x01) {
-			/* odd length, this is not correct. */
-			throw new IllegalArgumentException("hex string must have even length.");
-		}
-		byte[] dataBytes = new byte[hexString.length() / 2];
-		for (int stringIndex = 0; stringIndex < hexString.length(); stringIndex += 2) {
-			String hexNumber = hexString.substring(stringIndex, stringIndex + 2);
-			byte dataByte = (byte) Integer.parseInt(hexNumber, 16);
-			dataBytes[stringIndex / 2] = dataByte;
-		}
-		return dataBytes;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/number/Numbers.java b/alien/src/net/pterodactylus/util/number/Numbers.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/number/Numbers.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * utils - Numbers.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.number;
-
-/**
- * Collection of various helper methods that deal with numbers.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Numbers {
-
-	/**
-	 * Tries to parse the {@link String} representation of the given object (as
-	 * per {@link String#valueOf(Object)}) as an {@link Integer}.
-	 *
-	 * @param object
-	 *            The object to parse
-	 * @return The parsed {@link Integer}, or {@code null} if the object could
-	 *         not be parsed
-	 */
-	public static Integer safeParseInteger(Object object) {
-		return safeParseInteger(object, null);
-	}
-
-	/**
-	 * Tries to parse the {@link String} representation of the given object (as
-	 * per {@link String#valueOf(Object)}) as an {@link Integer}.
-	 *
-	 * @param object
-	 *            The object to parse
-	 * @param defaultValue
-	 *            The value to return if the object is {@code null} or can not
-	 *            be parsed as an {@link Integer}
-	 * @return The parsed Integer, or {@code null} if the object could not be
-	 *         parsed
-	 */
-	public static Integer safeParseInteger(Object object, Integer defaultValue) {
-		if (object == null) {
-			return defaultValue;
-		}
-		try {
-			return Integer.parseInt(String.valueOf(object));
-		} catch (NumberFormatException nfe1) {
-			/* ignore. */
-		}
-		return defaultValue;
-	}
-
-	/**
-	 * Tries to parse the {@link String} representation of the given object (as
-	 * per {@link String#valueOf(Object)}) as a {@link Long}.
-	 *
-	 * @param object
-	 *            The object to parse
-	 * @return The parsed {@link Long}, or {@code null} if the object could not
-	 *         be parsed
-	 */
-	public static Long safeParseLong(Object object) {
-		return safeParseLong(object, null);
-	}
-
-	/**
-	 * Tries to parse the {@link String} representation of the given object (as
-	 * per {@link String#valueOf(Object)}) as a {@link Long}.
-	 *
-	 * @param object
-	 *            The object to parse
-	 * @param defaultValue
-	 *            The value to return if the object is {@code null} or can not
-	 *            be parsed as an {@link Long}
-	 * @return The parsed Long, or {@code null} if the object could not be
-	 *         parsed
-	 */
-	public static Long safeParseLong(Object object, Long defaultValue) {
-		if (object == null) {
-			return defaultValue;
-		}
-		try {
-			return Long.parseLong(String.valueOf(object));
-		} catch (NumberFormatException nfe1) {
-			/* ignore. */
-		}
-		return defaultValue;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/number/SI.java b/alien/src/net/pterodactylus/util/number/SI.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/number/SI.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * utils - SI.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.number;
-
-/**
- * Formats a decimal number with SI units.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class SI {
-
-	/** The units (up to 2^24). */
-	private static final String[] units = { "", "K", "M", "G", "T", "P", "E", "Z", "Y" };
-
-	/**
-	 * Formats the specified number using 1000-based units.
-	 *
-	 * @param number
-	 *            The number to encode
-	 * @return The converted number with a unit postfix
-	 */
-	public static String format(long number) {
-		return format(number, false, false);
-	}
-
-	/**
-	 * Formats the specified number using 1024-based units.
-	 *
-	 * @param number
-	 *            The number to encode
-	 * @return The converted number with a unit postfix
-	 */
-	public static String formatBinary(long number) {
-		return format(number, true, false);
-	}
-
-	/**
-	 * Formats the specified number using the specified units. If
-	 * <code>useBinaryUnits</code> is <code>true</code>, 1024-based units
-	 * (marked by an 'i' after the unit character, e.g. 'Ki' for 1024) will be
-	 * used; if it is <code>false</code>, 1000-based units will be used.
-	 *
-	 * @param number
-	 *            The number to encode
-	 * @param useBinaryUnits
-	 *            Whether to use binary or decimal units
-	 * @return The converted number with a unit postfix
-	 */
-	public static String format(long number, boolean useBinaryUnits) {
-		return format(number, 0, useBinaryUnits, false);
-	}
-
-	/**
-	 * Formats the specified number using the specified units. If
-	 * <code>useBinaryUnits</code> is <code>true</code>, 1024-based units
-	 * (marked by an 'i' after the unit character, e.g. 'Ki' for 1024) will be
-	 * used; if it is <code>false</code>, 1000-based units will be used.
-	 *
-	 * @param number
-	 *            The number to encode
-	 * @param useBinaryUnits
-	 *            Whether to use binary or decimal units
-	 * @param addSpace
-	 *            Whether to add a space between the number and the unit
-	 * @return The converted number with a unit postfix
-	 */
-	public static String format(long number, boolean useBinaryUnits, boolean addSpace) {
-		return format(number, 0, useBinaryUnits, addSpace);
-	}
-
-	/**
-	 * Formats the specified number using the specified units. If
-	 * <code>useBinaryUnits</code> is <code>true</code>, 1024-based units
-	 * (marked by an 'i' after the unit character, e.g. 'Ki' for 1024) will be
-	 * used; if it is <code>false</code>, 1000-based units will be used.
-	 *
-	 * @param number
-	 *            The number to encode
-	 * @param digits
-	 *            The number of digits after the decimal point
-	 * @param useBinaryUnits
-	 *            Whether to use binary or decimal units
-	 * @param addSpace
-	 *            Whether to add a space between the number and the unit
-	 * @return The converted number with a unit postfix
-	 */
-	public static String format(long number, int digits, boolean useBinaryUnits, boolean addSpace) {
-		int unit = 0;
-		double realNumber = number;
-		while ((unit < units.length) && (realNumber >= (useBinaryUnits ? 1024 : 1000))) {
-			realNumber /= (useBinaryUnits ? 1024 : 1000);
-			unit++;
-		}
-		return Digits.formatFractions(realNumber, digits, false) + (addSpace ? " " : "") + units[unit] + ((useBinaryUnits && (unit > 0)) ? "i" : "");
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/service/AbstractService.java b/alien/src/net/pterodactylus/util/service/AbstractService.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/service/AbstractService.java
+++ /dev/null
@@ -1,625 +0,0 @@
-/*
- * utils - AbstractService.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.service;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ThreadFactory;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import net.pterodactylus.util.logging.Logging;
-import net.pterodactylus.util.thread.DumpingThreadFactory;
-import net.pterodactylus.util.validation.Validation;
-
-/**
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public abstract class AbstractService implements Service, Runnable {
-
-	/** Logger. */
-	private static final Logger logger = Logging.getLogger(AbstractService.class.getName());
-
-	/** Listener support. */
-	private final ServiceListenerManager serviceListenerSupport = new ServiceListenerManager(this);
-
-	/** The shutdown hook. */
-	private final ShutdownHook shutdownHook = new ShutdownHook();
-
-	/** Counter for unnamed instances. */
-	private static int counter = 0;
-
-	/** Object used for synchronization. */
-	protected final Object syncObject = new Object();
-
-	/** Whether this method should stop. */
-	private boolean shouldStop = false;
-
-	/** The name of the service. */
-	private final String name;
-
-	/** The current state of the service. */
-	private State state = State.offline;
-
-	/** The current action of the service. */
-	private String action = "";
-
-	/** The thread factory to use. */
-	private ThreadFactory threadFactory;
-
-	/** The service attributes. */
-	private final Map<String, Object> serviceAttributes = new HashMap<String, Object>();
-
-	/** Whether to register the shutdown hook. */
-	private final boolean registerShutdownHook;
-
-	/**
-	 * Constructs a new abstract service with an anonymous name.
-	 */
-	protected AbstractService() {
-		this("AbstractService-" + counter++);
-	}
-
-	/**
-	 * Constructs a new abstract service with the given name.
-	 *
-	 * @param name
-	 *            The name of the service
-	 */
-	protected AbstractService(String name) {
-		this(name, true);
-	}
-
-	/**
-	 * Constructs a new abstract service with the given name.
-	 *
-	 * @param name
-	 *            The name of the service
-	 * @param threadFactory
-	 *            The thread factory used to create the service thread
-	 */
-	protected AbstractService(String name, ThreadFactory threadFactory) {
-		this(name, true, threadFactory);
-	}
-
-	/**
-	 * Constructs a new abstract service with the given name.
-	 *
-	 * @param name
-	 *            The name of the service
-	 * @param registerShutdownHook
-	 *            <code>true</code> to register shutdown hook for this service,
-	 *            <code>false</code> to not register a shutdown hook
-	 */
-	protected AbstractService(String name, boolean registerShutdownHook) {
-		this(name, registerShutdownHook, new DumpingThreadFactory(name + " ", false));
-	}
-
-	/**
-	 * Constructs a new abstract service with the given name.
-	 *
-	 * @param name
-	 *            The name of the service
-	 * @param registerShutdownHook
-	 *            <code>true</code> to register shutdown hook for this service,
-	 *            <code>false</code> to not register a shutdown hook
-	 * @param threadFactory
-	 *            The thread factory used to create the service thread
-	 */
-	protected AbstractService(String name, boolean registerShutdownHook, ThreadFactory threadFactory) {
-		this.registerShutdownHook = registerShutdownHook;
-		Validation.begin().isNotNull("name", name).isNotNull("threadFactory", threadFactory).check();
-		this.name = name;
-		this.threadFactory = threadFactory;
-	}
-
-	//
-	// EVENT MANAGEMENT
-	//
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.service.Service#addServiceListener(net.pterodactylus.util.service.ServiceListener)
-	 */
-	@Override
-	public void addServiceListener(ServiceListener serviceListener) {
-		serviceListenerSupport.addListener(serviceListener);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.service.Service#removeServiceListener(net.pterodactylus.util.service.ServiceListener)
-	 */
-	@Override
-	public void removeServiceListener(ServiceListener serviceListener) {
-		serviceListenerSupport.removeListener(serviceListener);
-	}
-
-	//
-	// ACCESSORS
-	//
-
-	/**
-	 * Sets the thread factory that this service uses to spawn new threads.
-	 *
-	 * @param threadFactory
-	 *            The thread factory for new threads
-	 */
-	public void setThreadFactory(ThreadFactory threadFactory) {
-		Validation.begin().isNotNull("threadFactory", threadFactory).check();
-		this.threadFactory = threadFactory;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.service.Service#getState()
-	 */
-	@Override
-	public State getState() {
-		synchronized (syncObject) {
-			return state;
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	@Deprecated
-	public String getStateReason() {
-		synchronized (syncObject) {
-			return action;
-		}
-	}
-
-	/**
-	 * Returns the current action of the service.
-	 *
-	 * @return The current action of the service
-	 */
-	@Override
-	public String getAction() {
-		synchronized (syncObject) {
-			return action;
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see net.pterodactylus.util.service.Service#getName()
-	 */
-	@Override
-	public String getName() {
-		return name;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see java.lang.Object#toString()
-	 */
-	@Override
-	public String toString() {
-		return name;
-	}
-
-	/**
-	 * @see net.pterodactylus.util.service.Service#getServiceAttribute(java.lang.String)
-	 */
-	@Override
-	public Object getServiceAttribute(String attributeName) {
-		synchronized (syncObject) {
-			return serviceAttributes.get(attributeName);
-		}
-	}
-
-	/**
-	 * @see net.pterodactylus.util.service.Service#hasServiceAttribute(java.lang.String)
-	 */
-	@Override
-	public boolean hasServiceAttribute(String attributeName) {
-		synchronized (syncObject) {
-			return serviceAttributes.containsKey(attributeName);
-		}
-	}
-
-	/**
-	 * @see net.pterodactylus.util.service.Service#setServiceAttribute(java.lang.String,
-	 *      java.lang.Object)
-	 */
-	@Override
-	public void setServiceAttribute(String attributeName, Object attributeValue) {
-		synchronized (syncObject) {
-			serviceAttributes.put(attributeName, attributeValue);
-		}
-	}
-
-	//
-	// PROTECTED ACCESSORS
-	//
-
-	/**
-	 * Sets the new state of this service without changing the action. Calling
-	 * this method is equivalent to calling {@link #setState(State, String)
-	 * setState(newState, null)}.
-	 *
-	 * @param newState
-	 *            The new state of this service
-	 * @see #setState(State, String)
-	 */
-	protected void setState(State newState) {
-		setState(newState, null);
-	}
-
-	/**
-	 * Sets the action for the current state.
-	 *
-	 * @param action
-	 *            The new action of the service, or <code>null</code> to not
-	 *            change the action
-	 * @deprecated Use {@link #setAction(String)} instead
-	 */
-	@Deprecated
-	protected void setStateReason(String action) {
-		setAction(action);
-	}
-
-	/**
-	 * Sets the action of the service.
-	 *
-	 * @param action
-	 *            The new action of the service, or <code>null</code> to not
-	 *            change the action
-	 */
-	protected void setAction(String action) {
-		if (action != null) {
-			synchronized (syncObject) {
-				this.action = action;
-			}
-		}
-	}
-
-	/**
-	 * Sets the new state of this service. If the current state is different
-	 * from the given new state, a
-	 * {@link ServiceListener#serviceStateChanged(Service, State, State)
-	 * Service-State-Changed} event is fired. If the given action is
-	 * <code>null</code>, the current action will not be changed.
-	 *
-	 * @param newState
-	 *            The new state of the service
-	 * @param action
-	 *            The current action of the service, or <code>null</code> if the
-	 *            action should not be changed
-	 */
-	protected void setState(State newState, String action) {
-		State oldState = null;
-		synchronized (syncObject) {
-			oldState = state;
-			state = newState;
-			if (action != null) {
-				this.action = action;
-			}
-		}
-		if (oldState != newState) {
-			serviceListenerSupport.fireServiceStateChanged(oldState, newState);
-		}
-	}
-
-	/**
-	 * Returns whether this service should stop.
-	 *
-	 * @return <code>true</code> if this service should stop, <code>false</code>
-	 *         otherwise
-	 */
-	protected boolean shouldStop() {
-		synchronized (syncObject) {
-			return shouldStop;
-		}
-	}
-
-	//
-	// SERVICE METHODS
-	//
-
-	/**
-	 * Empty initialization. If your service needs to initialize anything before
-	 * being started, simply override this method.
-	 *
-	 * @see #init()
-	 */
-	protected void serviceInit() {
-		/* do nothing. */
-	}
-
-	/**
-	 * Initializes this services. This method returns immediately if the current
-	 * {@link #state} of this service is <strong>not</strong>
-	 * {@link State#offline}. Otherwise {@link #serviceInit()} is called for the
-	 * real initialization of this service.
-	 *
-	 * @see #serviceInit()
-	 * @see net.pterodactylus.util.service.Service#init()
-	 */
-	@Override
-	public final void init() {
-		if (state.getBasicState() != State.offline) {
-			logger.log(Level.WARNING, "will not init " + name + ", state is " + getState());
-			return;
-		}
-		serviceInit();
-	}
-
-	/**
-	 * Empty implementation. If your service needs to do something before the
-	 * service thread is started, simply override this method.
-	 *
-	 * @see #start()
-	 */
-	protected void serviceStart() {
-		/* do nothing. */
-	}
-
-	/**
-	 * Attempts to start this service. This method returns immediately if the
-	 * current {@link #state} is <strong>not</strong> {@link State#offline}.
-	 * Otherwise {@link #serviceStart()} is called for further post-init,
-	 * pre-start initialization.
-	 *
-	 * @see #serviceStart()
-	 * @see net.pterodactylus.util.service.Service#start()
-	 */
-	@Override
-	public final void start() {
-		if (getState() != State.offline) {
-			logger.log(Level.WARNING, "will not start " + name + ", state is " + getState());
-			return;
-		}
-		if (registerShutdownHook) {
-			Runtime.getRuntime().addShutdownHook(shutdownHook);
-		}
-		serviceStart();
-		synchronized (syncObject) {
-			shouldStop = false;
-		}
-		setState(State.starting, "");
-		Thread serviceThread = threadFactory.newThread(this);
-		serviceThread.setName(name);
-		serviceThread.start();
-	}
-
-	/**
-	 * Empty implementation. If your service needs to do anything this method
-	 * needs to be overridden. Otherwise it will {@link #sleep()} until
-	 * {@link #stop()} is called.
-	 *
-	 * @see #run()
-	 */
-	protected void serviceRun() {
-		while (!shouldStop()) {
-			sleep(0);
-		}
-	}
-
-	/**
-	 * Runner for the main {@link #serviceRun()} method. This method sets the
-	 * {@link #state} to {@link State#online} and fires a
-	 * {@link ServiceListener#serviceStarted(Service) Service-Started} event
-	 * before {@link #serviceRun()} is called. When the {@link #serviceRun()}
-	 * method terminates the {@link #state} is set to {@link State#offline}
-	 * without changing the action. If the {@link #serviceRun()} method threw an
-	 * exception {@link #state} is set to {@link State#offline} with the
-	 * {@link Exception#getMessage() message} of the exception as action. In
-	 * both cases a {@link ServiceListener#serviceStopped(Service, Throwable)
-	 * Service-Stopped} event is fired.
-	 */
-	@Override
-	public final void run() {
-		Throwable cause = null;
-		try {
-			setState(State.online);
-			serviceListenerSupport.fireServiceStarted();
-			serviceRun();
-		} catch (Throwable t) {
-			cause = t;
-		} finally {
-			setState(State.offline, (cause != null) ? cause.getMessage() : null);
-			serviceListenerSupport.fireServiceStopped(cause);
-		}
-	}
-
-	/**
-	 * Empty implementation. If you need to perform actions on stopping, simply
-	 * override this method.
-	 *
-	 * @see #stop()
-	 */
-	protected void serviceStop() {
-		/* do nothing. */
-	}
-
-	/**
-	 * Stops this service. This method returns immediately if the basic state of
-	 * {@link #state} is not {@link State#online} or {@link State#starting}.
-	 * Otherwise {@link #shouldStop} is set to <code>true</code>,
-	 * {@link #serviceStop} is called, and sleeping threads (if any) are
-	 * notified.
-	 *
-	 * @see net.pterodactylus.util.service.Service#stop()
-	 */
-	@Override
-	public final void stop() {
-		synchronized (syncObject) {
-			shouldStop = true;
-			syncObject.notify();
-		}
-		if (registerShutdownHook) {
-			Runtime.getRuntime().removeShutdownHook(shutdownHook);
-		}
-		serviceStop();
-	}
-
-	/**
-	 * Empty implementation. If you need to free resources used in a service,
-	 * simply override this method.
-	 *
-	 * @see #destroy()
-	 */
-	protected void serviceDestroy() {
-		/* do nothing. */
-	}
-
-	/**
-	 * Destroys this service, freeing all used resources. This method will
-	 * return immediately if {@link #state} is not {@link State#offline}.
-	 * Otherwise {@link #serviceDestroy} is called and internal resources are
-	 * freed.
-	 *
-	 * @see net.pterodactylus.util.service.Service#destroy()
-	 */
-	@Override
-	public final void destroy() {
-		serviceDestroy();
-	}
-
-	//
-	// PROTECTED ACTIONS
-	//
-
-	/**
-	 * Sleeps until {@link #syncObject} gets {@link #notify()}'ed.
-	 */
-	protected void sleep() {
-		sleep(0);
-	}
-
-	/**
-	 * Sleeps until {@link #syncObject} gets {@link #notify()}'ed or the
-	 * specified timeout (in milliseconds) has elapsed. This method will return
-	 * immediately if the service has already been told to {@link #stop()}.
-	 *
-	 * @param timeout
-	 *            The number of milliseconds to wait
-	 */
-	protected void sleep(long timeout) {
-		synchronized (syncObject) {
-			if (!shouldStop) {
-				try {
-					syncObject.wait(timeout);
-				} catch (InterruptedException ie1) {
-					/* FIXME - ignore. */
-				}
-			}
-		}
-	}
-
-	/**
-	 * {@link Object #notify() Notifies} the {@link #syncObject} to interrupt a
-	 * {@link #sleep()}.
-	 */
-	protected void notifySyncObject() {
-		synchronized (syncObject) {
-			syncObject.notify();
-		}
-	}
-
-	/**
-	 * Shutdown hook that is run when the VM is told to exit.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	private class ShutdownHook extends Thread implements ServiceListener {
-
-		/** Object used for synchronization. */
-		@SuppressWarnings("hiding")
-		private final Object syncObject = new Object();
-
-		/** Whether the service has stopped. */
-		private boolean stopped = true;
-
-		/**
-		 * Creates a new shutdown hook.
-		 */
-		public ShutdownHook() {
-			super("Shutdown Hook for " + AbstractService.this);
-			AbstractService.this.addServiceListener(this);
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		@SuppressWarnings("synthetic-access")
-		public void run() {
-			logger.log(Level.INFO, "shutdown hook for " + AbstractService.this + " started.");
-			synchronized (syncObject) {
-				if (!stopped) {
-					AbstractService.this.stop();
-				}
-				while (!stopped) {
-					logger.log(Level.FINER, "waiting for " + AbstractService.this + " to stop...");
-					try {
-						syncObject.wait();
-					} catch (InterruptedException ie1) {
-						/* ignore, continue waiting. */
-					}
-				}
-			}
-			logger.log(Level.INFO, "shutdown hook for " + AbstractService.this + " finished.");
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		@SuppressWarnings("synthetic-access")
-		public void serviceStarted(Service service) {
-			logger.log(Level.FINER, AbstractService.this + " started.");
-			synchronized (syncObject) {
-				stopped = false;
-			}
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public void serviceStateChanged(Service service, net.pterodactylus.util.service.State oldState, net.pterodactylus.util.service.State newState) {
-			/* ignore. */
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		@SuppressWarnings("synthetic-access")
-		public void serviceStopped(Service service, Throwable cause) {
-			logger.log(Level.FINE, AbstractService.this + " stopped.", cause);
-			synchronized (syncObject) {
-				stopped = true;
-				syncObject.notify();
-			}
-		}
-
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/service/Service.java b/alien/src/net/pterodactylus/util/service/Service.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/service/Service.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * utils - Service.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.service;
-
-/**
- * Interface for services. Services are the workhorses of every application. On
- * application startup, services are started and begin interacting with each
- * other, thus forming the application. Services can also contain “service
- * attributes” which are basically {@link Object}s mapped to {@link String}s.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface Service extends ServiceMBean {
-
-	/**
-	 * Returns the name of this service.
-	 *
-	 * @return The name of this service
-	 */
-	public String getName();
-
-	/**
-	 * Returns the current state of this service.
-	 *
-	 * @return The current state of this service
-	 */
-	@Override
-	public State getState();
-
-	/**
-	 * Returns the reason for the current state. The reason will never be
-	 * <code>null</code>.
-	 *
-	 * @deprecated Use {@link #getAction()} instead
-	 * @return The reason for the current state
-	 */
-	@Deprecated
-	public String getStateReason();
-
-	/**
-	 * Returns the current action of the service.
-	 *
-	 * @see net.pterodactylus.util.service.ServiceMBean#getAction()
-	 * @return The current action of the service
-	 */
-	@Override
-	public String getAction();
-
-	/**
-	 * Adds the given service listener to the list of service listeners that
-	 * will be notified on service events.
-	 *
-	 * @param serviceListener
-	 *            The service listener to add
-	 */
-	public void addServiceListener(ServiceListener serviceListener);
-
-	/**
-	 * Removes the given service listeners from the list of service listeners.
-	 *
-	 * @param serviceListener
-	 *            The service listener to remove
-	 */
-	public void removeServiceListener(ServiceListener serviceListener);
-
-	/**
-	 * Initializes the service.
-	 */
-	public void init();
-
-	/**
-	 * Starts the service.
-	 */
-	@Override
-	public void start();
-
-	/**
-	 * Stops the service.
-	 */
-	@Override
-	public void stop();
-
-	/**
-	 * Destroys the service and frees all used resources.
-	 */
-	public void destroy();
-
-	/**
-	 * Sets the service attribute with the given name to the given value.
-	 *
-	 * @param attributeName
-	 *            The name of the attribute
-	 * @param attributeValue
-	 *            The value of the attribute
-	 */
-	public void setServiceAttribute(String attributeName, Object attributeValue);
-
-	/**
-	 * Returns the value of the service attribute with the given name.
-	 *
-	 * @param attributeName
-	 *            The name of the attribute
-	 * @return The value of the attribute
-	 */
-	public Object getServiceAttribute(String attributeName);
-
-	/**
-	 * Returns whether this service contains a service attribute with the given
-	 * name.
-	 *
-	 * @param attributeName
-	 *            The name of the attribute
-	 * @return <code>true</code> if this service has a service attribute with
-	 *         the given name, <code>false</code> otherwise
-	 */
-	public boolean hasServiceAttribute(String attributeName);
-
-}
diff --git a/alien/src/net/pterodactylus/util/service/ServiceListener.java b/alien/src/net/pterodactylus/util/service/ServiceListener.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/service/ServiceListener.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * utils - ServiceListener.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.service;
-
-import java.util.EventListener;
-
-/**
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface ServiceListener extends EventListener {
-
-	/**
-	 * Notifies listeners that a {@link Service} has been started.
-	 *
-	 * @param service
-	 *            The service that started
-	 */
-	public void serviceStarted(Service service);
-
-	/**
-	 * Notifies listeners that a {@link Service} has changed its {@link State}.
-	 *
-	 * @param service
-	 *            The service that changed its state
-	 * @param oldState
-	 *            The old state of the service
-	 * @param newState
-	 *            The new state of the service
-	 */
-	public void serviceStateChanged(Service service, State oldState, State newState);
-
-	/**
-	 * Notifies listeners that a {@link Service} has been stopped.
-	 *
-	 * @param service
-	 *            The service that stopped
-	 * @param cause
-	 *            The cause for stopping, will be <code>null</code> if service
-	 *            stopped normally
-	 */
-	public void serviceStopped(Service service, Throwable cause);
-
-}
diff --git a/alien/src/net/pterodactylus/util/service/ServiceListenerManager.java b/alien/src/net/pterodactylus/util/service/ServiceListenerManager.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/service/ServiceListenerManager.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * utils - ServiceListenerManager.java - Copyright © 2008-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.service;
-
-import net.pterodactylus.util.event.AbstractListenerManager;
-
-/**
- * Listener manager for {@link ServiceListener}s.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ServiceListenerManager extends AbstractListenerManager<Service, ServiceListener> {
-
-	/**
-	 * Creates a new listener manager for {@link ServiceListener}s.
-	 *
-	 * @param service
-	 *            The source service
-	 */
-	public ServiceListenerManager(Service service) {
-		super(service);
-	}
-
-	/**
-	 * Notifies listeners that a {@link Service} has been started.
-	 */
-	public void fireServiceStarted() {
-		for (ServiceListener serviceListener : getListeners()) {
-			serviceListener.serviceStarted(getSource());
-		}
-	}
-
-	/**
-	 * Notifies listeners that a {@link Service} has changed its {@link State}.
-	 *
-	 * @param oldState
-	 *            The old state of the service
-	 * @param newState
-	 *            The new state of the service
-	 */
-	public void fireServiceStateChanged(State oldState, State newState) {
-		for (ServiceListener serviceListener : getListeners()) {
-			serviceListener.serviceStateChanged(getSource(), oldState, newState);
-		}
-	}
-
-	/**
-	 * Notifies listeners that a {@link Service} has been stopped.
-	 *
-	 * @param cause
-	 *            The cause for stopping, will be <code>null</code> if service
-	 *            stopped normally
-	 */
-	public void fireServiceStopped(Throwable cause) {
-		for (ServiceListener serviceListener : getListeners()) {
-			serviceListener.serviceStopped(getSource(), cause);
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/service/ServiceMBean.java b/alien/src/net/pterodactylus/util/service/ServiceMBean.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/service/ServiceMBean.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * utils - ServiceMBean.java - Copyright © 2008-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.service;
-
-/**
- * MBean interface for all {@link Service} implementations.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface ServiceMBean {
-
-	/**
-	 * Starts the service.
-	 */
-	public void start();
-
-	/**
-	 * Stops the service.
-	 */
-	public void stop();
-
-	/**
-	 * Returns the state of the service.
-	 *
-	 * @return The state of the service
-	 */
-	public State getState();
-
-	/**
-	 * Returns the current action of the service.
-	 *
-	 * @return The current action of the service
-	 */
-	public String getAction();
-
-}
diff --git a/alien/src/net/pterodactylus/util/service/State.java b/alien/src/net/pterodactylus/util/service/State.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/service/State.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * utils - State.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.service;
-
-/**
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class State implements Comparable<State> {
-
-	/** Basic State for services that are not running. */
-	public static final State offline = new State("offline", 0);
-
-	/** Basic State for services that are starting. */
-	public static final State starting = new State("starting", 1);
-
-	/** Basic State for services that are running. */
-	public static final State online = new State("online", 2);
-
-	/** Basic state for services that are stopping. */
-	public static final State stopping = new State("stopping", 3);
-
-	/** Basic static for services in an unknown state. */
-	public static final State unknown = new State("unknown", 4);
-
-	/** The basic state of this state. */
-	private final State basicState;
-
-	/** The name of the state. */
-	private final String name;
-
-	/** The ordinal number of the state. */
-	private final int ordinal;
-
-	/**
-	 * Constructs a new basic state with the given name and ordinal.
-	 *
-	 * @param name
-	 *            The name of the new basic state
-	 * @param ordinal
-	 *            The ordinal of the new basic state
-	 */
-	private State(String name, int ordinal) {
-		this.basicState = this;
-		this.name = name;
-		this.ordinal = ordinal;
-	}
-
-	/**
-	 * Constructs a new state that is derived from the given basic state and has
-	 * the given name.
-	 *
-	 * @param basicState
-	 *            The basic state of the new state
-	 * @param name
-	 *            The name of the new state
-	 */
-	public State(State basicState, String name) {
-		if (basicState == null) {
-			throw new IllegalArgumentException("basic state must not be null");
-		}
-		this.basicState = basicState;
-		this.name = name;
-		this.ordinal = basicState.ordinal;
-	}
-
-	/**
-	 * Returns the basic state of this state. If this state is one of the
-	 * predefined basic state, the state itself is returned so that this method
-	 * <em>never</em> returns <code>null</code>.
-	 *
-	 * @return The basic state of this state
-	 */
-	public State getBasicState() {
-		return basicState;
-	}
-
-	/**
-	 * Returns the name of this state.
-	 *
-	 * @return The name of this state
-	 */
-	public String getName() {
-		return name;
-	}
-
-	/**
-	 * Returns the ordinal number of this state. If this state is a derived
-	 * state the ordinal of the basic state is returned.
-	 *
-	 * @return The ordinal of this state
-	 */
-	public int getOrdinal() {
-		return ordinal;
-	}
-
-	//
-	// INTERFACE Comparable<State>
-	//
-
-	/**
-	 * Compares this state to the given state. A State is considered as smaller
-	 * than another state if the basic state’s ordinal of the first state is
-	 * smaller than the second state’s basic state’s ordinal.
-	 *
-	 * @param state
-	 *            The state that should be compared with this state
-	 * @return A negative number if this state’s ordinal is smaller than the
-	 *         ordinal of the given state’s basic state
-	 */
-	@Override
-	public int compareTo(State state) {
-		return this.basicState.ordinal - state.basicState.ordinal;
-	}
-
-	/**
-	 * Returns a textual representation of this state, consisting of the name of
-	 * this state and, if different, the name of its basic state.
-	 *
-	 * @return A textual representation of this state
-	 */
-	@Override
-	public String toString() {
-		if (this != basicState) {
-			return name + " (" + basicState + ")";
-		}
-		return name;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/service/package-info.java b/alien/src/net/pterodactylus/util/service/package-info.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/service/package-info.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Basic interface and implementation for services that can be started, stopped
- * and run asynchronously in the background. <h2>Usage of the Service Interface</h2>
- * <p>
- * Using a {@link net.pterodactylus.util.service.Service} is pretty straight-forward:
- *
- * <pre>
- *  Service someService = new SomeService();
- *  someService.init();
- *  someService.setParameter1(...);
- *  someService.setParameter2(...);
- *  // some more preparations
- *  // and finally...
- *  someService.start();
- * </pre>
- *
- * <h2>Implementing Own Services</h2>
- * <p>
- * If you want to implement your own service it is recommended that you override
- * the {@link net.pterodactylus.util.service.AbstractService} base class as it takes care
- * of a couple of things for you, like creating the thread that runs your
- * service, managing the {@link net.pterodactylus.util.service.Service#stop()} method,
- * providing synchronized access to state variables, and other things.
- * </p>
- * <p>
- * The {@link net.pterodactylus.util.service.AbstractService} base class adds a
- * <code>service</code> method for each of the
- * {@link net.pterodactylus.util.service.Service#init()},
- * {@link net.pterodactylus.util.service.Service#start()},
- * {@link net.pterodactylus.util.service.Service#stop()}, and
- * {@link net.pterodactylus.util.service.Service#destroy()} methods that let you take care
- * of things in your own service without having to interfere with the stuff at
- * {@link net.pterodactylus.util.service.AbstractService} does for you. The
- * {@link net.pterodactylus.util.service.AbstractService#serviceRun()} method is the place
- * to implement your magic then. It should be designed as an infinite loop like
- * this:
- *
- * <pre>
- * protected void serviceRun() {
- * 	while (!shouldStop()) {
- * 		doStuff();
- * 		doLengthyStuff();
- * 		if (shouldStop()) {
- * 			continue;
- * 		}
- * 		doMoreLengthyStuff();
- * 	}
- * }
- * </pre>
- *
- * Checking the {@link net.pterodactylus.util.service.AbstractService#shouldStop()} every
- * once in a while ensures that your service stops within a short time after
- * {@link net.pterodactylus.util.service.Service#stop()} has been called.
- *
- */
-package net.pterodactylus.util.service;
\ No newline at end of file
diff --git a/alien/src/net/pterodactylus/util/swing/ComboBoxModelList.java b/alien/src/net/pterodactylus/util/swing/ComboBoxModelList.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/swing/ComboBoxModelList.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * utils - ComboBoxModelList.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.swing;
-
-import java.util.List;
-
-import javax.swing.ComboBoxModel;
-import javax.swing.JComboBox;
-
-/**
- * Implementation of a {@link List} that doubles as a {@link ComboBoxModel},
- * e.g. for use with a {@link JComboBox}.
- *
- * @param <E>
- *            The type of the elements
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ComboBoxModelList<E> extends ListModelList<E> implements ComboBoxModel {
-
-	/** The selected item. */
-	private Object selectedItem;
-
-	/**
-	 * Creates a new combo box model list that wraps the given list.
-	 *
-	 * @param originalList
-	 *            The original list to wrap
-	 */
-	public ComboBoxModelList(List<E> originalList) {
-		super(originalList);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Object getSelectedItem() {
-		return selectedItem;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void setSelectedItem(Object anItem) {
-		selectedItem = anItem;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/swing/ListModelList.java b/alien/src/net/pterodactylus/util/swing/ListModelList.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/swing/ListModelList.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * utils - ListListModel.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.swing;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import javax.swing.JComboBox;
-import javax.swing.JList;
-import javax.swing.ListModel;
-import javax.swing.event.ListDataEvent;
-import javax.swing.event.ListDataListener;
-
-/**
- * Wrapper around a {@link List} that doubles as a {@link ListModel}, e.g. for a
- * {@link JComboBox} or a {@link JList}.
- *
- * @param <E>
- *            The type of the elements
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ListModelList<E> implements ListModel, List<E> {
-
-	/** The wrapped list. */
-	private final List<E> wrappedList;
-
-	/** The list data listeners. */
-	private final List<ListDataListener> listDataListeners = new CopyOnWriteArrayList<ListDataListener>();
-
-	/**
-	 * Creates a new list model list by wrapping the given list.
-	 *
-	 * @param originalList
-	 *            The list to wrap
-	 */
-	public ListModelList(List<E> originalList) {
-		this.wrappedList = originalList;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void addListDataListener(ListDataListener listDataListener) {
-		listDataListeners.add(listDataListener);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public E getElementAt(int index) {
-		return wrappedList.get(index);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int getSize() {
-		return wrappedList.size();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void removeListDataListener(ListDataListener listDataListener) {
-		listDataListeners.remove(listDataListener);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean add(E element) {
-		boolean added = wrappedList.add(element);
-		int position = wrappedList.size() - 1;
-		ListDataEvent listDataEvent = new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, position, position);
-		for (ListDataListener listDataListener : listDataListeners) {
-			listDataListener.intervalAdded(listDataEvent);
-		}
-		return added;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void add(int index, E element) {
-		wrappedList.add(element);
-		ListDataEvent listDataEvent = new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index);
-		for (ListDataListener listDataListener : listDataListeners) {
-			listDataListener.intervalAdded(listDataEvent);
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean addAll(Collection<? extends E> collection) {
-		int firstPosition = wrappedList.size();
-		boolean changed = wrappedList.addAll(collection);
-		if (changed) {
-			ListDataEvent listDataEvent = new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, firstPosition, wrappedList.size() - 1);
-			for (ListDataListener listDataListener : listDataListeners) {
-				listDataListener.intervalAdded(listDataEvent);
-			}
-		}
-		return changed;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean addAll(int index, Collection<? extends E> collection) {
-		boolean changed = wrappedList.addAll(collection);
-		if (changed) {
-			ListDataEvent listDataEvent = new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index + collection.size() - 1);
-			for (ListDataListener listDataListener : listDataListeners) {
-				listDataListener.intervalAdded(listDataEvent);
-			}
-		}
-		return changed;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void clear() {
-		if (!wrappedList.isEmpty()) {
-			int size = wrappedList.size();
-			wrappedList.clear();
-			ListDataEvent listDataEvent = new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, 0, size - 1);
-			for (ListDataListener listDataListener : listDataListeners) {
-				listDataListener.intervalRemoved(listDataEvent);
-			}
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean contains(Object object) {
-		return wrappedList.contains(object);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean containsAll(Collection<?> collection) {
-		return wrappedList.containsAll(collection);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public E get(int index) {
-		return wrappedList.get(index);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int indexOf(Object object) {
-		return wrappedList.indexOf(object);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean isEmpty() {
-		return wrappedList.isEmpty();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Iterator<E> iterator() {
-		return wrappedList.iterator();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int lastIndexOf(Object object) {
-		return wrappedList.lastIndexOf(object);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public ListIterator<E> listIterator() {
-		return wrappedList.listIterator();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public ListIterator<E> listIterator(int index) {
-		return wrappedList.listIterator(index);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean remove(Object object) {
-		int index = wrappedList.indexOf(object);
-		if (index != -1) {
-			wrappedList.remove(object);
-			ListDataEvent listDataEvent = new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index, index);
-			for (ListDataListener listDataListener : listDataListeners) {
-				listDataListener.intervalRemoved(listDataEvent);
-			}
-			return true;
-		}
-		return false;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public E remove(int index) {
-		E removedElement = wrappedList.remove(index);
-		ListDataEvent listDataEvent = new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index, index);
-		for (ListDataListener listDataListener : listDataListeners) {
-			listDataListener.intervalRemoved(listDataEvent);
-		}
-		return removedElement;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean removeAll(Collection<?> collection) {
-		int lowestPosition = Integer.MAX_VALUE;
-		int highestPosition = Integer.MIN_VALUE;
-		for (Object element : collection) {
-			int position = wrappedList.indexOf(element);
-			if (position == -1) {
-				continue;
-			}
-			if (position < lowestPosition) {
-				lowestPosition = position;
-			}
-			if (position > highestPosition) {
-				highestPosition = position;
-			}
-		}
-		if (lowestPosition < Integer.MAX_VALUE) {
-			for (Object element : collection) {
-				wrappedList.remove(element);
-			}
-			ListDataEvent listDataEvent = new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, lowestPosition, highestPosition);
-			for (ListDataListener listDataListener : listDataListeners) {
-				listDataListener.contentsChanged(listDataEvent);
-			}
-		}
-		return (lowestPosition < Integer.MAX_VALUE);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean retainAll(Collection<?> collection) {
-		int size = wrappedList.size();
-		boolean changed = wrappedList.retainAll(collection);
-		ListDataEvent listDataEvent = new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, 0, size - 1);
-		for (ListDataListener listDataListener : listDataListeners) {
-			listDataListener.contentsChanged(listDataEvent);
-		}
-		return changed;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public E set(int index, E element) {
-		E oldElement = wrappedList.set(index, element);
-		ListDataEvent listDataEvent = new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index);
-		for (ListDataListener listDataListener : listDataListeners) {
-			listDataListener.contentsChanged(listDataEvent);
-		}
-		return oldElement;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int size() {
-		return wrappedList.size();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public List<E> subList(int fromIndex, int toIndex) {
-		return wrappedList.subList(fromIndex, toIndex);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Object[] toArray() {
-		return wrappedList.toArray();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public <T> T[] toArray(T[] a) {
-		return wrappedList.toArray(a);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/swing/SortableTreeNode.java b/alien/src/net/pterodactylus/util/swing/SortableTreeNode.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/swing/SortableTreeNode.java
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * utils - SortableTreeNode.java - Copyright © 2008-2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.swing;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Enumeration;
-import java.util.List;
-
-import javax.swing.tree.MutableTreeNode;
-import javax.swing.tree.TreeNode;
-
-/**
- * {@link MutableTreeNode} subclass that allows to sort its children.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class SortableTreeNode implements MutableTreeNode {
-
-	/** The parent node. */
-	private MutableTreeNode parentNode;
-
-	/** The user-defined object. */
-	private Object userObject;
-
-	/** Whether this node allows children. */
-	private boolean allowsChildren;
-
-	/** The children of this node. */
-	private List<MutableTreeNode> children = new ArrayList<MutableTreeNode>();
-
-	/**
-	 * Creates a new sortable tree node.
-	 *
-	 * @param allowsChildren
-	 *            <code>true</code> if this node allows children,
-	 *            <code>false</code> otherwise
-	 */
-	public SortableTreeNode(boolean allowsChildren) {
-		this(null, allowsChildren);
-	}
-
-	/**
-	 * Creates a new sortable tree node that contains the given user-defined
-	 * object.
-	 *
-	 * @param userObject
-	 *            The user-defined object
-	 */
-	public SortableTreeNode(Object userObject) {
-		this(userObject, true);
-	}
-
-	/**
-	 * Creates a new sortable tree node that contains the given user-defined
-	 * object.
-	 *
-	 * @param userObject
-	 *            The user-defined object
-	 * @param allowsChildren
-	 *            <code>true</code> if this node allows children,
-	 *            <code>false</code> otherwise
-	 */
-	public SortableTreeNode(Object userObject, boolean allowsChildren) {
-		this.allowsChildren = allowsChildren;
-		this.userObject = userObject;
-	}
-
-	//
-	// ACCESSORS
-	//
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean getAllowsChildren() {
-		return allowsChildren;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public TreeNode getChildAt(int childIndex) {
-		return children.get(childIndex);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int getChildCount() {
-		return children.size();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int getIndex(TreeNode node) {
-		return children.indexOf(node);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public TreeNode getParent() {
-		return parentNode;
-	}
-
-	/**
-	 * Returns the user-defined object.
-	 *
-	 * @return The user-defined object
-	 */
-	public Object getUserObject() {
-		return userObject;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean isLeaf() {
-		return children.isEmpty();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Enumeration<?> children() {
-		return Collections.enumeration(children);
-	}
-
-	//
-	// ACTIONS
-	//
-
-	/**
-	 * Adds the given node to this node as a child.
-	 *
-	 * @param child
-	 *            The child node to add
-	 */
-	public void add(MutableTreeNode child) {
-		children.add(child);
-		child.setParent(this);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void insert(MutableTreeNode child, int index) {
-		children.add(index, child);
-		child.setParent(this);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void remove(int index) {
-		children.remove(index).setParent(null);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void remove(MutableTreeNode node) {
-		children.remove(node);
-		node.setParent(null);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void removeFromParent() {
-		if (parentNode != null) {
-			parentNode.remove(this);
-			parentNode = null;
-		}
-	}
-
-	/**
-	 * Removes all children of this node.
-	 */
-	public void removeAll() {
-		for (MutableTreeNode childNode : children) {
-			childNode.setParent(null);
-		}
-		children.clear();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void setParent(MutableTreeNode newParent) {
-		parentNode = newParent;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void setUserObject(Object userObject) {
-		this.userObject = userObject;
-	}
-
-	/**
-	 * Sorts the children of this node.
-	 */
-	public void sort() {
-		Collections.sort(children, new Comparator<MutableTreeNode>() {
-
-			/**
-			 * {@inheritDoc}
-			 */
-			@Override
-			@SuppressWarnings( { "synthetic-access", "unchecked" })
-			public int compare(MutableTreeNode firstNode, MutableTreeNode secondNode) {
-				if (!(firstNode instanceof SortableTreeNode) || !(secondNode instanceof SortableTreeNode)) {
-					return 0;
-				}
-				SortableTreeNode firstSortableNode = (SortableTreeNode) firstNode;
-				SortableTreeNode secondSortableNode = (SortableTreeNode) secondNode;
-				if ((firstSortableNode.userObject == null) && (secondSortableNode.userObject == null)) {
-					return 0;
-				}
-				if ((firstSortableNode.userObject == null) && (secondSortableNode.userObject != null)) {
-					return -1;
-				}
-				if ((firstSortableNode.userObject != null) && (secondSortableNode.userObject == null)) {
-					return 1;
-				}
-				if (!(firstSortableNode.userObject instanceof Comparable) || !(secondSortableNode.userObject instanceof Comparable)) {
-					return 0;
-				}
-				return ((Comparable<Object>) firstSortableNode.userObject).compareTo(secondSortableNode.userObject);
-			}
-		});
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		return (userObject != null) ? userObject.toString() : null;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/swing/StatusBar.java b/alien/src/net/pterodactylus/util/swing/StatusBar.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/swing/StatusBar.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * utils - StatusBar.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.swing;
-
-import java.awt.BorderLayout;
-import java.awt.Component;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.border.CompoundBorder;
-import javax.swing.border.EmptyBorder;
-import javax.swing.border.EtchedBorder;
-
-/**
- * Status bar component that can be added to the {@link BorderLayout#SOUTH} area
- * of a {@link JFrame}’s {@link JFrame#getContentPane() content pane}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-/* TODO - make it possible to add further components. */
-public class StatusBar extends JPanel {
-
-	/** The layout. */
-	private GridBagLayout layout = new GridBagLayout();
-
-	/** The label. */
-	private JLabel statusLabel = new JLabel(" ");
-
-	/** Addition components. */
-	private List<Component> sideComponents = new ArrayList<Component>();
-
-	/**
-	 * Creates a new status bar.
-	 */
-	public StatusBar() {
-		setLayout(layout);
-		statusLabel.setBorder(new CompoundBorder(new EtchedBorder(EtchedBorder.LOWERED), new EmptyBorder(0, 3, 0, 0)));
-		add(statusLabel, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
-	}
-
-	/**
-	 * Clears the status bar.
-	 */
-	public void clear() {
-		statusLabel.setText(" ");
-	}
-
-	/**
-	 * Sets the text of the label.
-	 *
-	 * @param text
-	 *            The text of the label
-	 */
-	public void setText(String text) {
-		statusLabel.setText(text);
-	}
-
-	/**
-	 * Adds a side component to the right side of the status bar, pushing all
-	 * previously added side components to the left.
-	 *
-	 * @param component
-	 *            The component to add
-	 */
-	public void addSideComponent(Component component) {
-		sideComponents.add(component);
-		int newIndex = sideComponents.size();
-		add(component, new GridBagConstraints(newIndex, 0, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 2, 0, 0), 0, 0));
-		validate();
-	}
-
-	/**
-	 * Returns the number of side components.
-	 *
-	 * @return The number of side components
-	 */
-	public int getSideComponentCount() {
-		return sideComponents.size();
-	}
-
-	/**
-	 * Returns all side components in order.
-	 *
-	 * @return All side components
-	 */
-	public List<Component> getSideComponents() {
-		return sideComponents;
-	}
-
-	/**
-	 * Removes the side component with the given index.
-	 *
-	 * @param sideComponentIndex
-	 *            The index of the side component to remove
-	 */
-	public void removeSideComponent(int sideComponentIndex) {
-		Component sideComponent = sideComponents.remove(sideComponentIndex);
-		remove(sideComponent);
-		validate();
-	}
-
-	/**
-	 * Removes the given side component.
-	 *
-	 * @param sideComponent
-	 *            The side component to remove
-	 */
-	public void removeSideComponent(Component sideComponent) {
-		sideComponents.remove(sideComponent);
-		remove(sideComponent);
-		validate();
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/swing/SwingUtils.java b/alien/src/net/pterodactylus/util/swing/SwingUtils.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/swing/SwingUtils.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * utils - SwingUtils.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.swing;
-
-import java.awt.Dimension;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Toolkit;
-import java.awt.Window;
-
-/**
- * Collection of Swing-related helper methods.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class SwingUtils {
-
-	/**
-	 * Centers the given window on the primary screen.
-	 *
-	 * @param window
-	 *            The window to center
-	 */
-	public static void center(Window window) {
-		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
-		Dimension windowSize = window.getSize();
-		window.setLocation((screenSize.width - windowSize.width) / 2, (screenSize.height - windowSize.height) / 2);
-	}
-
-	/**
-	 * Centers the given window over its owner window.
-	 *
-	 * @param window
-	 *            The window to center
-	 * @param ownerWindow
-	 *            The window to center the other window over
-	 */
-	public static void center(Window window, Window ownerWindow) {
-		Point ownerWindowLocation = ownerWindow.getLocation();
-		Dimension ownerWindowDimension = ownerWindow.getSize();
-		Dimension windowSize = window.getSize();
-		window.setLocation(ownerWindowLocation.x + (ownerWindowDimension.width - windowSize.width) / 2, ownerWindowLocation.y + (ownerWindowDimension.height - windowSize.height) / 2);
-	}
-
-	/**
-	 * {@link Window#pack() Packs} the given window and positions it so that its
-	 * center stays the same.
-	 *
-	 * @param window
-	 *            The window to pack and recenter
-	 */
-	public static void repackCentered(Window window) {
-		Point center = getCenter(window.getBounds());
-		window.pack();
-		window.setLocation((center.x - window.getWidth() / 2), (center.y - window.getHeight() / 2));
-		window.repaint();
-	}
-
-	/**
-	 * Returns the center of the given rectangle.
-	 *
-	 * @param bounds
-	 *            The rectangle which center to get
-	 * @return The center of the rectangle
-	 */
-	private static Point getCenter(Rectangle bounds) {
-		return new Point(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/swing/ToolTipList.java b/alien/src/net/pterodactylus/util/swing/ToolTipList.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/swing/ToolTipList.java
+++ /dev/null
@@ -1,84 +0,0 @@
-
-package net.pterodactylus.util.swing;
-
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.Point;
-import java.awt.event.MouseEvent;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.swing.JComponent;
-import javax.swing.JList;
-import javax.swing.JPanel;
-import javax.swing.ListCellRenderer;
-import javax.swing.ListModel;
-
-import net.pterodactylus.util.logging.Logging;
-
-/**
- * Extension of {@link JList} that retrieves the tool tip text to display from
- * the cell renderer. This can be used to let a custom {@link ListCellRenderer}
- * return e.g. a {@link JPanel} with multiple components that can return
- * different tool tips.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ToolTipList extends JList {
-
-	/** The logger. */
-	private static final Logger logger = Logging.getLogger(ToolTipList.class);
-
-	/** The underlying list model. */
-	private final ListModel listModel;
-
-	/**
-	 * Creates a new tool tip list.
-	 *
-	 * @param listModel
-	 *            The underlying list model
-	 */
-	public ToolTipList(ListModel listModel) {
-		super(listModel);
-		this.listModel = listModel;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String getToolTipText(MouseEvent event) {
-		logger.log(Level.FINEST, "Getting Tooltip for " + event + "…");
-		int row = locationToIndex(event.getPoint());
-		logger.log(Level.FINEST, "Mouse is over row " + row + ".");
-		if (row < 0) {
-			return null;
-		}
-		Object value = listModel.getElementAt(row);
-		logger.log(Level.FINEST, "Getting Tooltip for “" + value + "”…");
-		if (value == null) {
-			return null;
-		}
-		Component cell = getCellRenderer().getListCellRendererComponent(this, value, row, false, false);
-		logger.log(Level.FINEST, "CellRenderer gave us Cell " + cell + ".");
-		if (cell == null) {
-			return null;
-		}
-		int cellX = cell.getX();
-		int cellY = cell.getY();
-		cell.setSize(new Dimension(-cellX, -cellY));
-		cell.setLocation(0, 0);
-		Point cellLocation = indexToLocation(row);
-		Point mousePosition = event.getPoint();
-		mousePosition.translate(-(int) cellLocation.getX(), -(int) cellLocation.getY());
-		logger.log(Level.FINEST, "Mouse Position translates to " + mousePosition + ".");
-		Component toolTipComponent = cell.getComponentAt(mousePosition);
-		cell.setLocation(cellX, cellY);
-		logger.log(Level.FINEST, "Component under Mouse is " + toolTipComponent + ".");
-		if (toolTipComponent instanceof JComponent) {
-			return ((JComponent) toolTipComponent).getToolTipText();
-		}
-		return null;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/telnet/AbstractCommand.java b/alien/src/net/pterodactylus/util/telnet/AbstractCommand.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/telnet/AbstractCommand.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * utils - AbstractCommand.java - Copyright © 2008-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.telnet;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Abstract base implementation of a {@link Command}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public abstract class AbstractCommand implements Command {
-
-	/** The name of this command. */
-	private final String name;
-
-	/** The brief description of this command. */
-	private final String briefDescription;
-
-	/** The detailed description of this command. */
-	private final List<String> detailedDescription = new ArrayList<String>();
-
-	/**
-	 * Creates a new command with the given name and description.
-	 *
-	 * @param name
-	 *            The name of the command
-	 * @param briefDescription
-	 *            The brief description of this command.
-	 */
-	protected AbstractCommand(String name, String briefDescription) {
-		this.name = name;
-		this.briefDescription = briefDescription;
-	}
-
-	/**
-	 * Creates a new command with the given name, brief description and detailed
-	 * description.
-	 *
-	 * @param name
-	 *            The name of the command
-	 * @param briefDescription
-	 *            The brief description of this command.
-	 * @param detailedDescriptions
-	 *            The detailed descriptions of this command
-	 */
-	protected AbstractCommand(String name, String briefDescription, String... detailedDescriptions) {
-		this.name = name;
-		this.briefDescription = briefDescription;
-		for (String detailedDescription : detailedDescriptions) {
-			this.detailedDescription.add(detailedDescription);
-		}
-	}
-
-	/**
-	 * Creates a new command with the given name, brief description and detailed
-	 * description.
-	 *
-	 * @param name
-	 *            The name of the command
-	 * @param briefDescription
-	 *            The brief description of this command.
-	 * @param detailedDescription
-	 *            The detailed description of this command
-	 */
-	protected AbstractCommand(String name, String briefDescription, List<String> detailedDescription) {
-		this(name, briefDescription);
-		this.detailedDescription.addAll(detailedDescription);
-	}
-
-	//
-	// INTERFACE Command
-	//
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String getName() {
-		return name;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String getBriefDescription() {
-		return briefDescription;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public List<String> getDetailedDescription() {
-		return detailedDescription;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/telnet/Command.java b/alien/src/net/pterodactylus/util/telnet/Command.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/telnet/Command.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * utils - Command.java - Copyright © 2008-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.telnet;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Basic structure of a command that can be sent to a {@link TelnetControl}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface Command {
-
-	/**
-	 * Returns the name of this command. The name is parsed case-insensitively.
-	 *
-	 * @return The name of this command
-	 */
-	public String getName();
-
-	/**
-	 * Returns a brief description of this command.
-	 *
-	 * @return The brief description of this command
-	 */
-	public String getBriefDescription();
-
-	/**
-	 * Returns a detailed description of this command.
-	 *
-	 * @return The detailed description of this command
-	 */
-	public List<String> getDetailedDescription();
-
-	/**
-	 * Executes the command.
-	 *
-	 * @param parameters
-	 *            The parameter of this command
-	 * @return The reply of the command
-	 */
-	public Reply execute(List<String> parameters);
-
-	/**
-	 * A reply to a {@link Command}.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public class Reply {
-
-		/** The “OK” status. */
-		public static final int OK = 200;
-
-		/** The “multiple choices” status. */
-		public static final int MULTIPLE_CHOICES = 300;
-
-		/** The “bad request” status. */
-		public static final int BAD_REQUEST = 400;
-
-		/** The “not found” status. */
-		public static final int NOT_FOUND = 404;
-
-		/** The “internal server error” status. */
-		public static final int INTERNAL_SERVER_ERROR = 500;
-
-		/** The status of the reply. */
-		private final int status;
-
-		/** The lines that make up the reply. */
-		private final List<String> lines = new ArrayList<String>();
-
-		/**
-		 * Creates a new reply with the given status.
-		 *
-		 * @param status
-		 *            The status of the reply
-		 */
-		public Reply(int status) {
-			this.status = status;
-		}
-
-		/**
-		 * Creates a new reply with the given status and line.
-		 *
-		 * @param status
-		 *            The status of the reply
-		 * @param line
-		 *            The line of the reply
-		 */
-		public Reply(int status, String line) {
-			this(status, new String[] { line });
-		}
-
-		/**
-		 * Creates a new reply with the given status and lines.
-		 *
-		 * @param status
-		 *            The status of the reply
-		 * @param lines
-		 *            The lines of the reply
-		 */
-		public Reply(int status, String... lines) {
-			this(status, Arrays.asList(lines));
-		}
-
-		/**
-		 * Creates a new reply with the given status and lines.
-		 *
-		 * @param status
-		 *            The status of the reply
-		 * @param lines
-		 *            The lines of the reply
-		 */
-		public Reply(int status, List<String> lines) {
-			this.status = status;
-			this.lines.addAll(lines);
-		}
-
-		/**
-		 * Adds a line to the reply.
-		 *
-		 * @param line
-		 *            The line to add
-		 * @return This reply (for method invocation chaining)
-		 */
-		public Reply addLine(String line) {
-			lines.add(line);
-			return this;
-		}
-
-		/**
-		 * Returns the status of this command.
-		 *
-		 * @return The status of this command
-		 */
-		public int getStatus() {
-			return status;
-		}
-
-		/**
-		 * Returns the lines that make up this reply.
-		 *
-		 * @return The lines of this reply
-		 */
-		public List<String> getLines() {
-			return lines;
-		}
-
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/telnet/ControlConnection.java b/alien/src/net/pterodactylus/util/telnet/ControlConnection.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/telnet/ControlConnection.java
+++ /dev/null
@@ -1,241 +0,0 @@
-
-package net.pterodactylus.util.telnet;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import net.pterodactylus.util.io.Closer;
-import net.pterodactylus.util.logging.Logging;
-import net.pterodactylus.util.service.AbstractService;
-import net.pterodactylus.util.telnet.Command.Reply;
-import net.pterodactylus.util.text.StringEscaper;
-import net.pterodactylus.util.text.TextException;
-
-/**
- * Handles a single client connection.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ControlConnection extends AbstractService {
-
-	/** The logger. */
-	private static final Logger logger = Logging.getLogger(ControlConnection.class.getName());
-
-	/** The line break. */
-	private static final String LINEFEED = "\r\n";
-
-	/** The client’s input stream. */
-	private final InputStream clientInputStream;
-
-	/** The client’s output stream. */
-	private final OutputStream clientOutputStream;
-
-	/** The output stream writer. */
-	private final PrintWriter outputStreamWriter;
-
-	/** Mapping from command names to commands. */
-	Map<String, Command> commands = new HashMap<String, Command>();
-
-	/** Mapping from internal command names to commands. */
-	Map<String, Command> internalCommands = new HashMap<String, Command>();
-
-	/**
-	 * Creates a new connection handler for a client on the given socket.
-	 *
-	 * @param clientInputStream
-	 *            The client input stream
-	 * @param clientOutputStream
-	 *            The client output stream
-	 */
-	public ControlConnection(InputStream clientInputStream, OutputStream clientOutputStream) {
-		this.clientInputStream = clientInputStream;
-		this.clientOutputStream = clientOutputStream;
-		this.outputStreamWriter = new PrintWriter(clientOutputStream);
-		addCommand(new QuitCommand());
-	}
-
-	//
-	// ACCESSORS
-	//
-
-	/**
-	 * Adds the given command to this control.
-	 *
-	 * @param command
-	 *            The command to add
-	 */
-	public void addCommand(Command command) {
-		commands.put(command.getName().toLowerCase(), command);
-		internalCommands.put("help", new HelpCommand(commands.values()));
-	}
-
-	//
-	// ACTIONS
-	//
-
-	/**
-	 * Prints the given line to the output stream.
-	 *
-	 * @param line
-	 *            The line to print
-	 */
-	public void addOutputLine(String line) {
-		addOutputLines(line);
-	}
-
-	/**
-	 * Prints the given lines to the output stream.
-	 *
-	 * @param lines
-	 *            The lines to print
-	 */
-	public void addOutputLines(String... lines) {
-		synchronized (outputStreamWriter) {
-			for (String line : lines) {
-				outputStreamWriter.println(line);
-			}
-			outputStreamWriter.flush();
-		}
-	}
-
-	//
-	// SERVICE METHODS
-	//
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	protected void serviceRun() {
-		InputStreamReader inputStreamReader = null;
-		BufferedReader bufferedReader = null;
-		try {
-			inputStreamReader = new InputStreamReader(clientInputStream);
-			bufferedReader = new BufferedReader(inputStreamReader);
-			String line;
-			boolean finished = false;
-			while (!finished && ((line = bufferedReader.readLine()) != null)) {
-				line = line.trim();
-				if (line.length() == 0) {
-					continue;
-				}
-				List<String> words;
-				try {
-					words = StringEscaper.parseLine(line);
-				} catch (TextException te1) {
-					writeReply(new Reply(Reply.BAD_REQUEST).addLine("Syntax error."));
-					continue;
-				}
-				if (words.isEmpty()) {
-					continue;
-				}
-				String commandName = words.remove(0).toLowerCase();
-				List<Command> foundCommands = findCommand(commandName);
-				if (foundCommands.isEmpty()) {
-					writeReply(new Reply(Reply.NOT_FOUND).addLine("Command not found."));
-				} else if (foundCommands.size() == 1) {
-					Command command = foundCommands.get(0);
-					try {
-						Reply commandReply = command.execute(words);
-						writeReply(commandReply);
-					} catch (IOException ioe1) {
-						throw ioe1;
-					} catch (Throwable t1) {
-						writeReply(new Reply(Reply.INTERNAL_SERVER_ERROR).addLine("Internal server error: " + t1.getMessage()));
-					}
-					if (command instanceof QuitCommand) {
-						finished = true;
-					}
-				} else {
-					Reply reply = new Reply(Reply.MULTIPLE_CHOICES, "Multiple choices found:");
-					for (Command command : foundCommands) {
-						reply.addLine(command.getName());
-					}
-					writeReply(reply);
-				}
-			}
-		} catch (IOException ioe1) {
-			logger.log(Level.INFO, "could not handle connection", ioe1);
-		} finally {
-			Closer.close(outputStreamWriter);
-			Closer.close(bufferedReader);
-			Closer.close(inputStreamReader);
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	protected void serviceStop() {
-		Closer.close(clientInputStream);
-		Closer.close(clientOutputStream);
-	}
-
-	//
-	// PRIVATE METHODS
-	//
-
-	/**
-	 * Searches both internal and user commands for a command. A command must
-	 * have a name that equals or starts with the given name to be a match.
-	 *
-	 * @param name
-	 *            The name of the command
-	 * @return All found commands
-	 */
-	private List<Command> findCommand(String name) {
-		List<Command> foundCommands = new ArrayList<Command>();
-		for (Command command : internalCommands.values()) {
-			if (command.getName().toLowerCase().startsWith(name.toLowerCase())) {
-				foundCommands.add(command);
-			}
-		}
-		for (Command command : commands.values()) {
-			if (command.getName().toLowerCase().startsWith(name.toLowerCase())) {
-				foundCommands.add(command);
-			}
-		}
-		return foundCommands;
-	}
-
-	/**
-	 * Writes the given reply to the client’s output stream. The
-	 * <code>reply</code> may be <code>null</code> in which case an appropriate
-	 * error message is written.
-	 *
-	 * @param reply
-	 *            The reply to send
-	 * @throws IOException
-	 *             if an I/O error occurs
-	 */
-	private void writeReply(Reply reply) throws IOException {
-		synchronized (outputStreamWriter) {
-			if (reply == null) {
-				outputStreamWriter.write("500 Internal server error." + LINEFEED);
-				outputStreamWriter.flush();
-				return;
-			}
-			int status = reply.getStatus();
-			List<String> lines = reply.getLines();
-			for (int lineIndex = 0, lineCount = lines.size(); lineIndex < lineCount; lineIndex++) {
-				outputStreamWriter.write(status + ((lineIndex < (lineCount - 1)) ? "-" : " ") + lines.get(lineIndex) + LINEFEED);
-			}
-			if (lines.size() == 0) {
-				outputStreamWriter.write("200 OK." + LINEFEED);
-			}
-			outputStreamWriter.flush();
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/telnet/GarbageCollectionCommand.java b/alien/src/net/pterodactylus/util/telnet/GarbageCollectionCommand.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/telnet/GarbageCollectionCommand.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.pterodactylus.util.telnet;
-
-import java.util.List;
-
-/**
- * Command that performs a garbage collection.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class GarbageCollectionCommand extends AbstractCommand {
-
-	/**
-	 * Creates a new garbage collection command.
-	 */
-	public GarbageCollectionCommand() {
-		super("GC", "Performs a garbage collection.");
-	}
-
-	/**
-	 * @see net.pterodactylus.util.telnet.Command#execute(java.util.List)
-	 */
-	@Override
-	public Reply execute(List<String> parameters) {
-		System.gc();
-		return new Reply(200, "Garbage Collection suggested.");
-	}
-
-}
\ No newline at end of file
diff --git a/alien/src/net/pterodactylus/util/telnet/HelpCommand.java b/alien/src/net/pterodactylus/util/telnet/HelpCommand.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/telnet/HelpCommand.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * utils - HelpCommand - Copyright © 2008-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.telnet;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Command that outputs help information about commands.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class HelpCommand extends AbstractCommand {
-
-	/** The list of commands to show help for. */
-	private final Collection<Command> commands;
-
-	/**
-	 * Creates a new HELP command.
-	 *
-	 * @param commands
-	 *            The commands to show help about
-	 */
-	public HelpCommand(Collection<Command> commands) {
-		super("HELP", "outputs help of all commands");
-		this.commands = commands;
-	}
-
-	//
-	// PRIVATE METHODS
-	//
-
-	//
-	// INTERFACE Command
-	//
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Reply execute(List<String> parameters) {
-		Reply reply = new Reply(200);
-
-		if (parameters.isEmpty()) {
-			for (Command command : commands) {
-				reply.addLine(command.getName().toUpperCase() + ": " + command.getBriefDescription());
-			}
-		} else {
-			String commandName = parameters.get(0).toLowerCase();
-			for (Command command : commands) {
-				if (command.getName().toLowerCase().startsWith(commandName)) {
-					reply.addLine(command.getName().toUpperCase() + ": " + command.getBriefDescription());
-					for (String detailDescription : command.getDetailedDescription()) {
-						reply.addLine("  " + detailDescription);
-					}
-				}
-			}
-		}
-
-		return reply;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/telnet/MemoryCommand.java b/alien/src/net/pterodactylus/util/telnet/MemoryCommand.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/telnet/MemoryCommand.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * utils - MemoryCommand.java - Copyright © 2008-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.telnet;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import net.pterodactylus.util.number.Digits;
-import net.pterodactylus.util.number.SI;
-
-/**
- * Command that outputs some memory statistics.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class MemoryCommand extends AbstractCommand {
-
-	/**
-	 * Creates a new memory command.
-	 */
-	public MemoryCommand() {
-		super("MEMORY", "Shows memory statistics.");
-	}
-
-	/**
-	 * @see net.pterodactylus.util.telnet.Command#execute(java.util.List)
-	 */
-	@Override
-	public Reply execute(List<String> parameters) {
-		long freeMemory = Runtime.getRuntime().freeMemory();
-		long totalMemory = Runtime.getRuntime().totalMemory();
-		long maxMemory = Runtime.getRuntime().maxMemory();
-		long usedMemory = totalMemory - freeMemory;
-		List<String> lines = new ArrayList<String>();
-		lines.add("Used Memory: " + SI.format(usedMemory, 1, true, true) + "B");
-		lines.add("Reversed Memory: " + SI.format(totalMemory, 1, true, true) + "B, " + Digits.formatFractions(usedMemory * 100.0 / totalMemory, 1, false) + "% used");
-		lines.add("Maximum Memory: " + SI.format(maxMemory, 1, true, true) + "B, " + Digits.formatFractions(usedMemory * 100.0 / maxMemory, 1, false) + "% used");
-		return new Reply(200, lines);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/telnet/QuitCommand.java b/alien/src/net/pterodactylus/util/telnet/QuitCommand.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/telnet/QuitCommand.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * utils - QuitCommand.java - Copyright © 2008-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.telnet;
-
-import java.util.List;
-
-/**
- * Special command that closes the connection to the telnet control.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class QuitCommand extends AbstractCommand {
-
-	/**
-	 * Creates a new quit command.
-	 */
-	public QuitCommand() {
-		super("QUIT", "Closes the connection.");
-	}
-
-	/**
-	 * @see net.pterodactylus.util.telnet.Command#execute(java.util.List)
-	 */
-	@Override
-	public Reply execute(List<String> parameters) {
-		return new Reply(200, "Goodbye.");
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/telnet/TelnetControl.java b/alien/src/net/pterodactylus/util/telnet/TelnetControl.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/telnet/TelnetControl.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * utils - TelnetControl.java - Copyright © 2008-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.telnet;
-
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import net.pterodactylus.util.io.Closer;
-import net.pterodactylus.util.logging.Logging;
-import net.pterodactylus.util.service.AbstractService;
-
-/**
- * TODO
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class TelnetControl extends AbstractService {
-
-	/** The logger. */
-	private static final Logger logger = Logging.getLogger(TelnetControl.class.getName());
-
-	/** The server socket. */
-	private ServerSocket serverSocket;
-
-	/** The port to listen on. */
-	private int listenPort = 20013;
-
-	/** Mapping from command names to commands. */
-	private final Map<String, Command> commands = new HashMap<String, Command>();
-
-	/**
-	 * Creates a new telnet control.
-	 */
-	public TelnetControl() {
-		super("Telnet Control");
-	}
-
-	//
-	// ACCESSORS
-	//
-
-	/**
-	 * Sets the port to listen on.
-	 *
-	 * @param listenPort
-	 *            The port to listen on
-	 */
-	public void setListenPort(int listenPort) {
-		this.listenPort = listenPort;
-	}
-
-	/**
-	 * Adds the given command to this control.
-	 *
-	 * @param command
-	 *            The command to add
-	 */
-	public void addCommand(Command command) {
-		commands.put(command.getName().toLowerCase(), command);
-	}
-
-	//
-	// SERVICE METHODS
-	//
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	protected void serviceRun() {
-		logger.log(Level.INFO, "starting telnet control main loop");
-		try {
-			serverSocket = new ServerSocket(listenPort);
-		} catch (IOException ioe1) {
-			logger.log(Level.SEVERE, "could not create server socket on port " + listenPort, ioe1);
-			return;
-		}
-		while (!shouldStop()) {
-			try {
-				Socket clientSocket = serverSocket.accept();
-				logger.log(Level.INFO, "acception client connection on " + clientSocket.getRemoteSocketAddress());
-				ControlConnection controlConnection = new ControlConnection(clientSocket.getInputStream(), clientSocket.getOutputStream());
-				for (Command command : commands.values()) {
-					controlConnection.addCommand(command);
-				}
-				controlConnection.start();
-			} catch (IOException ioe1) {
-				if (!shouldStop()) {
-					logger.log(Level.WARNING, "could not accept client connection", ioe1);
-				}
-			}
-		}
-		logger.log(Level.INFO, "stopped telnet control main loop.");
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	protected void serviceStop() {
-		Closer.close(serverSocket);
-	}
-
-	/**
-	 * VM entry point for testing.
-	 *
-	 * @param arguments
-	 *            Command-line arguments
-	 * @throws InterruptedException
-	 *             if {@link Thread#sleep(long)} is interrupted
-	 */
-	public static void main(String... arguments) throws InterruptedException {
-		TelnetControl telnetControl = new TelnetControl();
-		telnetControl.init();
-		telnetControl.addCommand(new MemoryCommand());
-		telnetControl.addCommand(new GarbageCollectionCommand());
-		telnetControl.start();
-		Thread.sleep(120 * 1000);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/telnet/UptimeCommand.java b/alien/src/net/pterodactylus/util/telnet/UptimeCommand.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/telnet/UptimeCommand.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * utils - UptimeCommand.java - Copyright © 2008-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.telnet;
-
-import java.util.List;
-
-import net.pterodactylus.util.time.Duration;
-
-/**
- * Command that prints out the current uptime.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class UptimeCommand extends AbstractCommand {
-
-	/**
-	 * Creates a new uptime command.
-	 */
-	public UptimeCommand() {
-		super("UPTIME", "Prints uptime information");
-	}
-
-	/** The startup time. */
-	private static final long startupTime = System.currentTimeMillis();
-
-	/**
-	 * @see net.pterodactylus.util.telnet.Command#execute(java.util.List)
-	 */
-	@Override
-	public Reply execute(List<String> parameters) {
-		return new Reply(200, new Duration(System.currentTimeMillis() - startupTime).toString(false));
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/telnet/VersionCommand.java b/alien/src/net/pterodactylus/util/telnet/VersionCommand.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/telnet/VersionCommand.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * utils - VersionCommand.java - Copyright © 2008-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.telnet;
-
-import java.util.List;
-
-/**
- * Replies with the name of the application and the version number.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class VersionCommand extends AbstractCommand {
-
-	/** The name of the application. */
-	private final String application;
-
-	/** The version of the application. */
-	private final String version;
-
-	/**
-	 * Creates a new version command.
-	 *
-	 * @param application
-	 *            The name of the application
-	 * @param version
-	 *            The version of the application
-	 */
-	public VersionCommand(String application, String version) {
-		super("VERSION", "Shows version information about " + application + ".");
-		this.application = application;
-		this.version = version;
-	}
-
-	/**
-	 * @see net.pterodactylus.util.telnet.Command#execute(java.util.List)
-	 */
-	@Override
-	public Reply execute(List<String> parameters) {
-		return new Reply(200, application + " " + version);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/Accessor.java b/alien/src/net/pterodactylus/util/template/Accessor.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/Accessor.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * utils - Accessor.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.util.Map;
-
-/**
- * An accessor can access member variables of objects of a given type.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface Accessor {
-
-	/** Accessor for {@link Map}s. */
-	public static final Accessor MAP_ACCESSOR = new MapAccessor();
-
-	/**
-	 * Returns the member with the given name.
-	 *
-	 * @param dataProvider
-	 *            The current data provider
-	 * @param object
-	 *            The object to access
-	 * @param member
-	 *            The name of the member
-	 * @return The member, or {@code null} if the member does not exist
-	 */
-	public Object get(DataProvider dataProvider, Object object, String member);
-
-}
-
-/**
- * {@link Accessor} implementation that can access values in a {@link Map}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-class MapAccessor implements Accessor {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Object get(DataProvider dataProvider, Object object, String member) {
-		return ((Map<?, ?>) object).get(member);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/ConditionalPart.java b/alien/src/net/pterodactylus/util/template/ConditionalPart.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/ConditionalPart.java
+++ /dev/null
@@ -1,521 +0,0 @@
-/*
- * utils - ConditionalPart.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.io.Writer;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * {@link ContainerPart} implementation that determines at render time whether
- * it should be rendered or not.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-class ConditionalPart extends ContainerPart {
-
-	/** The condition. */
-	private final Condition condition;
-
-	/**
-	 * Creates a new conditional part.
-	 *
-	 * @param condition
-	 *            The condition
-	 */
-	public ConditionalPart(Condition condition) {
-		super();
-		this.condition = condition;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void render(DataProvider dataProvider, Writer writer) throws TemplateException {
-		if (condition.isAllowed(dataProvider)) {
-			super.render(dataProvider, writer);
-		}
-	}
-
-	/**
-	 * Condition that decides whether a {@link ConditionalPart} is rendered at
-	 * render time.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public interface Condition {
-
-		/**
-		 * Returns whether the condition is fulfilled.
-		 *
-		 * @param dataProvider
-		 *            The data provider
-		 * @return {@code true} if the condition is fulfilled, {@code false}
-		 *         otherwise
-		 * @throws TemplateException
-		 *             if a template variable can not be parsed or evaluated
-		 */
-		public boolean isAllowed(DataProvider dataProvider) throws TemplateException;
-
-	}
-
-	/**
-	 * {@link Condition} implements that inverts another condition.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public static class NotCondition implements Condition {
-
-		/** The condition to invert. */
-		private final Condition condition;
-
-		/**
-		 * Creates a inverting condition.
-		 *
-		 * @param condition
-		 *            The condition to invert
-		 */
-		public NotCondition(Condition condition) {
-			this.condition = condition;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public boolean isAllowed(DataProvider dataProvider) throws TemplateException {
-			return !condition.isAllowed(dataProvider);
-		}
-
-	}
-
-	/**
-	 * {@link Condition} implementation that only returns true if all its
-	 * conditions are true also.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public static class AndCondition implements Condition {
-
-		/** The conditions. */
-		private final Collection<Condition> conditions;
-
-		/**
-		 * Creates a new AND condition.
-		 *
-		 * @param conditions
-		 *            The conditions
-		 */
-		public AndCondition(Condition... conditions) {
-			this(Arrays.asList(conditions));
-		}
-
-		/**
-		 * Creates a new AND condition.
-		 *
-		 * @param conditions
-		 *            The conditions
-		 */
-		public AndCondition(Collection<Condition> conditions) {
-			this.conditions = conditions;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public boolean isAllowed(DataProvider dataProvider) throws TemplateException {
-			for (Condition condition : conditions) {
-				if (!condition.isAllowed(dataProvider)) {
-					return false;
-				}
-			}
-			return true;
-		}
-
-	}
-
-	/**
-	 * {@link Condition} implementation that only returns false if all its
-	 * conditions are false also.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public static class OrCondition implements Condition {
-
-		/** The conditions. */
-		private final Collection<Condition> conditions;
-
-		/**
-		 * Creates a new OR condition.
-		 *
-		 * @param conditions
-		 *            The conditions
-		 */
-		public OrCondition(Condition... conditions) {
-			this(Arrays.asList(conditions));
-		}
-
-		/**
-		 * Creates a new OR condition.
-		 *
-		 * @param conditions
-		 *            The conditions
-		 */
-		public OrCondition(Collection<Condition> conditions) {
-			this.conditions = conditions;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public boolean isAllowed(DataProvider dataProvider) throws TemplateException {
-			for (Condition condition : conditions) {
-				if (condition.isAllowed(dataProvider)) {
-					return true;
-				}
-			}
-			return false;
-		}
-
-	}
-
-	/**
-	 * {@link Condition} implementation that asks the {@link DataProvider} for a
-	 * {@link Boolean} value.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public static class DataCondition implements Condition {
-
-		/** Whether to invert the result. */
-		private final boolean invert;
-
-		/** The name of the data item to check. */
-		private final String itemName;
-
-		/**
-		 * Creates a new data condition.
-		 *
-		 * @param itemName
-		 *            The name of the item to check
-		 */
-		public DataCondition(String itemName) {
-			this(itemName, false);
-		}
-
-		/**
-		 * Creates a new data condition.
-		 *
-		 * @param itemName
-		 *            The name of the item to check
-		 * @param invert
-		 *            {@code true} to invert the result, {@code false} otherwise
-		 */
-		public DataCondition(String itemName, boolean invert) {
-			this.invert = invert;
-			this.itemName = itemName;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public boolean isAllowed(DataProvider dataProvider) throws TemplateException {
-			return Boolean.valueOf(String.valueOf(dataProvider.getData(itemName))) ^ invert;
-		}
-
-	}
-
-	/**
-	 * {@link Condition} implementation that checks a given text for a
-	 * {@link Boolean} value.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public static class DataTextCondition implements Condition {
-
-		/** Whether to invert the result. */
-		private final boolean invert;
-
-		/** The text to check. */
-		private final String text;
-
-		/**
-		 * Creates a new data condition.
-		 *
-		 * @param text
-		 *            The text to check
-		 */
-		public DataTextCondition(String text) {
-			this(text, false);
-		}
-
-		/**
-		 * Creates a new data condition.
-		 *
-		 * @param text
-		 *            The text to check
-		 * @param invert
-		 *            {@code true} to invert the result, {@code false} otherwise
-		 */
-		public DataTextCondition(String text, boolean invert) {
-			this.invert = invert;
-			this.text = text;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public boolean isAllowed(DataProvider dataProvider) throws TemplateException {
-			return Boolean.valueOf(text) ^ invert;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public String toString() {
-			return "(" + text + " = " + !invert + ")";
-		}
-
-	}
-
-	/**
-	 * {@link Condition} implementation that asks the {@link DataProvider} for a
-	 * {@link Boolean} value and checks whether it’s {@code null} or not.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public static class NullDataCondition implements Condition {
-
-		/** Whether to invert the result. */
-		private final boolean invert;
-
-		/** The name of the data item to check. */
-		private final String itemName;
-
-		/**
-		 * Creates a new data condition.
-		 *
-		 * @param itemName
-		 *            The name of the item to check
-		 */
-		public NullDataCondition(String itemName) {
-			this(itemName, false);
-		}
-
-		/**
-		 * Creates a new data condition.
-		 *
-		 * @param itemName
-		 *            The name of the item to check
-		 * @param invert
-		 *            {@code true} to invert the result, {@code false} otherwise
-		 */
-		public NullDataCondition(String itemName, boolean invert) {
-			this.invert = invert;
-			this.itemName = itemName;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public boolean isAllowed(DataProvider dataProvider) throws TemplateException {
-			return (dataProvider.getData(itemName) == null) ^ invert;
-		}
-
-	}
-
-	/**
-	 * {@link Condition} implementation that filters the value from the data
-	 * provider before checking whether it matches “true.”
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public static class FilterCondition implements Condition {
-
-		/** The name of the item. */
-		private final String itemName;
-
-		/** The filters. */
-		private final Collection<Filter> filters;
-
-		/** The filter parameters. */
-		private final Map<Filter, Map<String, String>> filterParameters;
-
-		/** Whether to invert the result. */
-		private final boolean invert;
-
-		/**
-		 * Creates a new filter condition.
-		 *
-		 * @param itemName
-		 *            The name of the item
-		 * @param filters
-		 *            The filters to run through
-		 * @param filterParameters
-		 *            The filter parameters
-		 */
-		public FilterCondition(String itemName, Collection<Filter> filters, Map<Filter, Map<String, String>> filterParameters) {
-			this(itemName, filters, filterParameters, false);
-		}
-
-		/**
-		 * Creates a new filter condition.
-		 *
-		 * @param itemName
-		 *            The name of the item
-		 * @param filters
-		 *            The filters to run through
-		 * @param filterParameters
-		 *            The filter parameters
-		 * @param invert
-		 *            {@code true} to invert the result
-		 */
-		public FilterCondition(String itemName, Collection<Filter> filters, Map<Filter, Map<String, String>> filterParameters, boolean invert) {
-			this.itemName = itemName;
-			this.filters = filters;
-			this.filterParameters = filterParameters;
-			this.invert = invert;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public boolean isAllowed(DataProvider dataProvider) throws TemplateException {
-			Object data = dataProvider.getData(itemName);
-			for (Filter filter : filters) {
-				data = filter.format(dataProvider, data, filterParameters.get(filter));
-			}
-			return Boolean.valueOf(String.valueOf(data)) ^ invert;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public String toString() {
-			StringBuilder stringBuilder = new StringBuilder();
-			stringBuilder.append("([").append(itemName).append("]");
-			for (Filter filter : filters) {
-				stringBuilder.append("|").append(filter.getClass().getSimpleName());
-				if (filterParameters.containsKey(filter)) {
-					for (Entry<String, String> filterParameter : filterParameters.get(filter).entrySet()) {
-						stringBuilder.append(" ").append(filterParameter.getKey()).append("=").append(filterParameter.getValue());
-					}
-				}
-			}
-			return stringBuilder.append(" = ").append(!invert).append(")").toString();
-		}
-
-	}
-
-	/**
-	 * {@link Condition} implementation that filters a given text before
-	 * checking whether it matches “true.”
-	 *
-	 * @author <a href="mailto:david.roden@sysart.de">David Roden</a>
-	 */
-	public static class FilterTextCondition implements Condition {
-
-		/** The text to filter. */
-		private final String text;
-
-		/** The filters. */
-		private final Collection<Filter> filters;
-
-		/** The filter parameters. */
-		private final Map<Filter, Map<String, String>> filterParameters;
-
-		/** Whether to invert the result. */
-		private final boolean invert;
-
-		/**
-		 * Creates a new filter text condition.
-		 *
-		 * @param text
-		 *            The text to filter
-		 * @param filters
-		 *            The filters to run through
-		 * @param filterParameters
-		 *            The filter parameters
-		 */
-		public FilterTextCondition(String text, Collection<Filter> filters, Map<Filter, Map<String, String>> filterParameters) {
-			this(text, filters, filterParameters, false);
-		}
-
-		/**
-		 * Creates a new filter text condition.
-		 *
-		 * @param text
-		 *            The text to filter
-		 * @param filters
-		 *            The filters to run through
-		 * @param filterParameters
-		 *            The filter parameters
-		 * @param invert
-		 *            {@code true} to invert the result
-		 */
-		public FilterTextCondition(String text, Collection<Filter> filters, Map<Filter, Map<String, String>> filterParameters, boolean invert) {
-			this.text = text;
-			this.filters = filters;
-			this.filterParameters = filterParameters;
-			this.invert = invert;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public boolean isAllowed(DataProvider dataProvider) throws TemplateException {
-			Object data = text;
-			for (Filter filter : filters) {
-				data = filter.format(dataProvider, data, filterParameters.get(filter));
-			}
-			return Boolean.valueOf(String.valueOf(data)) ^ invert;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public String toString() {
-			StringBuilder stringBuilder = new StringBuilder();
-			stringBuilder.append("(").append(text);
-			for (Filter filter : filters) {
-				stringBuilder.append("|").append(filter.getClass().getSimpleName());
-				if (filterParameters.containsKey(filter)) {
-					for (Entry<String, String> filterParameter : filterParameters.get(filter).entrySet()) {
-						stringBuilder.append(" ").append(filterParameter.getKey()).append("=").append(filterParameter.getValue());
-					}
-				}
-			}
-			return stringBuilder.append(" = ").append(!invert).append(")").toString();
-		}
-
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/ContainerPart.java b/alien/src/net/pterodactylus/util/template/ContainerPart.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/ContainerPart.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * utils - ContainerPart.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * A {@link Part} that can contain multiple other {@code Part}s.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-class ContainerPart extends Part implements Iterable<Part> {
-
-	/** The parts this part contains. */
-	protected final List<Part> parts = new ArrayList<Part>();
-
-	/**
-	 * Creates a new container part that contains the given parts
-	 */
-	public ContainerPart() {
-		/* do nothing. */
-	}
-
-	/**
-	 * /** Creates a new container part that contains the given parts
-	 *
-	 * @param parts
-	 *            The parts the container part contains
-	 */
-	public ContainerPart(List<Part> parts) {
-		this.parts.addAll(parts);
-	}
-
-	/**
-	 * Adds the given part.
-	 *
-	 * @param part
-	 *            The part to add
-	 */
-	public void add(Part part) {
-		parts.add(part);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void render(DataProvider dataProvider, Writer writer) throws TemplateException {
-		for (Part part : parts) {
-			part.render(dataProvider, writer);
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Iterator<Part> iterator() {
-		return parts.iterator();
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/DataProvider.java b/alien/src/net/pterodactylus/util/template/DataProvider.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/DataProvider.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * utils - DataProvider.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-/**
- * Interface for objects that need to supply data to a {@link Template}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class DataProvider {
-
-	/** Object store. */
-	private final DataStore dataStore;
-
-	/** Accessors. */
-	private final Map<Class<?>, Accessor> classAccessors = new HashMap<Class<?>, Accessor>();
-
-	/**
-	 * Creates a new data provider.
-	 */
-	public DataProvider() {
-		this(new DataStore.MapDataStore());
-	}
-
-	/**
-	 * Creates a new data provider using the given data store as backend.
-	 *
-	 * @param dataStore
-	 *            The data store
-	 */
-	public DataProvider(DataStore dataStore) {
-		this.dataStore = dataStore;
-		classAccessors.put(Map.class, Accessor.MAP_ACCESSOR);
-	}
-
-	/**
-	 * Returns the data provider’s data store.
-	 *
-	 * @return The data store
-	 */
-	protected DataStore getDataStore() {
-		return dataStore;
-	}
-
-	/**
-	 * Adds an accessor for objects of the given class.
-	 *
-	 * @param clazz
-	 *            The class of the objects to handle with the accessor
-	 * @param accessor
-	 *            The accessor to handle the objects with
-	 */
-	public void addAccessor(Class<?> clazz, Accessor accessor) {
-		classAccessors.put(clazz, accessor);
-	}
-
-	/**
-	 * Finds an accessor that can handle the given class. If
-	 * {@link #classAccessors} does not contain a perfect match, a match to a
-	 * superclass or superinterface is searched.
-	 *
-	 * @param clazz
-	 *            The class to get an accessor for
-	 * @return The accessor for the given class, or {@code null} if no accessor
-	 *         could be found
-	 */
-	protected Accessor findAccessor(Class<?> clazz) {
-		if (classAccessors.containsKey(clazz)) {
-			return classAccessors.get(clazz);
-		}
-		for (Class<?> interfaceClass : clazz.getInterfaces()) {
-			if (classAccessors.containsKey(interfaceClass)) {
-				return classAccessors.get(interfaceClass);
-			}
-		}
-		Class<?> classToCheck = clazz.getSuperclass();
-		while (classToCheck != null) {
-			if (classAccessors.containsKey(classToCheck)) {
-				return classAccessors.get(classToCheck);
-			}
-			for (Class<?> interfaceClass : classToCheck.getInterfaces()) {
-				if (classAccessors.containsKey(interfaceClass)) {
-					return classAccessors.get(interfaceClass);
-				}
-			}
-			classToCheck = classToCheck.getSuperclass();
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the object stored under the given name. The name can contain
-	 * hierarchical structures separated by a dot (“.”), such as “loop.count” in
-	 * which case a {@link Map} must be stored under “loop”.
-	 *
-	 * @param name
-	 *            The name of the object to get
-	 * @return The object
-	 * @throws TemplateException
-	 *             if the name or some objects can not be parsed or evaluated
-	 */
-	public Object getData(String name) throws TemplateException {
-		if (name.indexOf('.') == -1) {
-			return getDataStore().get(name);
-		}
-		StringTokenizer nameTokens = new StringTokenizer(name, ".");
-		Object object = null;
-		while (nameTokens.hasMoreTokens()) {
-			String nameToken = nameTokens.nextToken();
-			if (object == null) {
-				object = getDataStore().get(nameToken);
-			} else {
-				Accessor accessor = findAccessor(object.getClass());
-				if (accessor != null) {
-					object = accessor.get(this, object, nameToken);
-				} else {
-					throw new TemplateException("no accessor found for " + object.getClass());
-				}
-			}
-			if (object == null) {
-				return null;
-			}
-		}
-		return object;
-	}
-
-	/**
-	 * Sets data in this data provider.
-	 *
-	 * @param name
-	 *            The key under which to store the data
-	 * @param data
-	 *            The data to store
-	 */
-	public void setData(String name, Object data) {
-		getDataStore().set(name, data);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/DataProviderPart.java b/alien/src/net/pterodactylus/util/template/DataProviderPart.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/DataProviderPart.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * utils - DataProviderPart.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import net.pterodactylus.util.io.Renderable;
-
-/**
- * A {@link Part} whose content is dynamically fetched from a
- * {@link DataProvider}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-class DataProviderPart extends Part {
-
-	/** The name of the object to get. */
-	private final String name;
-
-	/**
-	 * Creates a new data provider part.
-	 *
-	 * @param name
-	 *            The name of the object
-	 */
-	public DataProviderPart(String name) {
-		this.name = name;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void render(DataProvider dataProvider, Writer writer) throws TemplateException {
-		Object output = dataProvider.getData(name);
-		try {
-			if (output instanceof Renderable) {
-				((Renderable) output).render(writer);
-			} else {
-				writer.write((output != null) ? String.valueOf(output) : "");
-			}
-		} catch (IOException ioe1) {
-			throw new TemplateException("Can not render part.", ioe1);
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/DataStore.java b/alien/src/net/pterodactylus/util/template/DataStore.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/DataStore.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * utils - DataStore.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Interface for {@link DataProvider} backends.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface DataStore {
-
-	/**
-	 * Returns the object with the given key.
-	 *
-	 * @param name
-	 *            The key of the data
-	 * @return The data, or {@code null} if there is no data under the given key
-	 */
-	public Object get(String name);
-
-	/**
-	 * Stores an object under the given key.
-	 *
-	 * @param name
-	 *            The key under which to store the object
-	 * @param data
-	 *            The object to store
-	 */
-	public void set(String name, Object data);
-
-	/**
-	 * Default {@link Map}-based implementation of a {@link DataStore}.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	public class MapDataStore implements DataStore {
-
-		/** The backing store. */
-		private final Map<String, Object> objectStore = new HashMap<String, Object>();
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public Object get(String name) {
-			return objectStore.get(name);
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public void set(String name, Object data) {
-			objectStore.put(name, data);
-		}
-
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/DataTemplateProvider.java b/alien/src/net/pterodactylus/util/template/DataTemplateProvider.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/DataTemplateProvider.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * utils - DataTemplateProvider.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-/**
- * {@link TemplateProvider} implementation that retrieves a {@link Template}
- * from a {@link DataProvider}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class DataTemplateProvider implements TemplateProvider {
-
-	/** The data provider. */
-	private final DataProvider dataProvider;
-
-	/**
-	 * Creates a new {@link DataProvider}-based {@link TemplateProvider}.
-	 *
-	 * @param dataProvider
-	 *            The underlying data provider
-	 */
-	public DataTemplateProvider(DataProvider dataProvider) {
-		this.dataProvider = dataProvider;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Template getTemplate(String templateName) {
-		Object templateObject = dataProvider.getData(templateName);
-		return (templateObject instanceof Template) ? (Template) templateObject : null;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/DateFilter.java b/alien/src/net/pterodactylus/util/template/DateFilter.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/DateFilter.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * utils - DateFilter.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * {@link Filter} implementation that formats a date. The date may be given
- * either as a {@link Date} or a {@link Long} object.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class DateFilter implements Filter {
-
-	/** The date format cache. */
-	private static final Map<String, DateFormat> dateFormats = new HashMap<String, DateFormat>();
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String format(DataProvider dataProvider, Object data, Map<String, String> parameters) {
-		String format = parameters.get("format");
-		DateFormat dateFormat = getDateFormat(format);
-		if (data instanceof Date) {
-			return dateFormat.format((Date) data);
-		} else if (data instanceof Long) {
-			return dateFormat.format(new Date((Long) data));
-		}
-		return "";
-	}
-
-	//
-	// PRIVATE METHODS
-	//
-
-	/**
-	 * Returns a {@link DateFormat} for the given format. If the format is
-	 * {@code null} or an empty {@link String}, a default {@link DateFormat}
-	 * instance is returned.
-	 *
-	 * @param format
-	 *            The format of the formatter
-	 * @return A suitable date format
-	 */
-	private DateFormat getDateFormat(String format) {
-		if ((format == null) || (format.trim().length() == 0)) {
-			return DateFormat.getInstance();
-		}
-		DateFormat dateFormat = dateFormats.get(format);
-		if (dateFormat == null) {
-			dateFormat = new SimpleDateFormat(format);
-			dateFormats.put(format, dateFormat);
-		}
-		return dateFormat;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/DefaultFilter.java b/alien/src/net/pterodactylus/util/template/DefaultFilter.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/DefaultFilter.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * utils - DefaultFilter.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.util.Map;
-
-/**
- * {@link Filter} implementation that can return fixed values when the input
- * value is {@code null}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class DefaultFilter implements Filter {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Object format(DataProvider dataProvider, Object data, Map<String, String> parameters) {
-		String defaultValue = parameters.get("value");
-		if (data == null) {
-			return defaultValue;
-		}
-		return data;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/DefaultTemplateFactory.java b/alien/src/net/pterodactylus/util/template/DefaultTemplateFactory.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/DefaultTemplateFactory.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * utils - DefaultTemplateFactory.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.io.Reader;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Default {@link TemplateFactory} implementation that creates {@link Template}s
- * with {@link HtmlFilter}s and {@link ReplaceFilter}s added.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class DefaultTemplateFactory implements TemplateFactory {
-
-	/** The default instance. */
-	private static DefaultTemplateFactory instance;
-
-	/** Filters that will be added to all created templates. */
-	private final Map<String, Filter> filters = new HashMap<String, Filter>();
-
-	/** Plugins that will be added to all created templates. */
-	private final Map<String, Plugin> plugins = new HashMap<String, Plugin>();
-
-	/** Accessors that will be added to all created templates. */
-	private final Map<Class<?>, Accessor> accessors = new HashMap<Class<?>, Accessor>();
-
-	/** The template provider for all created templates. */
-	private TemplateProvider templateProvider;
-
-	/** Additional objects to set in all templates. */
-	private final Map<String, Object> templateObjects = new HashMap<String, Object>();
-
-	/**
-	 * Creates a new default template factory that adds both an
-	 * {@link HtmlFilter} and a {@link ReplaceFilter} to created templates.
-	 */
-	public DefaultTemplateFactory() {
-		this(true, true);
-	}
-
-	/**
-	 * Creates a new default template factory.
-	 *
-	 * @param addHtmlFilter
-	 *            {@code true} to add an {@link HtmlFilter} to created
-	 *            templates, {@code false} otherwise
-	 * @param addReplaceFilter
-	 *            {@code true} to add a {@link ReplaceFilter} to created
-	 *            templates, {@code false} otherwise
-	 */
-	public DefaultTemplateFactory(boolean addHtmlFilter, boolean addReplaceFilter) {
-		this(addHtmlFilter, addReplaceFilter, true, true);
-	}
-
-	/**
-	 * Creates a new default template factory.
-	 *
-	 * @param addHtmlFilter
-	 *            {@code true} to add an {@link HtmlFilter} to created
-	 *            templates, {@code false} otherwise
-	 * @param addReplaceFilter
-	 *            {@code true} to add a {@link ReplaceFilter} to created
-	 *            templates, {@code false} otherwise
-	 * @param addStoreFilter
-	 *            {@code true} to add a {@link StoreFilter} to created
-	 *            templates, {@code false} otherwise
-	 * @param addInsertFilter
-	 *            {@code true} to add a {@link InsertFilter} to created
-	 *            templates, {@code false} otherwise
-	 */
-	public DefaultTemplateFactory(boolean addHtmlFilter, boolean addReplaceFilter, boolean addStoreFilter, boolean addInsertFilter) {
-		this(addHtmlFilter, addReplaceFilter, addStoreFilter, addInsertFilter, true);
-	}
-
-	/**
-	 * Creates a new default template factory.
-	 *
-	 * @param addHtmlFilter
-	 *            {@code true} to add an {@link HtmlFilter} to created
-	 *            templates, {@code false} otherwise
-	 * @param addReplaceFilter
-	 *            {@code true} to add a {@link ReplaceFilter} to created
-	 *            templates, {@code false} otherwise
-	 * @param addStoreFilter
-	 *            {@code true} to add a {@link StoreFilter} to created
-	 *            templates, {@code false} otherwise
-	 * @param addInsertFilter
-	 *            {@code true} to add a {@link InsertFilter} to created
-	 *            templates, {@code false} otherwise
-	 * @param addDefaultFilter
-	 *            {@code true} to add a {@link DefaultFilter} to created
-	 *            templates, {@code false} otherwise
-	 */
-	public DefaultTemplateFactory(boolean addHtmlFilter, boolean addReplaceFilter, boolean addStoreFilter, boolean addInsertFilter, boolean addDefaultFilter) {
-		if (addHtmlFilter) {
-			filters.put("html", new HtmlFilter());
-		}
-		if (addReplaceFilter) {
-			filters.put("replace", new ReplaceFilter());
-		}
-		if (addStoreFilter) {
-			filters.put("store", new StoreFilter());
-		}
-		if (addInsertFilter) {
-			filters.put("insert", new InsertFilter());
-		}
-		if (addDefaultFilter) {
-			filters.put("default", new DefaultFilter());
-		}
-	}
-
-	/**
-	 * Adds an accessor that will be added to all created templates.
-	 *
-	 * @param clazz
-	 *            The class to add the accessor for
-	 * @param accessor
-	 *            The accessor to add
-	 */
-	public void addAccessor(Class<?> clazz, Accessor accessor) {
-		accessors.put(clazz, accessor);
-	}
-
-	/**
-	 * Adds the given filter to all created templates.
-	 *
-	 * @param name
-	 *            The name of the filter
-	 * @param filter
-	 *            The filter to add
-	 */
-	public void addFilter(String name, Filter filter) {
-		filters.put(name, filter);
-	}
-
-	/**
-	 * Adds the given plugin to all created templates.
-	 *
-	 * @param name
-	 *            The name of the plugin
-	 * @param plugin
-	 *            The plugin to add
-	 */
-	public void addPlugin(String name, Plugin plugin) {
-		plugins.put(name, plugin);
-	}
-
-	/**
-	 * Sets the template provider that is set on all created templates.
-	 *
-	 * @param templateProvider
-	 *            The template provider to set
-	 */
-	public void setTemplateProvider(TemplateProvider templateProvider) {
-		this.templateProvider = templateProvider;
-	}
-
-	/**
-	 * Adds an object that will be stored in all created templates.
-	 *
-	 * @param name
-	 *            The name of the template variable
-	 * @param object
-	 *            The object to store
-	 */
-	public void addTemplateObject(String name, Object object) {
-		templateObjects.put(name, object);
-	}
-
-	/**
-	 * Returns the static default instance of this template factory.
-	 *
-	 * @return The default template factory
-	 */
-	public synchronized static TemplateFactory getInstance() {
-		if (instance == null) {
-			instance = new DefaultTemplateFactory();
-		}
-		return instance;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Template createTemplate(Reader templateSource) {
-		Template template = new Template(templateSource);
-		for (Entry<String, Filter> filterEntry : filters.entrySet()) {
-			template.addFilter(filterEntry.getKey(), filterEntry.getValue());
-		}
-		for (Entry<String, Plugin> pluginEntry : plugins.entrySet()) {
-			template.addPlugin(pluginEntry.getKey(), pluginEntry.getValue());
-		}
-		for (Entry<Class<?>, Accessor> accessorEntry : accessors.entrySet()) {
-			template.addAccessor(accessorEntry.getKey(), accessorEntry.getValue());
-		}
-		if (templateProvider != null) {
-			template.setTemplateProvider(templateProvider);
-		}
-		for (Entry<String, Object> objectEntry : templateObjects.entrySet()) {
-			template.set(objectEntry.getKey(), objectEntry.getValue());
-		}
-		return template;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/EmptyLoopPart.java b/alien/src/net/pterodactylus/util/template/EmptyLoopPart.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/EmptyLoopPart.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * utils - EmptyLoopPart.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.io.Writer;
-import java.util.Collection;
-
-/**
- * {@ContainerPart} implementation that only renders its childrens if a
- * {@link Collection} in the template is empty. In combination with
- * {@link LoopPart} this can be used to implements {@code foreach}/{@code
- * foreachelse} loops.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-class EmptyLoopPart extends ContainerPart {
-
-	/** The name of the collection. */
-	private final String collectionName;
-
-	/**
-	 * Creates a new empty loop part.
-	 *
-	 * @param collectionName
-	 *            The name of the collection
-	 */
-	public EmptyLoopPart(String collectionName) {
-		this.collectionName = collectionName;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void render(DataProvider dataProvider, Writer writer) throws TemplateException {
-		Collection<?> collection = (Collection<?>) dataProvider.getData(collectionName);
-		if ((collection != null) && !collection.isEmpty()) {
-			return;
-		}
-		super.render(dataProvider, writer);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/Filter.java b/alien/src/net/pterodactylus/util/template/Filter.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/Filter.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * utils - Filter.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.util.Map;
-
-/**
- * Filters can be used to transform the contents of a variable into some other
- * representation.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface Filter {
-
-	/**
-	 * Formats the given data object.
-	 *
-	 * @param dataProvider
-	 *            The current data provider
-	 * @param data
-	 *            The data to format
-	 * @param parameters
-	 *            Parameters for the filter
-	 * @return The formatted data
-	 */
-	public Object format(DataProvider dataProvider, Object data, Map<String, String> parameters);
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/FilteredPart.java b/alien/src/net/pterodactylus/util/template/FilteredPart.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/FilteredPart.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * utils - FilteredPart.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Collection;
-import java.util.Map;
-
-import net.pterodactylus.util.io.Renderable;
-
-/**
- * {@link Part} implementation that runs the output of another part through one
- * or more {@link Filter}s.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-class FilteredPart extends Part {
-
-	/** The name of the data object to filter. */
-	private final String name;
-
-	/** The filters to apply. */
-	private final Collection<Filter> filters;
-
-	/** Parameters for all filters. */
-	private final Map<Filter, Map<String, String>> allFilterParameters;
-
-	/**
-	 * Creates a new filtered part.
-	 *
-	 * @param name
-	 *            The name of the data object
-	 * @param filters
-	 *            The filters to apply
-	 * @param allFilterParameters
-	 *            All filters’ parameters
-	 */
-	public FilteredPart(String name, Collection<Filter> filters, Map<Filter, Map<String, String>> allFilterParameters) {
-		this.name = name;
-		this.filters = filters;
-		this.allFilterParameters = allFilterParameters;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void render(DataProvider dataProvider, Writer writer) throws TemplateException {
-		Object data = dataProvider.getData(name);
-		Object output = data;
-		for (Filter filter : filters) {
-			data = output = filter.format(dataProvider, data, allFilterParameters.get(filter));
-		}
-		try {
-			if (output instanceof Renderable) {
-				((Renderable) output).render(writer);
-			} else {
-				writer.write((output != null) ? String.valueOf(output) : "");
-			}
-		} catch (IOException ioe1) {
-			throw new TemplateException("Can not render part.", ioe1);
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/FilteredTextPart.java b/alien/src/net/pterodactylus/util/template/FilteredTextPart.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/FilteredTextPart.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * utils - FilteredTextPart.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Collection;
-import java.util.Map;
-
-import net.pterodactylus.util.io.Renderable;
-
-/**
- * {@link Part} implementation that runs a predefined text through one or more
- * {@link Filter}s.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-class FilteredTextPart extends Part {
-
-	/** The text to filter. */
-	private final String text;
-
-	/** The filters to apply. */
-	private final Collection<Filter> filters;
-
-	/** Parameters for all filters. */
-	private final Map<Filter, Map<String, String>> allFilterParameters;
-
-	/**
-	 * Creates a new filtered part.
-	 *
-	 * @param text
-	 *            The text to filter
-	 * @param filters
-	 *            The filters to apply
-	 * @param allFilterParameters
-	 *            Parameters for all filters
-	 */
-	public FilteredTextPart(String text, Collection<Filter> filters, Map<Filter, Map<String, String>> allFilterParameters) {
-		this.text = text;
-		this.filters = filters;
-		this.allFilterParameters = allFilterParameters;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void render(DataProvider dataProvider, Writer writer) throws TemplateException {
-		Object output = text;
-		for (Filter filter : filters) {
-			output = filter.format(dataProvider, output, allFilterParameters.get(filter));
-		}
-		try {
-			if (output instanceof Renderable) {
-				((Renderable) output).render(writer);
-			} else {
-				writer.write((output != null) ? String.valueOf(output) : "");
-			}
-		} catch (IOException ioe1) {
-			throw new TemplateException("Can not render part.", ioe1);
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/HtmlFilter.java b/alien/src/net/pterodactylus/util/template/HtmlFilter.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/HtmlFilter.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * utils - HtmlFilter.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Filters HTML by replacing all characters that match a defined HTML entity by
- * that entity. Unknown characters that are outside of the US-ASCII range (0 to
- * 127) are encoded using the {@code &#1234;} syntax.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class HtmlFilter implements Filter {
-
-	/** Map of defined HTML entities. */
-	private static final Map<Character, String> htmlEntities = new HashMap<Character, String>();
-
-	static {
-		htmlEntities.put('Â', "Acirc");
-		htmlEntities.put('â', "acirc");
-		htmlEntities.put('´', "acute");
-		htmlEntities.put('Æ', "AElig");
-		htmlEntities.put('æ', "aelig");
-		htmlEntities.put('À', "Agrave");
-		htmlEntities.put('à', "agrave");
-		htmlEntities.put('ℵ', "alefsym");
-		htmlEntities.put('Α', "alpha");
-		htmlEntities.put('α', "alpha");
-		htmlEntities.put('&', "amp");
-		htmlEntities.put('∧', "and");
-		htmlEntities.put('∠', "ang");
-		htmlEntities.put('\'', "apos");
-		htmlEntities.put('Å', "Aring");
-		htmlEntities.put('å', "aring");
-		htmlEntities.put('≈', "asymp");
-		htmlEntities.put('Ã', "Atilde");
-		htmlEntities.put('ã', "atilde");
-		htmlEntities.put('Ä', "Auml");
-		htmlEntities.put('ä', "auml");
-		htmlEntities.put('„', "bdquo");
-		htmlEntities.put('Β', "Beta");
-		htmlEntities.put('β', "beta");
-		htmlEntities.put('¦', "brvbar");
-		htmlEntities.put('•', "bull");
-		htmlEntities.put('∩', "cap");
-		htmlEntities.put('Ç', "Ccedil");
-		htmlEntities.put('ç', "ccedil");
-		htmlEntities.put('¸', "cedil");
-		htmlEntities.put('¢', "cent");
-		htmlEntities.put('Χ', "Chi");
-		htmlEntities.put('χ', "chi");
-		htmlEntities.put('ˆ', "circ");
-		htmlEntities.put('♣', "clubs");
-		htmlEntities.put('≅', "cong");
-		htmlEntities.put('©', "copy");
-		htmlEntities.put('↵', "crarr");
-		htmlEntities.put('∪', "cup");
-		htmlEntities.put('¤', "curren");
-		htmlEntities.put('‡', "Dagger");
-		htmlEntities.put('†', "dagger");
-		htmlEntities.put('⇓', "dArr");
-		htmlEntities.put('↓', "darr");
-		htmlEntities.put('°', "deg");
-		htmlEntities.put('Δ', "Delta");
-		htmlEntities.put('δ', "delta");
-		htmlEntities.put('♦', "diams");
-		htmlEntities.put('÷', "divide");
-		htmlEntities.put('É', "Eacute");
-		htmlEntities.put('é', "eacute");
-		htmlEntities.put('Ê', "Ecirc");
-		htmlEntities.put('ê', "ecirc");
-		htmlEntities.put('È', "Egrave");
-		htmlEntities.put('è', "egrave");
-		htmlEntities.put('∅', "empty");
-		htmlEntities.put('\u2003', "emsp");
-		htmlEntities.put('\u2002', "ensp");
-		htmlEntities.put('Ε', "Epsilon");
-		htmlEntities.put('ε', "epsilon");
-		htmlEntities.put('≡', "equiv");
-		htmlEntities.put('Η', "Eta");
-		htmlEntities.put('η', "eta");
-		htmlEntities.put('Ð', "ETH");
-		htmlEntities.put('ð', "eth");
-		htmlEntities.put('Ë', "Euml");
-		htmlEntities.put('ë', "euml");
-		htmlEntities.put('€', "euro");
-		htmlEntities.put('∃', "exist");
-		htmlEntities.put('ƒ', "fnof");
-		htmlEntities.put('∀', "forall");
-		htmlEntities.put('½', "frac12");
-		htmlEntities.put('¼', "frac14");
-		htmlEntities.put('¾', "frac34");
-		htmlEntities.put('⁄', "frasl");
-		htmlEntities.put('Γ', "Gamma");
-		htmlEntities.put('γ', "gamma");
-		htmlEntities.put('≥', "ge");
-		htmlEntities.put('>', "gt");
-		htmlEntities.put('⇔', "hArr");
-		htmlEntities.put('↔', "harr");
-		htmlEntities.put('♥', "hearts");
-		htmlEntities.put('…', "hellip");
-		htmlEntities.put('Í', "Iacute");
-		htmlEntities.put('í', "iacute");
-		htmlEntities.put('Î', "Icirc");
-		htmlEntities.put('î', "icirc");
-		htmlEntities.put('¡', "iexcl");
-		htmlEntities.put('Ì', "Igrave");
-		htmlEntities.put('ì', "igrave");
-		htmlEntities.put('ℑ', "image");
-		htmlEntities.put('∞', "infin");
-		htmlEntities.put('∫', "int");
-		htmlEntities.put('Ι', "Iota");
-		htmlEntities.put('ι', "iota");
-		htmlEntities.put('¿', "iquest");
-		htmlEntities.put('∈', "isin");
-		htmlEntities.put('Ï', "Iuml");
-		htmlEntities.put('ï', "iuml");
-		htmlEntities.put('Κ', "Kappa");
-		htmlEntities.put('κ', "kappa");
-		htmlEntities.put('Λ', "Lambda");
-		htmlEntities.put('λ', "lambda");
-		htmlEntities.put('〈', "lang");
-		htmlEntities.put('«', "laquo");
-		htmlEntities.put('⇐', "lArr");
-		htmlEntities.put('←', "larr");
-		htmlEntities.put('⌈', "lceil");
-		htmlEntities.put('“', "ldquo");
-		htmlEntities.put('≤', "le");
-		htmlEntities.put('⌊', "lfloor");
-		htmlEntities.put('∗', "lowast");
-		htmlEntities.put('◊', "loz");
-		htmlEntities.put('\u200e', "lrm");
-		htmlEntities.put('‹', "lsaquo");
-		htmlEntities.put('‘', "lsquo");
-		htmlEntities.put('<', "lt");
-		htmlEntities.put('¯', "macr");
-		htmlEntities.put('—', "mdash");
-		htmlEntities.put('µ', "micro");
-		htmlEntities.put('·', "middot");
-		htmlEntities.put('−', "minus");
-		htmlEntities.put('Μ', "Mu");
-		htmlEntities.put('μ', "mu");
-		htmlEntities.put('∇', "nabla");
-		htmlEntities.put('\u00a0', "nbsp");
-		htmlEntities.put('–', "ndash");
-		htmlEntities.put('≠', "ne");
-		htmlEntities.put('∋', "ni");
-		htmlEntities.put('¬', "not");
-		htmlEntities.put('∉', "notin");
-		htmlEntities.put('⊄', "nsub");
-		htmlEntities.put('Ñ', "Ntilde");
-		htmlEntities.put('ñ', "ntilde");
-		htmlEntities.put('Ν', "Nu");
-		htmlEntities.put('ν', "nu");
-		htmlEntities.put('Ó', "Oacute");
-		htmlEntities.put('ó', "oacute");
-		htmlEntities.put('Ô', "Ocirc");
-		htmlEntities.put('ô', "ocirc");
-		htmlEntities.put('Œ', "OElig");
-		htmlEntities.put('œ', "oelig");
-		htmlEntities.put('Ò', "Ograve");
-		htmlEntities.put('ò', "ograve");
-		htmlEntities.put('‾', "oline");
-		htmlEntities.put('Ω', "Omega");
-		htmlEntities.put('ω', "omega");
-		htmlEntities.put('Ο', "Omicron");
-		htmlEntities.put('ο', "omicron");
-		htmlEntities.put('⊕', "oplus");
-		htmlEntities.put('∨', "or");
-		htmlEntities.put('ª', "ordf");
-		htmlEntities.put('º', "ordm");
-		htmlEntities.put('Ø', "Oslash");
-		htmlEntities.put('ø', "oslash");
-		htmlEntities.put('Õ', "Otilde");
-		htmlEntities.put('õ', "otilde");
-		htmlEntities.put('⊗', "otimes");
-		htmlEntities.put('Ö', "Ouml");
-		htmlEntities.put('ö', "ouml");
-		htmlEntities.put('¶', "para");
-		htmlEntities.put('∂', "part");
-		htmlEntities.put('‰', "permil");
-		htmlEntities.put('⊥', "perp");
-		htmlEntities.put('Φ', "Phi");
-		htmlEntities.put('φ', "phi");
-		htmlEntities.put('Π', "pi");
-		htmlEntities.put('π', "pi");
-		htmlEntities.put('ϖ', "piv");
-		htmlEntities.put('±', "plusmn");
-		htmlEntities.put('£', "pound");
-		htmlEntities.put('″', "Prime");
-		htmlEntities.put('′', "prime");
-		htmlEntities.put('∏', "prod");
-		htmlEntities.put('∝', "prop");
-		htmlEntities.put('Ψ', "Psi");
-		htmlEntities.put('ψ', "psi");
-		htmlEntities.put('"', "quot");
-		htmlEntities.put('√', "radic");
-		htmlEntities.put('〉', "rang");
-		htmlEntities.put('»', "raquo");
-		htmlEntities.put('⇒', "rArr");
-		htmlEntities.put('→', "rarr");
-		htmlEntities.put('⌉', "rceil");
-		htmlEntities.put('”', "rdquo");
-		htmlEntities.put('ℜ', "real");
-		htmlEntities.put('®', "reg");
-		htmlEntities.put('⌋', "rfloor");
-		htmlEntities.put('Ρ', "Rho");
-		htmlEntities.put('ρ', "rho");
-		htmlEntities.put('\u200f', "rlm");
-		htmlEntities.put('›', "rsaquo");
-		htmlEntities.put('’', "rsquo");
-		htmlEntities.put('‚', "sbquo");
-		htmlEntities.put('Š', "Scaron");
-		htmlEntities.put('š', "scaron");
-		htmlEntities.put('⋅', "sdot");
-		htmlEntities.put('§', "sect");
-		htmlEntities.put('\u00ad', "shy");
-		htmlEntities.put('Σ', "Sigma");
-		htmlEntities.put('σ', "sigma");
-		htmlEntities.put('ς', "sigmaf");
-		htmlEntities.put('∼', "sim");
-		htmlEntities.put('♠', "spades");
-		htmlEntities.put('⊂', "sub");
-		htmlEntities.put('⊆', "sube");
-		htmlEntities.put('∑', "sum");
-		htmlEntities.put('⊃', "sup");
-		htmlEntities.put('¹', "sup1");
-		htmlEntities.put('²', "sup2");
-		htmlEntities.put('³', "sup3");
-		htmlEntities.put('⊇', "supe");
-		htmlEntities.put('ß', "szlig");
-		htmlEntities.put('Τ', "Tau");
-		htmlEntities.put('τ', "tau");
-		htmlEntities.put('∴', "there4");
-		htmlEntities.put('Θ', "Theta");
-		htmlEntities.put('θ', "theta");
-		htmlEntities.put('ϑ', "thetasym");
-		htmlEntities.put('\u2009', "thinsp");
-		htmlEntities.put('Þ', "THORN");
-		htmlEntities.put('þ', "thorn");
-		htmlEntities.put('˜', "tilde");
-		htmlEntities.put('×', "times");
-		htmlEntities.put('™', "trade");
-		htmlEntities.put('Ú', "Uacute");
-		htmlEntities.put('ú', "uacute");
-		htmlEntities.put('⇑', "hArr");
-		htmlEntities.put('↑', "harr");
-		htmlEntities.put('Û', "Ucirc");
-		htmlEntities.put('û', "ucirc");
-		htmlEntities.put('Ù', "Ugrave");
-		htmlEntities.put('ù', "ugrave");
-		htmlEntities.put('¨', "uml");
-		htmlEntities.put('ϒ', "upsih");
-		htmlEntities.put('Υ', "Upsilon");
-		htmlEntities.put('υ', "upsilon");
-		htmlEntities.put('Ü', "Uuml");
-		htmlEntities.put('ü', "uuml");
-		htmlEntities.put('℘', "weierp");
-		htmlEntities.put('Ξ', "Xi");
-		htmlEntities.put('ξ', "xi");
-		htmlEntities.put('Ý', "Yacute");
-		htmlEntities.put('ý', "yacute");
-		htmlEntities.put('¥', "yen");
-		htmlEntities.put('Ÿ', "Yuml");
-		htmlEntities.put('ÿ', "yuml");
-		htmlEntities.put('Ζ', "Zeta");
-		htmlEntities.put('ζ', "zeta");
-		htmlEntities.put('\u200d', "zwj");
-		htmlEntities.put('\u200c', "zwnj");
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String format(DataProvider dataProvider, Object data, Map<String, String> parameters) {
-		StringBuilder htmlOutput = new StringBuilder();
-		for (char c : (data != null) ? String.valueOf(data).toCharArray() : new char[0]) {
-			if (htmlEntities.containsKey(c)) {
-				htmlOutput.append('&').append(htmlEntities.get(c)).append(';');
-				continue;
-			}
-			if (c > 127) {
-				htmlOutput.append("&#").append((int) c).append(';');
-				continue;
-			}
-			htmlOutput.append(c);
-		}
-		return htmlOutput.toString();
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/InsertFilter.java b/alien/src/net/pterodactylus/util/template/InsertFilter.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/InsertFilter.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * utils - InsertFilter.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.util.Map;
-
-/**
- * {@link Filter} implementation that works like a {@link ReplaceFilter}, only
- * that the actual replacement value is read from a template variable, which can
- * be set either using {@link Template#set(String, Object)} or using a
- * {@link StoreFilter}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class InsertFilter extends ReplaceFilter {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String format(DataProvider dataProvider, Object data, Map<String, String> parameters) {
-		parameters.put("replacement", String.valueOf(dataProvider.getData(parameters.get("key"))));
-		return super.format(dataProvider, data, parameters);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/ListAccessor.java b/alien/src/net/pterodactylus/util/template/ListAccessor.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/ListAccessor.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * utils - ListAccessor.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.util.List;
-
-/**
- * {@link Accessor} implementation that allows to access a {@link List} by
- * index. “list.size” will return the size of the list, “list.isEmpty” will
- * return the result of {@link List#isEmpty()}, and “list.0” will return the
- * first element of the list, “list.1” the second, and so on.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ListAccessor implements Accessor {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Object get(DataProvider dataProvider, Object object, String member) {
-		List<?> list = (List<?>) object;
-		if ("size".equals(member)) {
-			return list.size();
-		} else if ("isEmpty".equals(member)) {
-			return list.isEmpty();
-		}
-		int index = -1;
-		try {
-			index = Integer.parseInt(member);
-		} catch (NumberFormatException nfe1) {
-			/* ignore. */
-		}
-		if ((index > -1) && (index < list.size())) {
-			return list.get(index);
-		}
-		return null;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/LoopPart.java b/alien/src/net/pterodactylus/util/template/LoopPart.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/LoopPart.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * utils - LoopPart.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.io.Writer;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * {@link Part} implementation that loops over a {@link Collection}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-class LoopPart extends ContainerPart {
-
-	/** Accessor for {@link LoopStructure}s. */
-	@SuppressWarnings("synthetic-access")
-	private final Accessor LOOP_STRUCTURE_ACCESSOR = new LoopStructureAccessor();
-
-	/** The name of the collection to loop over. */
-	private final String collectionName;
-
-	/** The name under which to store the current item. */
-	private final String itemName;
-
-	/** The name under which to store the loop structure. */
-	private final String loopName;
-
-	/**
-	 * Creates a new loop part.
-	 *
-	 * @param collectionName
-	 *            The name of the collection
-	 * @param itemName
-	 *            The name under which to store the current item
-	 */
-	public LoopPart(String collectionName, String itemName) {
-		this(collectionName, itemName, "loop");
-	}
-
-	/**
-	 * Creates a new loop part.
-	 *
-	 * @param collectionName
-	 *            The name of the collection
-	 * @param itemName
-	 *            The name under which to store the current item
-	 * @param loopName
-	 *            The name of the loop
-	 */
-	public LoopPart(String collectionName, String itemName, String loopName) {
-		this.collectionName = collectionName;
-		this.itemName = itemName;
-		this.loopName = loopName;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void render(DataProvider dataProvider, Writer writer) throws TemplateException {
-		Collection<?> collection = (Collection<?>) dataProvider.getData(collectionName);
-		if ((collection == null) || collection.isEmpty()) {
-			return;
-		}
-		LoopStructure loopStructure = new LoopStructure(collection.size());
-		Map<String, Object> overrideObjects = new HashMap<String, Object>();
-		overrideObjects.put(loopName, loopStructure);
-		for (Object object : collection) {
-			overrideObjects.put(itemName, object);
-			DataProvider loopDataProvider = new OverrideDataProvider(dataProvider, overrideObjects);
-			loopDataProvider.addAccessor(LoopStructure.class, LOOP_STRUCTURE_ACCESSOR);
-			for (Part part : parts) {
-				part.render(loopDataProvider, writer);
-			}
-			loopStructure.incCount();
-		}
-	}
-
-	/**
-	 * Container for information about a loop.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	private static class LoopStructure {
-
-		/** The size of the loop. */
-		private final int size;
-
-		/** The current counter of the loop. */
-		private int count;
-
-		/**
-		 * Creates a new loop structure for a loop with the given size.
-		 *
-		 * @param size
-		 *            The size of the loop
-		 */
-		public LoopStructure(int size) {
-			this.size = size;
-		}
-
-		/**
-		 * Returns the size of the loop.
-		 *
-		 * @return The size of the loop
-		 */
-		public int getSize() {
-			return size;
-		}
-
-		/**
-		 * Returns the current counter of the loop.
-		 *
-		 * @return The current counter of the loop, in the range from {@code 0}
-		 *         to {@link #getSize() getSize() - 1}
-		 */
-		public int getCount() {
-			return count;
-		}
-
-		/**
-		 * Increments the current counter of the loop.
-		 */
-		public void incCount() {
-			++count;
-		}
-
-		/**
-		 * Returns whether the current iteration if the first one.
-		 *
-		 * @return {@code true} if the curren iteration is the first one,
-		 *         {@code false} otherwise
-		 */
-		public boolean isFirst() {
-			return count == 0;
-		}
-
-		/**
-		 * Returns whether the current iteration if the last one.
-		 *
-		 * @return {@code true} if the curren iteration is the last one, {@code
-		 *         false} otherwise
-		 */
-		public boolean isLast() {
-			return count == (size - 1);
-		}
-
-		/**
-		 * Returns whether the current loop count is odd, i.e. not divisible by
-		 * {@code 2}.
-		 *
-		 * @return {@code true} if the loop count is odd, {@code false}
-		 *         otherwise
-		 */
-		public boolean isOdd() {
-			return (count & 1) == 1;
-		}
-
-		/**
-		 * Returns whether the current loop count is even, i.e. divisible by
-		 * {@code 2}.
-		 *
-		 * @return {@code true} if the loop count is even, {@code false}
-		 *         otherwise
-		 */
-		public boolean isEven() {
-			return (count & 1) == 0;
-		}
-
-	}
-
-	/**
-	 * {@link Accessor} implementation that handles a {@link LoopStructure},
-	 * allowing access via the members “size”, “count”, “first”, and “last”.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	private static class LoopStructureAccessor implements Accessor {
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public Object get(DataProvider dataProvider, Object object, String member) {
-			LoopStructure loopStructure = (LoopStructure) object;
-			if ("size".equals(member)) {
-				return loopStructure.getSize();
-			} else if ("count".equals(member)) {
-				return loopStructure.getCount();
-			} else if ("first".equals(member)) {
-				return loopStructure.isFirst();
-			} else if ("last".equals(member)) {
-				return loopStructure.isLast();
-			} else if ("odd".equals(member)) {
-				return loopStructure.isOdd();
-			} else if ("even".equals(member)) {
-				return loopStructure.isEven();
-			}
-			return null;
-		}
-
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/MatchFilter.java b/alien/src/net/pterodactylus/util/template/MatchFilter.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/MatchFilter.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * utils - MatchFilter.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.util.Map;
-
-/**
- * {@link Filter} implementation that compares (for
- * {@link Object#equals(Object) equality}) the data either with a {@link String}
- * (given as parameter “value”) or an object from the {@link DataProvider}
- * (whose name is given as parameter “key”).
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class MatchFilter implements Filter {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Object format(DataProvider dataProvider, Object data, Map<String, String> parameters) {
-		String key = parameters.get("key");
-		Object value = parameters.get("value");
-		if (value == null) {
-			value = dataProvider.getData(key);
-		}
-		if (value instanceof String) {
-			return value.equals(String.valueOf(data));
-		}
-		return (value != null) ? value.equals(data) : (data == null);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/MultipleDataProvider.java b/alien/src/net/pterodactylus/util/template/MultipleDataProvider.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/MultipleDataProvider.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * utils - MultipleDataProvider.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.StringTokenizer;
-
-/**
- * {@link DataProvider} implementation that can get its data from multiple other
- * {@link DataProvider}s.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class MultipleDataProvider extends DataProvider {
-
-	/** The source data providers. */
-	private final List<DataProvider> dataProviders = new ArrayList<DataProvider>();
-
-	/** The data stores. */
-	private final MultipleDataStore dataStore;
-
-	/**
-	 * Creates a new multiple data provider.
-	 *
-	 * @param dataProviders
-	 *            The source data providers
-	 */
-	public MultipleDataProvider(DataProvider... dataProviders) {
-		this.dataProviders.addAll(Arrays.asList(dataProviders));
-		List<DataStore> dataStores = new ArrayList<DataStore>();
-		for (DataProvider dataProvider : dataProviders) {
-			dataStores.add(dataProvider.getDataStore());
-		}
-		this.dataStore = new MultipleDataStore(dataStores);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Object getData(String name) throws TemplateException {
-		if (name.indexOf('.') == -1) {
-			for (DataProvider dataProvider : dataProviders) {
-				Object data = dataProvider.getDataStore().get(name);
-				if (data != null) {
-					return data;
-				}
-			}
-			return null;
-		}
-		StringTokenizer nameTokens = new StringTokenizer(name, ".");
-		Object object = null;
-		while (nameTokens.hasMoreTokens()) {
-			String nameToken = nameTokens.nextToken();
-			if (object == null) {
-				for (DataProvider dataProvider : dataProviders) {
-					object = dataProvider.getDataStore().get(nameToken);
-					if (object != null) {
-						break;
-					}
-				}
-			} else {
-				Accessor accessor = null;
-				for (DataProvider dataProvider : dataProviders) {
-					accessor = dataProvider.findAccessor(object.getClass());
-					if (accessor != null) {
-						break;
-					}
-				}
-				if (accessor != null) {
-					object = accessor.get(this, object, nameToken);
-				} else {
-					throw new TemplateException("no accessor found for " + object.getClass());
-				}
-			}
-			if (object == null) {
-				return null;
-			}
-		}
-		return object;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	protected DataStore getDataStore() {
-		return dataStore;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void setData(String name, Object data) {
-		for (DataProvider dataProvider : dataProviders) {
-			dataProvider.setData(name, data);
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	protected Accessor findAccessor(Class<?> clazz) {
-		for (DataProvider dataProvider : dataProviders) {
-			Accessor accessor = dataProvider.findAccessor(clazz);
-			if (accessor != null) {
-				return accessor;
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * A {@link DataStore} implementation that is backed by multiple other
-	 * {@link DataStore}s.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	private static class MultipleDataStore implements DataStore {
-
-		/** The backing data stores. */
-		private List<DataStore> dataStores = new ArrayList<DataStore>();
-
-		/**
-		 * Creates a new multiple data store.
-		 *
-		 * @param dataStores
-		 *            The backing data stores
-		 */
-		public MultipleDataStore(List<DataStore> dataStores) {
-			this.dataStores.addAll(dataStores);
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public Object get(String name) {
-			for (DataStore dataStore : dataStores) {
-				Object data = dataStore.get(name);
-				if (data != null) {
-					return data;
-				}
-			}
-			return null;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public void set(String name, Object data) {
-			for (DataStore dataStore : dataStores) {
-				dataStore.set(name, data);
-			}
-		}
-
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/OverrideDataProvider.java b/alien/src/net/pterodactylus/util/template/OverrideDataProvider.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/OverrideDataProvider.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * utils - OverrideDataProvider.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * {@link DataProvider} implementation that uses a parent data provider but can
- * override objects.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-class OverrideDataProvider extends DataProvider {
-
-	/** The parent data provider. */
-	private final DataProvider parentDataProvider;
-
-	/** Accessors. */
-	private final Map<Class<?>, Accessor> classAccessors = new HashMap<Class<?>, Accessor>();
-
-	/**
-	 * Creates a new override data provider.
-	 *
-	 * @param parentDataProvider
-	 *            The parent data provider
-	 * @param name
-	 *            The name of the object to override
-	 * @param object
-	 *            The object
-	 */
-	public OverrideDataProvider(DataProvider parentDataProvider, String name, Object object) {
-		super(new OverrideDataStore(parentDataProvider, name, object));
-		this.parentDataProvider = parentDataProvider;
-	}
-
-	/**
-	 * Creates a new override data provider.
-	 *
-	 * @param parentDataProvider
-	 *            The parent data provider
-	 * @param overrideObjects
-	 *            The override objects
-	 */
-	public OverrideDataProvider(DataProvider parentDataProvider, Map<String, Object> overrideObjects) {
-		super(new OverrideDataStore(parentDataProvider, overrideObjects));
-		this.parentDataProvider = parentDataProvider;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void addAccessor(Class<?> clazz, Accessor accessor) {
-		classAccessors.put(clazz, accessor);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	protected Accessor findAccessor(Class<?> clazz) {
-		if (classAccessors.containsKey(clazz)) {
-			return classAccessors.get(clazz);
-		}
-		for (Class<?> interfaceClass : clazz.getInterfaces()) {
-			if (classAccessors.containsKey(interfaceClass)) {
-				return classAccessors.get(interfaceClass);
-			}
-		}
-		Class<?> classToCheck = clazz.getSuperclass();
-		while (classToCheck != null) {
-			if (classAccessors.containsKey(classToCheck)) {
-				return classAccessors.get(classToCheck);
-			}
-			classToCheck = classToCheck.getSuperclass();
-		}
-		return parentDataProvider.findAccessor(clazz);
-	}
-
-	/**
-	 * {@link DataStore} implementation that can override objects and redirects
-	 * requests for not-overridden objects to a parent {@link DataProvider}.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	private static class OverrideDataStore implements DataStore {
-
-		/** The parent data provider. */
-		private final DataProvider parentDataProvider;
-
-		/** The store containing the overridden objects. */
-		private final Map<String, Object> overrideDataStore = new HashMap<String, Object>();
-
-		/**
-		 * Creates a new overriding data store.
-		 *
-		 * @param parentDataProvider
-		 *            The parent data provider
-		 * @param name
-		 *            The key of the object to override
-		 * @param data
-		 *            The object to override
-		 */
-		public OverrideDataStore(DataProvider parentDataProvider, String name, Object data) {
-			this.parentDataProvider = parentDataProvider;
-			overrideDataStore.put(name, data);
-		}
-
-		/**
-		 * Creates a new overriding data store.
-		 *
-		 * @param parentDataProvider
-		 *            The parent data provider
-		 * @param overrideDataStore
-		 *            {@link Map} containing all overriding objects
-		 */
-		public OverrideDataStore(DataProvider parentDataProvider, Map<String, Object> overrideDataStore) {
-			this.parentDataProvider = parentDataProvider;
-			this.overrideDataStore.putAll(overrideDataStore);
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public Object get(String name) {
-			if (overrideDataStore.containsKey(name)) {
-				return overrideDataStore.get(name);
-			}
-			return parentDataProvider.getData(name);
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public void set(String name, Object data) {
-			parentDataProvider.setData(name, data);
-		}
-
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/PaginationPlugin.java b/alien/src/net/pterodactylus/util/template/PaginationPlugin.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/PaginationPlugin.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * utils - PaginationPlugin.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import net.pterodactylus.util.collection.Pagination;
-
-/**
- * {@link Plugin} implementation that takes care of paginating a {@link List} of
- * items (parameter “list”).
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class PaginationPlugin implements Plugin {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void execute(DataProvider dataProvider, Map<String, String> parameters) {
-		String listKey = parameters.get("list");
-		String pageSizeString = parameters.get("pagesize");
-		String pageKey = parameters.get("page");
-		String paginationKey = parameters.get("key");
-		if (pageKey == null) {
-			pageKey = "page";
-		}
-		if (paginationKey == null) {
-			paginationKey = "pagination";
-		}
-		String pageString = String.valueOf(dataProvider.getData(pageKey));
-		int page = 0;
-		try {
-			page = Integer.parseInt(pageString);
-		} catch (NumberFormatException nfe1) {
-			/* ignore. */
-		}
-		int pageSize = 25;
-		try {
-			pageSize = Integer.parseInt(pageSizeString);
-		} catch (NumberFormatException nfe1) {
-			/* ignore. */
-		}
-		List<?> list = (List<?>) dataProvider.getData(listKey);
-		@SuppressWarnings({ "unchecked", "rawtypes" })
-		Pagination<?> pagination = new Pagination((list == null) ? Collections.emptyList() : list, pageSize).setPage(page);
-		dataProvider.setData(paginationKey, pagination);
-	}
-}
diff --git a/alien/src/net/pterodactylus/util/template/Part.java b/alien/src/net/pterodactylus/util/template/Part.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/Part.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * utils - Part.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.io.Writer;
-
-/**
- * Interface for a part of a template that can be rendered without further
- * parsing.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-abstract class Part {
-
-	/**
-	 * Renders this part.
-	 *
-	 * @param dataProvider
-	 *            The data provider for the part
-	 * @param writer
-	 *            The writer to render the part to
-	 * @throws TemplateException
-	 *             if a template variable can not be parsed
-	 */
-	public abstract void render(DataProvider dataProvider, Writer writer) throws TemplateException;
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/Plugin.java b/alien/src/net/pterodactylus/util/template/Plugin.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/Plugin.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * utils - Plugin.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.util.Map;
-
-/**
- * Defines a template plugin. A plugin can be called just like the built-in
- * functions, e.g. “<%plugin>”. It also can have parameters just like a filter,
- * e.g. “<%plugin parameter=value>”.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface Plugin {
-
-	/**
-	 * Executes the plugin.
-	 *
-	 * @param dataProvider
-	 *            The data provider
-	 * @param parameters
-	 *            The plugin parameters
-	 */
-	public void execute(DataProvider dataProvider, Map<String, String> parameters);
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/PluginPart.java b/alien/src/net/pterodactylus/util/template/PluginPart.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/PluginPart.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * utils - PluginPart.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.io.Writer;
-import java.util.Map;
-
-/**
- * {@link Part} implementation that executes a {@link Plugin}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-class PluginPart extends Part {
-
-	/** The plugin to execute. */
-	private final Plugin plugin;
-
-	/** The plugin parameters. */
-	private final Map<String, String> pluginParameters;
-
-	/**
-	 * Creates a new plugin part.
-	 *
-	 * @param plugin
-	 *            The plugin to execute
-	 * @param pluginParameters
-	 *            The plugin parameters
-	 */
-	public PluginPart(Plugin plugin, Map<String, String> pluginParameters) {
-		this.plugin = plugin;
-		this.pluginParameters = pluginParameters;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void render(DataProvider dataProvider, Writer writer) throws TemplateException {
-		plugin.execute(dataProvider, pluginParameters);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/ReflectionAccessor.java b/alien/src/net/pterodactylus/util/template/ReflectionAccessor.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/ReflectionAccessor.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * utils - ReflectionAccessor.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * {@link Accessor} implementation that checks the object for a method that
- * looks like a getter for the requested member name. If “object.data” is
- * requested, the methods “getData()” and “isData()” are checked,
- * “object.realName” would search for the methods “getRealName()” and
- * “isRealName()”.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ReflectionAccessor implements Accessor {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Object get(DataProvider dataProvider, Object object, String member) {
-		Method method = null;
-		String methodName = member.substring(0, 1).toUpperCase() + member.substring(1);
-		try {
-			method = object.getClass().getMethod("get" + methodName);
-		} catch (SecurityException se1) {
-			/* TODO - logging. */
-		} catch (NoSuchMethodException nsme1) {
-			/* swallow, method just doesn’t exist. */
-		}
-		if (method == null) {
-			try {
-				method = object.getClass().getMethod("is" + methodName);
-			} catch (SecurityException e) {
-				/* TODO - logging. */
-			} catch (NoSuchMethodException e) {
-				/* swallow, method just doesn’t exist. */
-			}
-		}
-		if (method == null) {
-			try {
-				method = object.getClass().getMethod(member);
-			} catch (SecurityException e) {
-				/* TODO - logging. */
-			} catch (NoSuchMethodException e) {
-				/* swallow, method just doesn’t exist. */
-			}
-		}
-		if (method != null) {
-			try {
-				return method.invoke(object);
-			} catch (IllegalArgumentException iae1) {
-				/* TODO - logging. */
-			} catch (IllegalAccessException iae1) {
-				/* TODO - logging. */
-			} catch (InvocationTargetException ite1) {
-				/* TODO - logging. */
-			}
-		}
-		return null;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/ReplaceFilter.java b/alien/src/net/pterodactylus/util/template/ReplaceFilter.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/ReplaceFilter.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * utils - ReplaceFilter.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.util.Map;
-
-/**
- * {@link Filter} implementation that replaces parts of a value.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class ReplaceFilter implements Filter {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String format(DataProvider dataProvider, Object data, Map<String, String> parameters) {
-		String input = String.valueOf(data);
-		String needle = parameters.get("needle");
-		String replacementKey = parameters.get("replacementKey");
-		String replacement = parameters.get("replacement");
-		if (replacement == null) {
-			replacement = String.valueOf(dataProvider.getData(replacementKey));
-		}
-		return input.replace(needle, replacement);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/StoreFilter.java b/alien/src/net/pterodactylus/util/template/StoreFilter.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/StoreFilter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * utils - StoreFilter.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.util.Map;
-
-/**
- * Filter that temporarily stores the output of the chain in a
- * {@link ThreadLocal}. It is used in conjunction with {@link InsertFilter}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class StoreFilter implements Filter {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String format(DataProvider dataProvider, Object data, Map<String, String> parameters) {
-		String key = parameters.get("key");
-		dataProvider.setData(key, data);
-		return "";
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/Template.java b/alien/src/net/pterodactylus/util/template/Template.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/Template.java
+++ /dev/null
@@ -1,649 +0,0 @@
-/*
- * utils - TemplateImpl.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-
-import net.pterodactylus.util.template.ConditionalPart.AndCondition;
-import net.pterodactylus.util.template.ConditionalPart.Condition;
-import net.pterodactylus.util.template.ConditionalPart.DataCondition;
-import net.pterodactylus.util.template.ConditionalPart.DataTextCondition;
-import net.pterodactylus.util.template.ConditionalPart.FilterCondition;
-import net.pterodactylus.util.template.ConditionalPart.FilterTextCondition;
-import net.pterodactylus.util.template.ConditionalPart.NotCondition;
-import net.pterodactylus.util.template.ConditionalPart.NullDataCondition;
-import net.pterodactylus.util.template.ConditionalPart.OrCondition;
-
-/**
- * Simple template system that is geared towards easy of use and high
- * performance.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Template {
-
-	/** The template’s default data store. */
-	private DataProvider dataProvider = new DataProvider();
-
-	/** The template’s default template provider. */
-	private TemplateProvider templateProvider = new DataTemplateProvider(dataProvider);
-
-	/** The input of the template. */
-	private final Reader input;
-
-	/** The parsed template. */
-	private Part parsedTemplate;
-
-	/** Filters for the template. */
-	private final Map<String, Filter> filters = new HashMap<String, Filter>();
-
-	/** Plugins for the template. */
-	private final Map<String, Plugin> plugins = new HashMap<String, Plugin>();
-
-	/**
-	 * Creates a new template from the given input.
-	 *
-	 * @param input
-	 *            The template’s input source
-	 */
-	public Template(Reader input) {
-		this.input = input;
-	}
-
-	/**
-	 * Returns the object with the given name from the data provider.
-	 *
-	 * @param name
-	 *            The name of the object
-	 * @return The object, or {@code null} if no object could be found
-	 */
-	public Object get(String name) {
-		return dataProvider.getData(name);
-	}
-
-	/**
-	 * Sets the template object with the given name.
-	 *
-	 * @param name
-	 *            The name of the template object
-	 * @param object
-	 *            The object to store in the template
-	 */
-	public void set(String name, Object object) {
-		dataProvider.setData(name, object);
-	}
-
-	/**
-	 * Adds an accessor to the underlying {@link DataStore}.
-	 *
-	 * @param clazz
-	 *            The class for which to add an accessor
-	 * @param accessor
-	 *            The accessor to add
-	 */
-	public void addAccessor(Class<?> clazz, Accessor accessor) {
-		dataProvider.addAccessor(clazz, accessor);
-	}
-
-	/**
-	 * Adds a filter with the given name.
-	 *
-	 * @param name
-	 *            The name of the filter
-	 * @param filter
-	 *            The filter
-	 */
-	public void addFilter(String name, Filter filter) {
-		filters.put(name, filter);
-	}
-
-	/**
-	 * Adds a plugin with the given name.
-	 *
-	 * @param name
-	 *            The name of the plugin
-	 * @param plugin
-	 *            The plugin to add
-	 */
-	public void addPlugin(String name, Plugin plugin) {
-		plugins.put(name, plugin);
-	}
-
-	/**
-	 * Sets a custom template provider for this template.
-	 *
-	 * @param templateProvider
-	 *            The new template provider
-	 */
-	public void setTemplateProvider(TemplateProvider templateProvider) {
-		this.templateProvider = templateProvider;
-	}
-
-	/**
-	 * Exposes the data provider, e.g. for {@link TemplatePart}.
-	 *
-	 * @return The template’s data provider
-	 */
-	DataProvider getDataProvider() {
-		return dataProvider;
-	}
-
-	/**
-	 * Parses the input of the template if it wasn’t already parsed.
-	 *
-	 * @throws TemplateException
-	 *             if the template can not be parsed
-	 */
-	public synchronized void parse() throws TemplateException {
-		if (parsedTemplate == null) {
-			parsedTemplate = extractParts();
-		}
-	}
-
-	/**
-	 * Renders the template to the given writer.
-	 *
-	 * @param writer
-	 *            The write to render the template to
-	 * @throws TemplateException
-	 *             if the template can not be parsed
-	 */
-	public synchronized void render(Writer writer) throws TemplateException {
-		render(dataProvider, writer);
-	}
-
-	/**
-	 * Renders the template to the given writer.
-	 *
-	 * @param dataProvider
-	 *            The data provider for template variables
-	 * @param writer
-	 *            The write to render the template to
-	 * @throws TemplateException
-	 *             if the template can not be parsed
-	 */
-	public synchronized void render(DataProvider dataProvider, Writer writer) throws TemplateException {
-		parse();
-		parsedTemplate.render(dataProvider, writer);
-	}
-
-	//
-	// PRIVATE METHODS
-	//
-
-	/**
-	 * Parses the template and creates {@link Part}s of the input.
-	 *
-	 * @return The list of parts created from the template’s {@link #input}
-	 * @throws TemplateException
-	 *             if the template can not be parsed correctly
-	 */
-	private Part extractParts() throws TemplateException {
-		BufferedReader bufferedInputReader;
-		if (input instanceof BufferedReader) {
-			bufferedInputReader = (BufferedReader) input;
-		} else {
-			bufferedInputReader = new BufferedReader(input);
-		}
-		Stack<String> commandStack = new Stack<String>();
-		Stack<ContainerPart> partsStack = new Stack<ContainerPart>();
-		Stack<String> lastCollectionName = new Stack<String>();
-		Stack<String> lastLoopName = new Stack<String>();
-		Stack<Condition> lastCondition = new Stack<Condition>();
-		Stack<List<Condition>> lastConditions = new Stack<List<Condition>>();
-		Stack<String> lastIfCommand = new Stack<String>();
-		ContainerPart parts = new ContainerPart();
-		StringBuilder currentTextPart = new StringBuilder();
-		boolean gotLeftAngleBracket = false;
-		boolean inAngleBracket = false;
-		boolean inSingleQuotes = false;
-		boolean inDoubleQuotes = false;
-		while (true) {
-			int nextCharacter;
-			try {
-				nextCharacter = bufferedInputReader.read();
-			} catch (IOException ioe1) {
-				throw new TemplateException("Can not read template.", ioe1);
-			}
-			if (nextCharacter == -1) {
-				break;
-			}
-			if (inAngleBracket) {
-				if (inSingleQuotes) {
-					if (nextCharacter == '\'') {
-						inSingleQuotes = false;
-					}
-					currentTextPart.append((char) nextCharacter);
-				} else if (inDoubleQuotes) {
-					if (nextCharacter == '"') {
-						inDoubleQuotes = false;
-					}
-					currentTextPart.append((char) nextCharacter);
-				} else if (nextCharacter == '\'') {
-					inSingleQuotes = true;
-					currentTextPart.append((char) nextCharacter);
-				} else if (nextCharacter == '"') {
-					inDoubleQuotes = true;
-					currentTextPart.append((char) nextCharacter);
-				} else if (nextCharacter == '>') {
-					inAngleBracket = false;
-					String tagContent = currentTextPart.toString().trim();
-					currentTextPart.setLength(0);
-					Iterator<String> tokens = parseTag(tagContent).iterator();
-					if (!tokens.hasNext()) {
-						throw new TemplateException("empty tag found");
-					}
-					String function = tokens.next();
-					if (function.startsWith("/")) {
-						String lastFunction = commandStack.pop();
-						if (!("/" + lastFunction).equals(function)) {
-							throw new TemplateException("unbalanced template, /" + lastFunction + " expected, " + function + " found");
-						}
-						if (lastFunction.equals("foreach")) {
-							ContainerPart innerParts = parts;
-							parts = partsStack.pop();
-							lastCollectionName.pop();
-							lastLoopName.pop();
-							parts.add(innerParts);
-						} else if (lastFunction.equals("first") || lastFunction.equals("notfirst") || lastFunction.equals("last") || lastFunction.equals("notlast") || lastFunction.equals("odd") || lastFunction.equals("even")) {
-							ContainerPart innerParts = parts;
-							parts = partsStack.pop();
-							parts.add(innerParts);
-						} else if (lastFunction.equals("if")) {
-							ContainerPart innerParts = parts;
-							parts = partsStack.pop();
-							lastCondition.pop();
-							lastConditions.pop();
-							parts.add(innerParts);
-							lastIfCommand.pop();
-						}
-					} else if (function.equals("foreach")) {
-						if (!tokens.hasNext()) {
-							throw new TemplateException("foreach requires at least one parameter");
-						}
-						String collectionName = tokens.next();
-						String itemName = null;
-						if (tokens.hasNext()) {
-							itemName = tokens.next();
-						}
-						String loopName = "loop";
-						if (tokens.hasNext()) {
-							loopName = tokens.next();
-						}
-						partsStack.push(parts);
-						parts = new LoopPart(collectionName, itemName, loopName);
-						commandStack.push("foreach");
-						lastCollectionName.push(collectionName);
-						lastLoopName.push(loopName);
-					} else if (function.equals("foreachelse")) {
-						if (!"foreach".equals(commandStack.peek())) {
-							throw new TemplateException("foreachelse is only allowed in foreach");
-						}
-						partsStack.peek().add(parts);
-						parts = new EmptyLoopPart(lastCollectionName.peek());
-					} else if (function.equals("first")) {
-						if (!"foreach".equals(commandStack.peek())) {
-							throw new TemplateException("first is only allowed in foreach");
-						}
-						partsStack.push(parts);
-						final String loopName = lastLoopName.peek();
-						parts = new ConditionalPart(new ConditionalPart.DataCondition(loopName + ".first"));
-						commandStack.push("first");
-					} else if (function.equals("notfirst")) {
-						if (!"foreach".equals(commandStack.peek())) {
-							throw new TemplateException("notfirst is only allowed in foreach");
-						}
-						partsStack.push(parts);
-						final String loopName = lastLoopName.peek();
-						parts = new ConditionalPart(new ConditionalPart.DataCondition(loopName + ".first", true));
-						commandStack.push("notfirst");
-					} else if (function.equals("last")) {
-						if (!"foreach".equals(commandStack.peek())) {
-							throw new TemplateException("last is only allowed in foreach");
-						}
-						partsStack.push(parts);
-						final String loopName = lastLoopName.peek();
-						parts = new ConditionalPart(new ConditionalPart.DataCondition(loopName + ".last"));
-						commandStack.push("last");
-					} else if (function.equals("notlast")) {
-						if (!"foreach".equals(commandStack.peek())) {
-							throw new TemplateException("notlast is only allowed in foreach");
-						}
-						partsStack.push(parts);
-						final String loopName = lastLoopName.peek();
-						parts = new ConditionalPart(new ConditionalPart.DataCondition(loopName + ".last", true));
-						commandStack.push("notlast");
-					} else if (function.equals("odd")) {
-						if (!"foreach".equals(commandStack.peek())) {
-							throw new TemplateException("odd is only allowed in foreach");
-						}
-						partsStack.push(parts);
-						final String loopName = lastLoopName.peek();
-						parts = new ConditionalPart(new ConditionalPart.DataCondition(loopName + ".odd"));
-						commandStack.push("odd");
-					} else if (function.equals("even")) {
-						if (!"foreach".equals(commandStack.peek())) {
-							throw new TemplateException("even is only allowed in foreach");
-						}
-						partsStack.push(parts);
-						final String loopName = lastLoopName.peek();
-						parts = new ConditionalPart(new ConditionalPart.DataCondition(loopName + ".even"));
-						commandStack.push("even");
-					} else if (function.equals("if") || function.equals("ifnull")) {
-						if (!tokens.hasNext()) {
-							throw new TemplateException("if requires one or two parameters");
-						}
-						String itemName = tokens.next();
-						boolean checkForNull = function.equals("ifnull");
-						boolean invert = false;
-						if (itemName.equals("!")) {
-							invert = true;
-							if (!tokens.hasNext()) {
-								throw new TemplateException("if ! requires one parameter");
-							}
-							itemName = tokens.next();
-						} else {
-							if (itemName.startsWith("!")) {
-								invert = true;
-								itemName = itemName.substring(1);
-							}
-						}
-						boolean directText = false;
-						if (itemName.startsWith("=")) {
-							if (checkForNull) {
-								throw new TemplateException("direct text ('=') with ifnull is not allowed");
-							}
-							itemName = itemName.substring(1);
-							directText = true;
-						}
-						Map<Filter, Map<String, String>> allFilterParameters = parseFilters(tokens);
-						partsStack.push(parts);
-						Condition condition = allFilterParameters.isEmpty() ? (checkForNull ? new NullDataCondition(itemName, invert) : (directText ? new DataTextCondition(itemName, invert) : new DataCondition(itemName, invert))) : (directText ? new FilterTextCondition(itemName, allFilterParameters.keySet(), allFilterParameters, invert) : new FilterCondition(itemName, allFilterParameters.keySet(), allFilterParameters, invert));
-						parts = new ConditionalPart(condition);
-						commandStack.push("if");
-						lastCondition.push(condition);
-						lastConditions.push(new ArrayList<Condition>(Arrays.asList(condition)));
-						lastIfCommand.push("if");
-					} else if (function.equals("else")) {
-						if (!"if".equals(commandStack.peek())) {
-							throw new TemplateException("else is only allowed in if");
-						}
-						if (!"if".equals(lastIfCommand.peek()) && !"elseif".equals(lastIfCommand.peek())) {
-							throw new TemplateException("else may only follow if or elseif");
-						}
-						partsStack.peek().add(parts);
-						Condition condition = new NotCondition(new OrCondition(lastConditions.peek()));
-						parts = new ConditionalPart(condition);
-						lastIfCommand.pop();
-						lastIfCommand.push("else");
-					} else if (function.equals("elseif") || function.equals("elseifnull")) {
-						if (!"if".equals(commandStack.peek())) {
-							throw new TemplateException("elseif is only allowed in if");
-						}
-						if (!"if".equals(lastIfCommand.peek()) && !"elseif".equals(lastIfCommand.peek())) {
-							throw new TemplateException("elseif is only allowed after if or elseif");
-						}
-						if (!tokens.hasNext()) {
-							throw new TemplateException("elseif requires one or two parameters");
-						}
-						String itemName = tokens.next();
-						boolean checkForNull = function.equals("elseifnull");
-						boolean invert = false;
-						if (itemName.equals("!")) {
-							invert = true;
-							if (!tokens.hasNext()) {
-								throw new TemplateException("if ! requires one parameter");
-							}
-							itemName = tokens.next();
-						} else {
-							if (itemName.startsWith("!")) {
-								invert = true;
-								itemName = itemName.substring(1);
-							}
-						}
-						Map<Filter, Map<String, String>> allFilterParameters = parseFilters(tokens);
-						partsStack.peek().add(parts);
-						Condition condition = new AndCondition(new NotCondition(lastCondition.pop()), allFilterParameters.isEmpty() ? (checkForNull ? new NullDataCondition(itemName, invert) : new DataCondition(itemName, invert)) : new FilterCondition(itemName, allFilterParameters.keySet(), allFilterParameters, invert));
-						parts = new ConditionalPart(condition);
-						lastCondition.push(condition);
-						lastConditions.peek().add(condition);
-						lastIfCommand.pop();
-						lastIfCommand.push("elseif");
-					} else if (function.equals("include")) {
-						if (!tokens.hasNext()) {
-							throw new TemplateException("include requires one parameter");
-						}
-						String templateName = tokens.next();
-						Template includedTemplate = templateProvider.getTemplate(templateName);
-						if (includedTemplate != null) {
-							parts.add(new TemplatePart(includedTemplate));
-						}
-					} else if (plugins.containsKey(function)) {
-						Map<String, String> pluginParameters = parseParameters(tokens);
-						parts.add(new PluginPart(plugins.get(function), pluginParameters));
-					} else {
-						boolean directText = false;
-						String itemName = function;
-						if (function.equals("=")) {
-							if (!tokens.hasNext()) {
-								throw new TemplateException("empty tag found");
-							}
-							itemName = tokens.next();
-							directText = true;
-						} else if (function.startsWith("=")) {
-							itemName = function.substring(1);
-							directText = true;
-						}
-						Map<Filter, Map<String, String>> allFilterParameters = parseFilters(tokens);
-						if (directText) {
-							parts.add(new FilteredTextPart(itemName, allFilterParameters.keySet(), allFilterParameters));
-						} else {
-							parts.add(new FilteredPart(itemName, allFilterParameters.keySet(), allFilterParameters));
-						}
-					}
-				} else {
-					currentTextPart.append((char) nextCharacter);
-				}
-				continue;
-			}
-			if (gotLeftAngleBracket) {
-				if (nextCharacter == '%') {
-					inAngleBracket = true;
-					if (currentTextPart.length() > 0) {
-						parts.add(new TextPart(currentTextPart.toString()));
-						currentTextPart.setLength(0);
-					}
-				} else {
-					currentTextPart.append('<').append((char) nextCharacter);
-				}
-				gotLeftAngleBracket = false;
-				continue;
-			}
-			if (nextCharacter == '<') {
-				gotLeftAngleBracket = true;
-				continue;
-			}
-			currentTextPart.append((char) nextCharacter);
-		}
-		if (currentTextPart.length() > 0) {
-			parts.add(new TextPart(currentTextPart.toString()));
-		}
-		if (!partsStack.isEmpty()) {
-			throw new TemplateException("Unbalanced template.");
-		}
-		return parts;
-	}
-
-	/**
-	 * Parses filters from the rest of the tokens.
-	 *
-	 * @param tokens
-	 *            The tokens to parse
-	 * @return The parsed filters
-	 */
-	private Map<Filter, Map<String, String>> parseFilters(Iterator<String> tokens) {
-		Map<Filter, Map<String, String>> allFilterParameters = new LinkedHashMap<Filter, Map<String, String>>();
-		if (tokens.hasNext() && (tokens.next() != null)) {
-			throw new TemplateException("expected \"|\" token");
-		}
-		while (tokens.hasNext()) {
-			String filterName = tokens.next();
-			Filter filter = filters.get(filterName);
-			if (filter == null) {
-				throw new TemplateException("unknown filter: " + filterName);
-			}
-			filter = new FilterWrapper(filter);
-			Map<String, String> filterParameters = parseParameters(tokens);
-			allFilterParameters.put(filter, filterParameters);
-		}
-		return allFilterParameters;
-	}
-
-	/**
-	 * Parses parameters from the given tokens.
-	 *
-	 * @param tokens
-	 *            The tokens to parse the parameters from
-	 * @return The parsed parameters
-	 * @throws TemplateException
-	 *             if an invalid parameter declaration is found
-	 */
-	private Map<String, String> parseParameters(Iterator<String> tokens) throws TemplateException {
-		Map<String, String> parameters = new HashMap<String, String>();
-		while (tokens.hasNext()) {
-			String parameterToken = tokens.next();
-			if (parameterToken == null) {
-				break;
-			}
-			int equals = parameterToken.indexOf('=');
-			if (equals == -1) {
-				throw new TemplateException("found parameter without \"=\" sign");
-			}
-			String key = parameterToken.substring(0, equals).trim();
-			String value = parameterToken.substring(equals + 1);
-			parameters.put(key, value);
-		}
-		return parameters;
-	}
-
-	/**
-	 * Parses the content of a tag into words, obeying syntactical rules about
-	 * separators and quotes. Separators are parsed as {@code null}.
-	 *
-	 * @param tagContent
-	 *            The content of the tag to parse
-	 * @return The parsed words
-	 */
-	static List<String> parseTag(String tagContent) {
-		List<String> expressions = new ArrayList<String>();
-		boolean inSingleQuotes = false;
-		boolean inDoubleQuotes = false;
-		boolean inBackslash = false;
-		StringBuilder currentExpression = new StringBuilder();
-		for (char c : tagContent.toCharArray()) {
-			if (inSingleQuotes) {
-				if (c == '\'') {
-					inSingleQuotes = false;
-				} else {
-					currentExpression.append(c);
-				}
-			} else if (inBackslash) {
-				currentExpression.append(c);
-				inBackslash = false;
-			} else if (inDoubleQuotes) {
-				if (c == '"') {
-					inDoubleQuotes = false;
-				} else if (c == '\\') {
-					inBackslash = true;
-				} else {
-					currentExpression.append(c);
-				}
-			} else {
-				if (c == '\'') {
-					inSingleQuotes = true;
-				} else if (c == '"') {
-					inDoubleQuotes = true;
-				} else if (c == '\\') {
-					inBackslash = true;
-				} else if (c == '|') {
-					if (currentExpression.toString().trim().length() > 0) {
-						expressions.add(currentExpression.toString());
-						currentExpression.setLength(0);
-					}
-					expressions.add(null);
-				} else {
-					if (c == ' ') {
-						if (currentExpression.length() > 0) {
-							expressions.add(currentExpression.toString());
-							currentExpression.setLength(0);
-						}
-					} else {
-						currentExpression.append(c);
-					}
-				}
-			}
-		}
-		if (currentExpression.length() > 0) {
-			expressions.add(currentExpression.toString());
-		}
-		return expressions;
-	}
-
-	/**
-	 * Wrapper around a {@link Filter} that allows adding several instances of a
-	 * filter to a single tag.
-	 *
-	 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-	 */
-	private static class FilterWrapper implements Filter {
-
-		/** The original filter. */
-		private final Filter originalFilter;
-
-		/**
-		 * Creates a new filter wrapper.
-		 *
-		 * @param originalFilter
-		 *            The filter to wrap
-		 */
-		public FilterWrapper(Filter originalFilter) {
-			this.originalFilter = originalFilter;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public Object format(DataProvider dataProvider, Object data, Map<String, String> parameters) {
-			return originalFilter.format(dataProvider, data, parameters);
-		}
-
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/TemplateException.java b/alien/src/net/pterodactylus/util/template/TemplateException.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/TemplateException.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * utils - TemplateException.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-/**
- * Exception that is thrown when a {@link Template} can not be rendered because
- * its input can not be parsed correctly, or when its template variables can not
- * be parsed or evaluated.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class TemplateException extends RuntimeException {
-
-	/**
-	 * Creates a new template exception.
-	 */
-	public TemplateException() {
-		super();
-	}
-
-	/**
-	 * Creates a new template exception.
-	 *
-	 * @param message
-	 *            The message of the exception
-	 */
-	public TemplateException(String message) {
-		super(message);
-
-	}
-
-	/**
-	 * Creates a new template exception.
-	 *
-	 * @param cause
-	 *            The cause of the exception
-	 */
-	public TemplateException(Throwable cause) {
-		super(cause);
-
-	}
-
-	/**
-	 * Creates a new template exception.
-	 *
-	 * @param message
-	 *            The message of the exception
-	 * @param cause
-	 *            The cause of the exception
-	 */
-	public TemplateException(String message, Throwable cause) {
-		super(message, cause);
-
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/TemplateFactory.java b/alien/src/net/pterodactylus/util/template/TemplateFactory.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/TemplateFactory.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * utils - TemplateFactory.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.io.Reader;
-
-/**
- * Interface for factories that can create templates with pre-defined settings,
- * e.g. a template factory that creates templates with a default
- * {@link HtmlFilter} added.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface TemplateFactory {
-
-	/**
-	 * Creates a template that is read from the given source.
-	 *
-	 * @param templateSource
-	 *            The source of the template
-	 * @return A template that is created from the given source
-	 */
-	public Template createTemplate(Reader templateSource);
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/TemplatePart.java b/alien/src/net/pterodactylus/util/template/TemplatePart.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/TemplatePart.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * utils - TemplatePart.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.io.Writer;
-
-/**
- * A {@link Part} that includes a complete {@link Template}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class TemplatePart extends Part {
-
-	/** The template to include. */
-	private final Template template;
-
-	/**
-	 * Creates a new template part.
-	 *
-	 * @param template
-	 *            The template to render
-	 */
-	public TemplatePart(Template template) {
-		this.template = template;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void render(DataProvider dataProvider, Writer writer) throws TemplateException {
-		template.render(new MultipleDataProvider(template.getDataProvider(), new UnmodifiableDataProvider(dataProvider)), writer);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/TemplateProvider.java b/alien/src/net/pterodactylus/util/template/TemplateProvider.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/TemplateProvider.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * utils - TemplateProvider.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-/**
- * A template provider is used to load templates that are included in other
- * templates when rendering a template.
- * <p>
- * Templates have a default template provider installed that tries to retrieve
- * the requsted template from the template’s data provider.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface TemplateProvider {
-
-	/**
-	 * Retrieves the template with the given name.
-	 *
-	 * @param templateName
-	 *            The name of the template
-	 * @return The template with the given name, or {@code null} if there is no
-	 *         template with the requested name
-	 */
-	public Template getTemplate(String templateName);
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/TextPart.java b/alien/src/net/pterodactylus/util/template/TextPart.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/TextPart.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * utils - TextPart.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.io.IOException;
-import java.io.Writer;
-
-/**
- * A {@link Part} that contains only text.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-class TextPart extends Part {
-
-	/** The text of the part. */
-	private final String text;
-
-	/**
-	 * Creates a new text part.
-	 *
-	 * @param text
-	 *            The text of the part
-	 */
-	public TextPart(String text) {
-		this.text = text;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void render(DataProvider dataProvider, Writer writer) throws TemplateException {
-		try {
-			writer.write(text);
-		} catch (IOException ioe1) {
-			throw new TemplateException("Can not render part.", ioe1);
-		}
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/UnmodifiableDataProvider.java b/alien/src/net/pterodactylus/util/template/UnmodifiableDataProvider.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/UnmodifiableDataProvider.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * utils - UnmodifiableDataProvider.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-/**
- * Wrapper around a {@link DataProvider} that prevents modifications.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class UnmodifiableDataProvider extends DataProvider {
-
-	/** The wrapped data provider. */
-	private final DataProvider dataProvider;
-
-	/**
-	 * Creates a new unmodifiable data provider backed by the given data
-	 * provider.
-	 *
-	 * @param dataProvider
-	 *            The data provider to wrap
-	 */
-	public UnmodifiableDataProvider(DataProvider dataProvider) {
-		this.dataProvider = dataProvider;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void addAccessor(Class<?> clazz, Accessor accessor) {
-		/* ignore. */
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	protected Accessor findAccessor(Class<?> clazz) {
-		return dataProvider.findAccessor(clazz);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	protected DataStore getDataStore() {
-		/* TODO - return an unmodifiable data store here? */
-		return dataProvider.getDataStore();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Object getData(String name) throws TemplateException {
-		return dataProvider.getData(name);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void setData(String name, Object data) {
-		/* ignore. */
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/XmlFilter.java b/alien/src/net/pterodactylus/util/template/XmlFilter.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/XmlFilter.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * utils - XmlFilter.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.template;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Filters XML by replacing double quotes characters, apostrophes, the less-than
- * character, the greater-than characters, and the ampersand by their respective
- * XML entities.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class XmlFilter implements Filter {
-
-	/** Map of defined XML entities. */
-	private static final Map<Character, String> xmlEntities = new HashMap<Character, String>();
-
-	static {
-		xmlEntities.put('&', "amp");
-		xmlEntities.put('\'', "apos");
-		xmlEntities.put('>', "gt");
-		xmlEntities.put('<', "lt");
-		xmlEntities.put('"', "quot");
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String format(DataProvider dataProvider, Object data, Map<String, String> parameters) {
-		StringBuilder xmlOutput = new StringBuilder();
-		for (char c : (data != null) ? String.valueOf(data).toCharArray() : new char[0]) {
-			if (xmlEntities.containsKey(c)) {
-				xmlOutput.append('&').append(xmlEntities.get(c)).append(';');
-				continue;
-			}
-			xmlOutput.append(c);
-		}
-		return xmlOutput.toString();
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/template/package-info.java b/alien/src/net/pterodactylus/util/template/package-info.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/template/package-info.java
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * utils - package-info.java - Copyright © 2010 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * Light-weight template system.
- *
- * <h3>Writing Templates</h3>
- *
- * <p>
- * Inserting values and control structures such as loops into a template uses
- * a syntax that is well-known by other preprocessors, such es PHP or JSPs.
- * For example:
- * </p>
- *
- * <pre>
- * <html>
- * <head>
- * <title>
- * <% title >
- * </title>
- * </head>
- * </html>
- * </pre>
- *
- * <p>
- * This will insert the value of the template variable named “title” into the
- * template.
- * </p>
- *
- * <h3>Setting Template Variables</h3>
- *
- * <p>
- * Variables in a template are set using the
- * {@link net.pterodactylus.util.template.Template#set(String, Object)} method.
- * </p>
- *
- * <pre>
- * Template template = new Template(new FileReader("template.html"));
- * template.set("variable", "value");
- * template.set("items", Arrays.asList("foo", "bar", "baz"));
- * template.render(outputWriter);
- * </pre>
- *
- * <h3>Looping Over Collections</h3>
- *
- * <p>
- * You can set the value of a template variable to an instance of
- * {@link java.util.Collection}. This allows you to iterate over the items in said collection:
- * </p>
- *
- * <pre>
- * <ul>
- * <%foreach pointCollection pointItem>
- * <li>
- * Item: <% pointItem>
- * </li>
- * <%/foreach>
- * </ul>
- * </pre>
- *
- * This will output the value of each item in the collection.
- *
- * <h3>Loop Properties</h3>
- *
- * <p>
- * Each iteration of a loop has numerous properties, such as being the first
- * iteration, or the last, or neither of them. These properties can be
- * accessed in a template.
- * </p>
- *
- * <pre>
- * <%foreach pointCollection pointItem>
- * <%first>
- * The collection contains the following items:
- * <ul>
- * <%/first>
- * <li>
- * Item: <% pointItem>
- * </li>
- * <%last>
- * </ul>
- * <%/last>
- * <%/foreach>
- * </pre>
- *
- * <p>
- * The loop properties that can be accessed in this way are: {@code first},
- * {@code last}, {@code notfirst}, {@code notlast}, {@code odd}, {@code even}.
- * </p>
- *
- * <h3>Item Properties</h3>
- *
- * <p>
- * Template variable names can specify a hierarchy: “item.index” specifies the
- * member “index” of the value of template variable “item”. The default
- * template implementation can only handle getting members of template
- * variables that contain instances of  {@link java.util.Map}; it is possible
- * to define member accessors for your own types (see below).
- * </p>
- *
- * <pre>
- * <ul>
- * <%foreach itemCollection item>
- * <li>
- * Item: <a href="item?id=<% item.id>"><% item.name></a>
- * </li>
- * <%/foreach>
- * </ul>
- * </pre>
- *
- * <p>
- * When {@code itemCollection} is properly set up this will print each item’s
- * name with a link to an item page that receives the ID of the item as
- * parameter. If {@code item} does not refer to a {@link java.util.Map} instance,
- * a custom accessor (see below) is necessary.
- * </p>
- *
- * <h3>Handling Custom Types</h3>
- *
- * <p>
- * The template system can be extended using
- * {@link net.pterodactylus.util.template.Accessor}s. An accessor is used to
- * allow template variable syntax like “object.foo”. Depending on the type of
- * {@code object}  the appropriate accessor is used to find the value of the
- * member “foo” (which can e.g. be retrieved by calling a complicated operation
- * on {@code object}).
- * </p>
- *
- * <p>
- * With a custom type {@code Item} that exposes both an ID and a name (using
- * {@code getID()} and {@code getName()} methods), the following
- * {@link net.pterodactylus.util.template.Accessor} will allow the above
- * example to work.
- * </p>
- *
- * <pre>
- * public class ItemAccessor implements Accessor {
- *     private final Item item;
- *     public ItemAccessor(Item item) { this.item = item; }
- *     public int getID() { return item.getID(); }
- *     public String getName() { return item.getName(); }
- * }
- * </pre>
- *
- * <h3>Conditional Execution</h3>
- *
- * <p>
- * With a loop and its constructs (e.g. <%first> or <%even>) you
- * can already shape your formatted text in quite some ways. If for some
- * reason this is not enough you do have another possibility.
- * </p>
- *
- * <pre>
- * <p>
- *     The color is:
- *     <%if color.black>
- *         black
- *     <%elseif color.red>
- *         red
- *     <%elseif ! color.green>
- *         not green
- *     <%else>
- *         green
- *     <%/if>
- * </p>
- * </pre>
- *
- * <p>
- * At the moment the {@code <%if>} directive requires a single argument
- * which has to evaluate to a {@link java.lang.Boolean} object. The object may
- * be prepended by an exclamation point (“!”, either with or without
- * whitespace following it) to signify that the condition should be reversed.
- * Using a custom accessor this can easily be accomplished. Any further
- * parsing (and expression evaluation) would make the template parser and
- * renderer almost infinitely more complex (and very not-light-weight-anymore).
- * </p>
- *
- * <h3>Filtering Output</h3>
- *
- * <p>
- * One large issue when handling text in web pages is escaping the HTML code
- * so that the content of a web page does not have the capability of inserting
- * custom code into a web site, or destroying its design by unbalanced tags.
- * The template supports filtering output but does not have any output filters
- * added to it by default.
- * </p>
- *
- * <pre>
- * Template template = new Template(templateReader);
- * template.addFilter("html", new HtmlFilter());
- * </pre>
- *
- * <p>
- * This will a filter for HTML to the list of available filters. If you want
- * to escape some text in your template, apply it using the pipe character
- * (“|”, with or without whitespace around it).
- * </p>
- *
- * <pre>
- * <div>Your name is <% name|html>, right?</div>
- * </pre>
- *
- * <p>
- * You can also use several filters for a single variable output. Those are
- * executed in the order they are specified.
- * </p>
- *
- * <pre>
- * <div>Your name is <% name|html|replace needle=Frank replacement=Steve>, right?</div>
- * </pre>
- *
- * <h3>Storing Values in the Template</h3>
- *
- * <p>
- * Sometimes it can be necessary to store a value in the template for later
- * use. In conjunction with a replacement filter this can be used to include
- * template variables in strings that are output by other filters, e.g. an
- * i18n filter.
- * </p>
- *
- * <pre>
- * <% user | html | store key='htmlUser'>
- * <% HelloText | i18n | html | insert needle='${user}' key='htmlUser'>
- * </pre>
- *
- * <p>
- * The “insert” filter can also read variables directly from the template.
- * </p>
- *
- * <h3>Internationalization / Localization (i18n, l10n)</h3>
- *
- * <p>
- * When creating web pages for larger projects you often have to deal with
- * multiple languages. One possibility to achieve multilingual support in a
- * template system would be to simply ignore language support in the template
- * system and create a new template for each language. However, this solution
- * is not desirable for any of the participating parties: the programmer has
- * to load a different template depending on the language; the designer has to
- * copy a desgin change into every translated template again; the translator
- * needs to copy and process a complete template, potentially missing
- * translatable items in a sea of design markup.
- * </p>
- *
- * <p>
- * One possible solution is the possibility to hardcode values in the template
- * and run them through arbitrary filters.
- * </p>
- *
- * <pre>
- * <div><%= Item.Name | i18n | html></div>
- * <div><% item.name | html></div>
- * <div><%= Item.ID | i18n | html></div>
- * <div><% item.id | html></div>
- * </pre>
- *
- * <p>
- * In this example the strings “Item.Name” and “Item.ID” are run through a
- * custom {@link net.pterodactylus.util.template.Filter} that replaces a
- * language-independent key into a translated string. To prevent nasty
- * surprises the translated string is also run through a HTML filter before
- * the final value is printed on the web page.
- * </p>
- *
- * <h3>Whitespace</h3>
- *
- * <p>
- * Sometimes, e.g. when using {@code <%=} or filters, whitespace in a filter
- * directive needs to be preserved. This can be accomplished by using single
- * quotes, double quotes, or a backslash.
- * </p>
- *
- * <h4>Single Quotes</h4>
- *
- * <p>
- * Single quotes preserve all characters until another single quote character
- * is encountered.
- * </p>
- *
- * <h4>Double Quotes</h4>
- *
- * <p>
- * Double quotes preserve all characters until either another double quote or
- * a backslash is encountered.
- * </p>
- *
- * <h4>Backslash</h4>
- *
- * <p>
- * The backslash preserves the next character but is discarded itself.
- * </p>
- *
- * <h4>Examples</h4>
- *
- * <pre>
- * <%= foo | replace needle=foo replacement="bar baz">
- * </pre>
- *
- * <p>
- * This will replace the text “foo” with the text “bar baz”.
- * </p>
- *
- * <pre>
- * <%= "foo bar" | replace needle=foo replacement="bar baz">
- * </pre>
- *
- * <p>
- * This will replace the text “foo bar” with the text “bar baz bar”.
- * </p>
- *
- * <pre>
- * <%= "foo bar" | replace needle='foo bar' replacement="bar baz">
- * </pre>
- *
- * <p>
- * This will replace the text “foo bar” with the text “bar baz”.
- * </p>
- *
- * <pre>
- * <%= "foo bar" | replace needle=foo\ bar replacement="bar baz">
- * </pre>
- *
- * <p>
- * This will also replace the text “foo bar” with the text “bar baz”.
- * </p>
- *
- * <pre>
- * <%= "foo bar" | replace needle="foo\ bar" replacement="bar baz">
- * </pre>
- *
- * <p>
- * This will also replace the text “foo bar” with the text “bar baz”.
- * </p>
- *
- * <pre>
- * <%= "foo bar" | replace needle='foo\ bar' replacement="bar baz">
- * </pre>
- *
- * <p>
- * This will not replace the text “foo bar” with anything because the text
- * “foo\ bar” is not found.
- * </p>
- *
- */
-
-package net.pterodactylus.util.template;
-
diff --git a/alien/src/net/pterodactylus/util/text/StringEscaper.java b/alien/src/net/pterodactylus/util/text/StringEscaper.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/text/StringEscaper.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * utils - StringEscaper.java - Copyright © 2008-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.text;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import net.pterodactylus.util.number.Hex;
-
-/**
- * Contains different methods to escape strings, e.g. for storage in a
- * text-based medium like databases or an XML file.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class StringEscaper {
-
-	/**
-	 * Converts the string into a form that is suitable for storage in
-	 * text-based medium.
-	 *
-	 * @param original
-	 *            The original string
-	 * @return A string that can be used for text-based persistence
-	 */
-	public static String persistString(String original) {
-		if (original == null) {
-			return "";
-		}
-		StringBuilder persistedString = new StringBuilder();
-		persistedString.append(original.length()).append(':');
-		for (char c : original.toCharArray()) {
-			persistedString.append(Hex.toHex(c, 4));
-		}
-		return persistedString.toString();
-	}
-
-	/**
-	 * Recovers the original string from a string that has been created with
-	 * {@link #persistString(String)}.
-	 *
-	 * @param persistedString
-	 *            The persisted string
-	 * @return The original string
-	 * @throws TextException
-	 *             if the persisted string can not be parsed
-	 */
-	public static String unpersistString(String persistedString) throws TextException {
-		if (persistedString.length() == 0) {
-			return null;
-		}
-		int colon = persistedString.indexOf(':');
-		if (colon == -1) {
-			throw new TextException("no colon in persisted string");
-		}
-		if (((persistedString.length() - (colon + 1)) % 4) != 0) {
-			throw new TextException("invalid length of persisted string");
-		}
-		int length = -1;
-		try {
-			length = Integer.parseInt(persistedString.substring(0, colon));
-		} catch (NumberFormatException nfe1) {
-			throw new TextException("could not parse length", nfe1);
-		}
-		if (length < 0) {
-			throw new TextException("invalid length: " + length);
-		}
-		StringBuilder unpersistedString = new StringBuilder(length);
-		try {
-			for (int charIndex = colon + 1; charIndex < persistedString.length(); charIndex += 4) {
-				char c = (char) Integer.parseInt(persistedString.substring(charIndex, charIndex + 4), 16);
-				unpersistedString.append(c);
-			}
-		} catch (NumberFormatException nfe1) {
-			throw new TextException("invalid character in persisted string", nfe1);
-		}
-		return unpersistedString.toString();
-	}
-
-	/**
-	 * Splits a string into words. Words are separated by space characters.
-	 *
-	 * @param line
-	 *            The line to parse
-	 * @return The parsed words
-	 * @throws TextException
-	 *             if quotes are not closed
-	 */
-	public static List<String> parseLine(String line) throws TextException {
-		boolean inDoubleQuote = false;
-		boolean inSingleQuote = false;
-		boolean backslashed = false;
-		List<String> words = new ArrayList<String>();
-		boolean wordEmpty = true;
-		StringBuilder currentWord = new StringBuilder();
-		for (char c : line.toCharArray()) {
-			if (c == '"') {
-				if (inSingleQuote || backslashed) {
-					currentWord.append(c);
-					backslashed = false;
-				} else {
-					inDoubleQuote ^= true;
-					wordEmpty = false;
-				}
-			} else if (c == '\'') {
-				if (inDoubleQuote || backslashed) {
-					currentWord.append(c);
-					backslashed = false;
-				} else {
-					inSingleQuote ^= true;
-					wordEmpty = false;
-				}
-			} else if (c == '\\') {
-				if (inSingleQuote || backslashed) {
-					currentWord.append(c);
-					backslashed = false;
-				} else {
-					backslashed = true;
-				}
-			} else if (c == ' ') {
-				if (inDoubleQuote || inSingleQuote || backslashed) {
-					currentWord.append(c);
-					backslashed = false;
-				} else {
-					if ((currentWord.length() > 0) || !wordEmpty) {
-						words.add(currentWord.toString());
-						currentWord.setLength(0);
-						wordEmpty = true;
-					}
-				}
-			} else {
-				if (backslashed && (c == 'n')) {
-					currentWord.append('\n');
-				} else {
-					currentWord.append(c);
-				}
-				backslashed = false;
-			}
-		}
-		if (inSingleQuote || inDoubleQuote || backslashed) {
-			throw new TextException("open quote");
-		}
-		if (currentWord.length() > 0) {
-			words.add(currentWord.toString());
-		}
-		return words;
-	}
-
-	/**
-	 * Escapes the given word in a way that {@link #parseLine(String)} can
-	 * correctly unescape it. The following rules are applied to the word:
-	 * <ul>
-	 * <li>If the word is the empty string, it is surrounded by double quotes.</li>
-	 * <li>If the word does not contain single quotes, double quotes,
-	 * backslashes, or space characters, it is returned as is.</li>
-	 * <li>If the word contains space characters and single quotes but none of
-	 * the other characters, it is surrounded by double quotes.</li>
-	 * <li>If the word contains space characters and double quotes and
-	 * backslashes, it is surrounded by single quotes.</li>
-	 * <li>Otherwise single quotes, double quotes, backslashes and space
-	 * characters are escaped by prefixing them with a backslash.</li>
-	 * </ul>
-	 *
-	 * @param word
-	 *            The word to escape
-	 * @return The escaped word
-	 */
-	public static String escapeWord(String word) {
-		if (word == null) {
-			return "";
-		}
-		if (word.length() == 0) {
-			return "\"\"";
-		}
-		boolean containsSingleQuote = word.indexOf('\'') != -1;
-		boolean containsDoubleQuote = word.indexOf('"') != -1;
-		boolean containsBackslash = word.indexOf('\\') != -1;
-		boolean containsSpace = word.indexOf(' ') != -1;
-		boolean containsLineBreak = word.indexOf('\n') != -1;
-		if (!containsSingleQuote && !containsDoubleQuote && !containsBackslash && !containsSpace) {
-			return word.replace("\n", "\\n");
-		}
-		if (!containsDoubleQuote && !containsBackslash) {
-			return "\"" + word.replace("\n", "\\n") + "\"";
-		}
-		if (!containsSingleQuote && !containsLineBreak) {
-			return "'" + word.replace("\n", "\\n") + "'";
-		}
-		return word.replace("\\", "\\\\").replace(" ", "\\ ").replace("\"", "\\\"").replace("'", "\\'").replace("\n", "\\n");
-	}
-
-	/**
-	 * Escapes all words in the given collection and joins them separated by a
-	 * space.
-	 *
-	 * @param words
-	 *            The words to escape
-	 * @return A line with all escaped word separated by a space
-	 */
-	public static String escapeWords(Collection<String> words) {
-		StringBuilder wordBuilder = new StringBuilder();
-		for (String word : words) {
-			if (wordBuilder.length() > 0) {
-				wordBuilder.append(' ');
-			}
-			wordBuilder.append(escapeWord(word));
-		}
-		return wordBuilder.toString();
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/text/TextException.java b/alien/src/net/pterodactylus/util/text/TextException.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/text/TextException.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * utils - TextException.java - Copyright © 2008-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.text;
-
-import java.text.ParseException;
-
-/**
- * Exception that signals an error when processing texts.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class TextException extends ParseException {
-
-	/**
-	 * Creates a new text exception.
-	 */
-	public TextException() {
-		this("");
-	}
-
-	/**
-	 * Creates a new text exception with the given message.
-	 *
-	 * @param message
-	 *            The message of the exception
-	 */
-	public TextException(String message) {
-		super(message, -1);
-	}
-
-	/**
-	 * Creates a new text exception with the given cause.
-	 *
-	 * @param cause
-	 *            The cause of the exception
-	 */
-	public TextException(Throwable cause) {
-		this("", cause);
-	}
-
-	/**
-	 * Creates a new text exception with the given message and cause.
-	 *
-	 * @param message
-	 *            The message of the exception
-	 * @param cause
-	 *            The cause of the exception
-	 */
-	public TextException(String message, Throwable cause) {
-		this(message);
-		initCause(cause);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/time/Duration.java b/alien/src/net/pterodactylus/util/time/Duration.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/time/Duration.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * utils - Duration.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.time;
-
-/**
- * A duration is the length between two events in time.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Duration {
-
-	/** This duration in milliseconds. */
-	private final long duration;
-
-	/** The number of whole weeks in this duration. */
-	private final long weeks;
-
-	/** The number of days in the last week of this duration. */
-	private final int days;
-
-	/** The number of hours in the last day of this duration. */
-	private final int hours;
-
-	/** The number of minutes in the last hour of this duration. */
-	private final int minutes;
-
-	/** The number of seconds in the last minute of this duration. */
-	private final int seconds;
-
-	/** The number of milliseconds in the last second of this duration. */
-	private final int milliseconds;
-
-	/**
-	 * Creates a new duration with the specified length.
-	 *
-	 * @param duration
-	 *            The length of this duration in milliseconds
-	 */
-	public Duration(long duration) {
-		this.duration = duration;
-		milliseconds = (int) (duration % 1000);
-		seconds = (int) ((duration / 1000) % 60);
-		minutes = (int) ((duration / (1000 * 60)) % 60);
-		hours = (int) ((duration / (1000 * 60 * 60)) % 24);
-		days = (int) ((duration / (1000 * 60 * 60 * 24)) % 7);
-		weeks = duration / (1000 * 60 * 60 * 24 * 7);
-	}
-
-	/**
-	 * Returns the number of days in the last week of this duration
-	 *
-	 * @return The number of days
-	 */
-	public int getDays() {
-		return days;
-	}
-
-	/**
-	 * Returns the length of this duration.
-	 *
-	 * @return The length of this duration (in milliseconds)
-	 */
-	public long getDuration() {
-		return duration;
-	}
-
-	/**
-	 * Returns the number of hours in the last day of this duration.
-	 *
-	 * @return The number of hours
-	 */
-	public int getHours() {
-		return hours;
-	}
-
-	/**
-	 * Returns the number of milliseconds in the last second of this duration.
-	 *
-	 * @return The number of milliseconds
-	 */
-	public int getMilliseconds() {
-		return milliseconds;
-	}
-
-	/**
-	 * Returns the number of minutes in the last hour of this duration.
-	 *
-	 * @return The number of minutes
-	 */
-	public int getMinutes() {
-		return minutes;
-	}
-
-	/**
-	 * Returns the number of seconds in the last minute of this duration.
-	 *
-	 * @return The number of seconds
-	 */
-	public int getSeconds() {
-		return seconds;
-	}
-
-	/**
-	 * Returns the number of whole weeks in this duration.
-	 *
-	 * @return The number of weeks
-	 */
-	public long getWeeks() {
-		return weeks;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see java.lang.Object#toString()
-	 */
-	@Override
-	public String toString() {
-		return toString(true);
-	}
-
-	/**
-	 * Returns a textual representation of this duration.
-	 *
-	 * @param showMilliseconds
-	 *            <code>true</code> if the milliseconds should be shown,
-	 *            <code>false</code> otherwise
-	 * @return The textual representation of this duration
-	 */
-	public String toString(boolean showMilliseconds) {
-		StringBuilder durationBuilder = new StringBuilder();
-		if ((milliseconds != 0) && showMilliseconds) {
-			int ms = milliseconds;
-			while ((ms % 10) == 0) {
-				ms /= 10;
-			}
-			durationBuilder.append(seconds).append('.').append(ms).append('s');
-		} else if (seconds != 0) {
-			durationBuilder.append(seconds).append('s');
-		} else if ((minutes == 0) && (hours == 0) && (days == 0) && (weeks == 0)) {
-			durationBuilder.append("0s");
-		}
-		if (minutes != 0) {
-			durationBuilder.insert(0, "m ").insert(0, minutes);
-		}
-		if (hours != 0) {
-			durationBuilder.insert(0, "h ").insert(0, hours);
-		}
-		if (days != 0) {
-			durationBuilder.insert(0, "d ").insert(0, days);
-		}
-		if (weeks != 0) {
-			durationBuilder.insert(0, "w ").insert(0, weeks);
-		}
-		return durationBuilder.toString();
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/validation/Validation.java b/alien/src/net/pterodactylus/util/validation/Validation.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/validation/Validation.java
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * utils - Validation.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package net.pterodactylus.util.validation;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * <p>
- * Helps with parameter validation. Parameters can be checked using a construct
- * like this:
- * </p>
- * <code><pre>
- * public void copy(Object[] object, int leftValue, int ríghtValue) {
- *     Validation.begin().isNotNull(object, "object").check()
- *         .isPositive(leftValue, "leftValue").isLess(leftValue, object.length, "leftValue").check()
- *         .isPositive(rightValue, "rightValue").isLess(rightValue, object.length, "rightValue").isGreater(rightValue, leftValue, "rightValue").check();
- *     // do something with the values
- * }
- * </pre></code>
- * <p>
- * This example will perform several checks. Only the {@link #check()} method
- * will throw an {@link IllegalArgumentException} if one of the previous checks
- * failed, so you can gather several reasons for a validation failure before
- * throwing an exception which will in turn decrease the time spent in
- * debugging.
- * </p>
- * <p>
- * In the example, <code>object</code> is first checked for a non-
- * <code>null</code> value and an {@link IllegalArgumentException} is thrown if
- * <code>object</code> is <code>null</code>. Afterwards <code>leftValue</code>
- * is checked for being a positive value that is also smaller than the length of
- * the array <code>object</code>. The {@link IllegalArgumentException} that is
- * thrown if the checks failed will contain a message for each of the failed
- * checks. At last <code>rightValue</code> is checked for being positive,
- * smaller than the array’s length and larger than <code>leftValue</code>.
- * </p>
- * <p>
- * Remember to call the {@link #check()} method after performing the checks,
- * otherwise the {@link IllegalArgumentException} will never be thrown!
- * </p>
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Validation {
-
-	/** The list of failed checks. */
-	private List<String> failedChecks;
-
-	/**
-	 * Private constructor to prevent construction from the outside.
-	 */
-	private Validation() {
-		/* do nothing. */
-	}
-
-	/**
-	 * Adds a check to the list of failed checks, instantiating a new list if
-	 * {@link #failedChecks} is still <code>null</code>.
-	 *
-	 * @param check
-	 *            The check to add
-	 */
-	private void addFailedCheck(String check) {
-		if (failedChecks == null) {
-			failedChecks = new ArrayList<String>();
-		}
-		failedChecks.add(check);
-	}
-
-	/**
-	 * Returns a new {@link Validation} object.
-	 *
-	 * @return A new validation
-	 */
-	public static Validation begin() {
-		return new Validation();
-	}
-
-	/**
-	 * Checks if one of the previous checks failed and throws an
-	 * {@link IllegalArgumentException} if a previous check did fail.
-	 *
-	 * @return This {@link Validation} object to allow method chaining
-	 * @throws IllegalArgumentException
-	 *             if a previous check failed
-	 */
-	public Validation check() throws IllegalArgumentException {
-		if (failedChecks == null) {
-			return this;
-		}
-		StringBuilder message = new StringBuilder();
-		message.append("Failed checks: ");
-		for (String failedCheck : failedChecks) {
-			message.append(failedCheck).append(", ");
-		}
-		message.setLength(message.length() - 2);
-		message.append('.');
-		throw new IllegalArgumentException(message.toString());
-	}
-
-	/**
-	 * Checks if the given object is not <code>null</code>.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param object
-	 *            The object to check
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isNotNull(String objectName, Object object) {
-		if (object == null) {
-			addFailedCheck(objectName + " should not be null");
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if <code>value</code> is less than <code>upperBound</code>.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @param upperBound
-	 *            The upper bound to check <code>value</code> against
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isLess(String objectName, double value, double upperBound) {
-		if (value >= upperBound) {
-			addFailedCheck(objectName + " should be < " + upperBound + " but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if <code>value</code> is less than <code>upperBound</code>.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @param upperBound
-	 *            The upper bound to check <code>value</code> against
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isLessOrEqual(String objectName, long value, long upperBound) {
-		if (value > upperBound) {
-			addFailedCheck(objectName + " should be <= " + upperBound + " but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if <code>value</code> is less than <code>upperBound</code>.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @param upperBound
-	 *            The upper bound to check <code>value</code> against
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isLessOrEqual(String objectName, double value, double upperBound) {
-		if (value > upperBound) {
-			addFailedCheck(objectName + " should be <= " + upperBound + " but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if the given value is equal to the expected value.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @param expected
-	 *            The expected value to check <code>value</code> against
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isEqual(String objectName, long value, long expected) {
-		if (value != expected) {
-			addFailedCheck(objectName + " should be == " + expected + " but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if the given value is equal to the expected value.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @param expected
-	 *            The expected value to check <code>value</code> against
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isEqual(String objectName, double value, double expected) {
-		if (value != expected) {
-			addFailedCheck(objectName + " should be == " + expected + " but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if the given value is equal to the expected value.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @param expected
-	 *            The expected value to check <code>value</code> against
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isEqual(String objectName, boolean value, boolean expected) {
-		if (value != expected) {
-			addFailedCheck(objectName + " should be == " + expected + " but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if the given value is equal to the expected value.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @param expected
-	 *            The expected value to check <code>value</code> against
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isEqual(String objectName, Object value, Object expected) {
-		if (!value.equals(expected)) {
-			addFailedCheck(objectName + " should equal " + expected + " but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if the given value is the same as the expected value.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @param expected
-	 *            The expected value to check <code>value</code> against
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isSame(String objectName, Object value, Object expected) {
-		if (value != expected) {
-			addFailedCheck(objectName + " should be == " + expected + " but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if the given value is not equal to the expected value.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @param expected
-	 *            The expected value to check <code>value</code> against
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isNotEqual(String objectName, long value, long expected) {
-		if (value == expected) {
-			addFailedCheck(objectName + " should be != " + expected + " but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if the given value is not equal to the expected value.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @param expected
-	 *            The expected value to check <code>value</code> against
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isNotEqual(String objectName, double value, double expected) {
-		if (value == expected) {
-			addFailedCheck(objectName + " should be != " + expected + " but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if the given value is not equal to the expected value.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @param expected
-	 *            The expected value to check <code>value</code> against
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isNotEqual(String objectName, boolean value, boolean expected) {
-		if (value == expected) {
-			addFailedCheck(objectName + " should be != " + expected + " but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if <code>value</code> is greater than <code>lowerBound</code>.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @param lowerBound
-	 *            The lower bound to check <code>value</code> against
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isGreater(String objectName, long value, long lowerBound) {
-		if (value <= lowerBound) {
-			addFailedCheck(objectName + " should be > " + lowerBound + " but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if <code>value</code> is greater than <code>lowerBound</code>.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @param lowerBound
-	 *            The lower bound to check <code>value</code> against
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isGreater(String objectName, double value, double lowerBound) {
-		if (value <= lowerBound) {
-			addFailedCheck(objectName + " should be > " + lowerBound + " but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if <code>value</code> is greater than <code>lowerBound</code>.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @param lowerBound
-	 *            The lower bound to check <code>value</code> against
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isGreaterOrEqual(String objectName, long value, long lowerBound) {
-		if (value < lowerBound) {
-			addFailedCheck(objectName + " should be >= " + lowerBound + " but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if <code>value</code> is greater than <code>lowerBound</code>.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @param lowerBound
-	 *            The lower bound to check <code>value</code> against
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isGreaterOrEqual(String objectName, double value, double lowerBound) {
-		if (value < lowerBound) {
-			addFailedCheck(objectName + " should be >= " + lowerBound + " but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if the given value is greater to or equal to <code>0</code>.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isPositive(String objectName, long value) {
-		if (value < 0) {
-			addFailedCheck(objectName + " should be >= 0 but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if the given value is greater to or equal to <code>0</code>.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isPositive(String objectName, double value) {
-		if (value < 0) {
-			addFailedCheck(objectName + " should be >= 0 but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if the given value is less than <code>0</code>.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isNegative(String objectName, long value) {
-		if (value >= 0) {
-			addFailedCheck(objectName + " should be < 0 but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks if the given value is less than <code>0</code>.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The value to check
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isNegative(String objectName, double value) {
-		if (value >= 0) {
-			addFailedCheck(objectName + " should be < 0 but was " + value);
-		}
-		return this;
-	}
-
-	/**
-	 * Checks whether the given object is assignable to an object of the given
-	 * class.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param object
-	 *            The object to check
-	 * @param clazz
-	 *            The class the object should be representable as
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isInstanceOf(String objectName, Object object, Class<?> clazz) {
-		if (!object.getClass().isAssignableFrom(clazz)) {
-			addFailedCheck(objectName + " should be a kind of " + clazz.getName() + " but is " + object.getClass().getName());
-		}
-		return this;
-	}
-
-	/**
-	 * Checks whether the given value is one of the expected values.
-	 *
-	 * @param objectName
-	 *            The object’s name
-	 * @param value
-	 *            The object’s value
-	 * @param expectedValues
-	 *            The expected values
-	 * @return This {@link Validation} object to allow method chaining
-	 */
-	public Validation isOneOf(String objectName, Object value, Object... expectedValues) {
-		List<?> values;
-		if (!(values = Arrays.asList(expectedValues)).contains(value)) {
-			addFailedCheck(objectName + " should be one of " + values + " but is " + value);
-		}
-		return this;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/version/Version.java b/alien/src/net/pterodactylus/util/version/Version.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/version/Version.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * utils - Version.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.version;
-
-import java.util.Arrays;
-
-/**
- * Version number container.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Version implements Comparable<Version> {
-
-	/** The version numbers. */
-	private final int[] numbers;
-
-	/** An optional appendix. */
-	private final String appendix;
-
-	/**
-	 * Creates a new version with the given numbers.
-	 *
-	 * @param numbers
-	 *            The numbers of the version
-	 */
-	public Version(int... numbers) {
-		this(null, numbers);
-	}
-
-	/**
-	 * Creates a new version with the given numbers.
-	 *
-	 * @param appendix
-	 *            The optional appendix
-	 * @param numbers
-	 *            The numbers of the version
-	 */
-	public Version(String appendix, int... numbers) {
-		this.numbers = new int[numbers.length];
-		System.arraycopy(numbers, 0, this.numbers, 0, numbers.length);
-		this.appendix = appendix;
-	}
-
-	/**
-	 * Returns the number at the given index.
-	 *
-	 * @param index
-	 *            The index of the number
-	 * @return The number, or <code>0</code> if there is no number at the given
-	 *         index
-	 */
-	public int getNumber(int index) {
-		if (index >= numbers.length) {
-			return 0;
-		}
-		return numbers[index];
-	}
-
-	/**
-	 * Returns the first number of the version.
-	 *
-	 * @return The first number of the version
-	 */
-	public int getMajor() {
-		return getNumber(0);
-	}
-
-	/**
-	 * Returns the second number of the version.
-	 *
-	 * @return The second number of the version
-	 */
-	public int getMinor() {
-		return getNumber(1);
-	}
-
-	/**
-	 * Returns the third number of the version.
-	 *
-	 * @return The third number of the version
-	 */
-	public int getRelease() {
-		return getNumber(2);
-	}
-
-	/**
-	 * Returns the fourth number of the version.
-	 *
-	 * @return The fourth number of the version
-	 */
-	public int getPatch() {
-		return getNumber(3);
-	}
-
-	/**
-	 * Returns the optional appendix.
-	 *
-	 * @return The appendix, or <code>null</code> if there is no appendix
-	 */
-	public String getAppendix() {
-		return appendix;
-	}
-
-	/**
-	 * @see java.lang.Object#toString()
-	 */
-	@Override
-	public String toString() {
-		StringBuilder versionString = new StringBuilder();
-		for (int number : numbers) {
-			if (versionString.length() > 0) {
-				versionString.append('.');
-			}
-			versionString.append(number);
-		}
-		if (appendix != null) {
-			versionString.append('-').append(appendix);
-		}
-		return versionString.toString();
-	}
-
-	//
-	// INTERFACE Comparable<Version>
-	//
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see java.lang.Comparable#compareTo(java.lang.Object)
-	 */
-	@Override
-	public int compareTo(Version version) {
-		int lengthDiff = numbers.length - version.numbers.length;
-		for (int index = 0; index < Math.abs(lengthDiff); index++) {
-			int diff = numbers[index] - version.numbers[index];
-			if (diff != 0) {
-				return diff;
-			}
-		}
-		return lengthDiff;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see java.lang.Object#equals(java.lang.Object)
-	 */
-	@Override
-	public boolean equals(Object obj) {
-		if ((obj == null) || !(obj instanceof Version)) {
-			return false;
-		}
-		Version version = (Version) obj;
-		return Arrays.equals(numbers, version.numbers);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 *
-	 * @see java.lang.Object#hashCode()
-	 */
-	@Override
-	public int hashCode() {
-		return Arrays.hashCode(numbers);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/xml/DOMUtil.java b/alien/src/net/pterodactylus/util/xml/DOMUtil.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/xml/DOMUtil.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * utils - DOMUtil.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.xml;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * Contains various helper methods that let you more easily work with
- * {@code org.w3c.dom} objects.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class DOMUtil {
-
-	/**
-	 * Returns the first child node of the given root node that has the given
-	 * name.
-	 *
-	 * @param rootNode
-	 *            The root node
-	 * @param childName
-	 *            The name of the child node
-	 * @return The child node, or {@code null} if the root node does not have a
-	 *         child node with the given name
-	 */
-	public static Node getChildNode(Node rootNode, String childName) {
-		NodeList nodeList = rootNode.getChildNodes();
-		for (int nodeIndex = 0, nodeSize = nodeList.getLength(); nodeIndex < nodeSize; nodeIndex++) {
-			Node childNode = nodeList.item(nodeIndex);
-			if (childNode.getNodeName().equals(childName)) {
-				return childNode;
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns all child nodes of the given root node with the given name.
-	 *
-	 * @param rootNode
-	 *            The root node
-	 * @param childName
-	 *            The name of child nodes
-	 * @return All child nodes with the given name, or an empty array if there
-	 *         are no child nodes with the given name
-	 */
-	public static Node[] getChildNodes(Node rootNode, String childName) {
-		List<Node> nodes = new ArrayList<Node>();
-		NodeList nodeList = rootNode.getChildNodes();
-		for (int nodeIndex = 0, nodeSize = nodeList.getLength(); nodeIndex < nodeSize; nodeIndex++) {
-			Node childNode = nodeList.item(nodeIndex);
-			if (childNode.getNodeName().equals(childName)) {
-				nodes.add(childNode);
-			}
-		}
-		return nodes.toArray(new Node[nodes.size()]);
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/xml/SimpleXML.java b/alien/src/net/pterodactylus/util/xml/SimpleXML.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/xml/SimpleXML.java
+++ /dev/null
@@ -1,569 +0,0 @@
-/*
- * utils - SimpleXML.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.xml;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import net.pterodactylus.util.logging.Logging;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.Text;
-
-/**
- * SimpleXML is a helper class to construct XML trees in a fast and simple way.
- * Construct a new XML tree by calling {@link #SimpleXML(String)} and append new
- * nodes by calling {@link #append(String)}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class SimpleXML {
-
-	/** Logger. */
-	private static final Logger logger = Logging.getLogger(SimpleXML.class.getName());
-
-	/**
-	 * A {@link List} containing all child nodes of this node.
-	 */
-	private List<SimpleXML> children = new ArrayList<SimpleXML>();
-
-	/**
-	 * The name of this node.
-	 */
-	private String name = null;
-
-	/**
-	 * The value of this node.
-	 */
-	private String value = null;
-
-	/** Attributes of the element. */
-	private Map<String, String> attributes = null;
-
-	/**
-	 * Constructs a new XML node without a name.
-	 */
-	public SimpleXML() {
-		super();
-	}
-
-	/**
-	 * Constructs a new XML node with the specified name.
-	 *
-	 * @param name
-	 *            The name of the new node
-	 */
-	public SimpleXML(String name) {
-		this(name, (String[]) null, (String[]) null);
-	}
-
-	/**
-	 * Constructs a new XML node with the specified name and a single attribute.
-	 *
-	 * @param name
-	 *            The name of the node
-	 * @param attributeName
-	 *            The name of the attribute
-	 * @param attributeValue
-	 *            The value of the attribute
-	 */
-	public SimpleXML(String name, String attributeName, String attributeValue) {
-		this(name, new String[] { attributeName }, new String[] { attributeValue });
-	}
-
-	/**
-	 * Constructs a new XML node with the specified name and attributes.
-	 *
-	 * @param name
-	 *            The name of the node
-	 * @param attributeNames
-	 *            The names of the attribute
-	 * @param attributeValues
-	 *            The values of the attribute
-	 */
-	public SimpleXML(String name, String[] attributeNames, String[] attributeValues) {
-		this.name = name;
-		attributes = new HashMap<String, String>();
-		if ((attributeNames != null) && (attributeValues != null) && (attributeNames.length == attributeValues.length)) {
-			for (int index = 0, size = attributeNames.length; index < size; index++) {
-				attributes.put(attributeNames[index], attributeValues[index]);
-			}
-		}
-	}
-
-	/**
-	 * Returns all attributes’ names. The array is not sorted.
-	 *
-	 * @return The names of all attributes
-	 */
-	public String[] getAttributeNames() {
-		return attributes.keySet().toArray(new String[attributes.size()]);
-	}
-
-	/**
-	 * Returns the value of the attribute with the given name.
-	 *
-	 * @param attributeName
-	 *            The name of the attribute to look up
-	 * @return The value of the attribute
-	 */
-	public String getAttribute(String attributeName) {
-		return getAttribute(attributeName, null);
-	}
-
-	/**
-	 * Returns the value of the attribute with the given name.
-	 *
-	 * @param attributeName
-	 *            The name of the attribute to look up
-	 * @param defaultValue
-	 *            The value to return if there is no attribute with the given
-	 *            name
-	 * @return The value of the attribute
-	 */
-	public String getAttribute(String attributeName, String defaultValue) {
-		if (!attributes.containsKey(attributeName)) {
-			return defaultValue;
-		}
-		return attributes.get(attributeName);
-	}
-
-	/**
-	 * Sets the value of an attribute.
-	 *
-	 * @param attributeName
-	 *            The name of the attribute to set
-	 * @param attributeValue
-	 *            The value of the attribute
-	 */
-	public void setAttribute(String attributeName, String attributeValue) {
-		attributes.put(attributeName, attributeValue);
-	}
-
-	/**
-	 * Removes the attribute with the given name, returning its previous value.
-	 *
-	 * @param attributeName
-	 *            The name of the attribute to remove
-	 * @return The value of the attribute before removing it
-	 */
-	public String removeAttribute(String attributeName) {
-		return attributes.remove(attributeName);
-	}
-
-	/**
-	 * Checks whether this node contains the attribute with the given name.
-	 *
-	 * @param attributeName
-	 *            The name of the attribute
-	 * @return <code>true</code> if this node has an attribute with the given
-	 *         name, <code>false</code> otherwise
-	 */
-	public boolean hasAttribute(String attributeName) {
-		return attributes.containsKey(attributeName);
-	}
-
-	/**
-	 * Returns whether this node has any child nodes.
-	 *
-	 * @return {@code true} if this node has child nodes, {@code false}
-	 *         otherwise
-	 */
-	public boolean hasNodes() {
-		return !children.isEmpty();
-	}
-
-	/**
-	 * Checks if this object has a child with the specified name.
-	 *
-	 * @param nodeName
-	 *            The name of the child node to check for
-	 * @return <code>true</code> if this node has at least one child with the
-	 *         specified name, <code>false</code> otherwise
-	 */
-	public boolean hasNode(String nodeName) {
-		return getNode(nodeName) != null;
-	}
-
-	/**
-	 * Returns the child node of this node with the specified name. If there are
-	 * several child nodes with the specified name only the first node is
-	 * returned.
-	 *
-	 * @param nodeName
-	 *            The name of the child node
-	 * @return The child node, or <code>null</code> if there is no child node
-	 *         with the specified name
-	 */
-	public SimpleXML getNode(String nodeName) {
-		for (int index = 0, count = children.size(); index < count; index++) {
-			if (children.get(index).name.equals(nodeName)) {
-				return children.get(index);
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the child node that is specified by the names. The first element
-	 * of <code>nodeNames</code> is the name of the child node of this node, the
-	 * second element of <code>nodeNames</code> is the name of a child node's
-	 * child node, and so on. By using this method you can descend into an XML
-	 * tree pretty fast.
-	 *
-	 * <pre>
-	 * <code>
-	 * SimpleXML deepNode = topNode.getNodes(new String[] { "person", "address", "number" });
-	 * </code>
-	 * </pre>
-	 *
-	 * @param nodeNames
-	 *            The names of the nodes
-	 * @return A node that is a deep child of this node, or <code>null</code> if
-	 *         the specified node does not eixst
-	 */
-	public SimpleXML getNode(String[] nodeNames) {
-		SimpleXML node = this;
-		for (String nodeName : nodeNames) {
-			node = node.getNode(nodeName);
-		}
-		return node;
-	}
-
-	/**
-	 * Returns all child nodes of this node.
-	 *
-	 * @return All child nodes of this node
-	 */
-	public SimpleXML[] getNodes() {
-		return getNodes(null);
-	}
-
-	/**
-	 * Returns all child nodes of this node with the specified name. If there
-	 * are no child nodes with the specified name an empty array is returned.
-	 *
-	 * @param nodeName
-	 *            The name of the nodes to retrieve, or <code>null</code> to
-	 *            retrieve all nodes
-	 * @return All child nodes with the specified name
-	 */
-	public SimpleXML[] getNodes(String nodeName) {
-		List<SimpleXML> resultList = new ArrayList<SimpleXML>();
-		for (SimpleXML child : children) {
-			if ((nodeName == null) || child.name.equals(nodeName)) {
-				resultList.add(child);
-			}
-		}
-		return resultList.toArray(new SimpleXML[resultList.size()]);
-	}
-
-	/**
-	 * Appends a new XML node with the specified name and returns the new node.
-	 * With this method you can create deep structures very fast.
-	 *
-	 * <pre>
-	 * <code>
-	 * SimpleXML mouseNode = topNode.append("computer").append("bus").append("usb").append("mouse");
-	 * </code>
-	 * </pre>
-	 *
-	 * @param nodeName
-	 *            The name of the node to append as a child to this node
-	 * @return The new node
-	 */
-	public SimpleXML append(String nodeName) {
-		return append(new SimpleXML(nodeName));
-	}
-
-	/**
-	 * Appends a new XML node with the specified name and value and returns the
-	 * new node.
-	 *
-	 * @param nodeName
-	 *            The name of the node to append
-	 * @param nodeValue
-	 *            The value of the node to append
-	 * @return The newly appended node
-	 */
-	public SimpleXML append(String nodeName, String nodeValue) {
-		return append(nodeName).setValue(nodeValue);
-	}
-
-	/**
-	 * Appends the node with all its child nodes to this node and returns the
-	 * child node.
-	 *
-	 * @param newChild
-	 *            The node to append as a child
-	 * @return The child node that was appended
-	 */
-	public SimpleXML append(SimpleXML newChild) {
-		children.add(newChild);
-		return newChild;
-	}
-
-	/**
-	 * Removes the specified child from this node.
-	 *
-	 * @param child
-	 *            The child to remove
-	 */
-	public void remove(SimpleXML child) {
-		children.remove(child);
-	}
-
-	/**
-	 * Removes the child with the specified name from this node. If more than
-	 * one children have the same name only the first is removed.
-	 *
-	 * @param childName
-	 *            The name of the child node to remove
-	 */
-	public void remove(String childName) {
-		SimpleXML child = getNode(childName);
-		if (child != null) {
-			remove(child);
-		}
-	}
-
-	/**
-	 * Replace the child node with the specified name by a new node with the
-	 * specified content.
-	 *
-	 * @param childName
-	 *            The name of the child to replace
-	 * @param value
-	 *            The node child's value
-	 */
-	public void replace(String childName, String value) {
-		remove(childName);
-		append(childName, value);
-	}
-
-	/**
-	 * Replaces the child node that has the same name as the given node by the
-	 * given node.
-	 *
-	 * @param childNode
-	 *            The node to replace the previous child node with the same name
-	 */
-	public void replace(SimpleXML childNode) {
-		remove(childNode.getName());
-		append(childNode);
-	}
-
-	/**
-	 * Removes all children from this node.
-	 */
-	public void removeAll() {
-		children.clear();
-	}
-
-	/**
-	 * Sets the value of this node.
-	 *
-	 * @param nodeValue
-	 *            The new value of this node
-	 * @return This node
-	 */
-	public SimpleXML setValue(String nodeValue) {
-		value = nodeValue;
-		return this;
-	}
-
-	/**
-	 * Returns the name of this node.
-	 *
-	 * @return The name of this node
-	 */
-	public String getName() {
-		return name;
-	}
-
-	/**
-	 * Returns the value of this node.
-	 *
-	 * @return The value of this node
-	 */
-	public String getValue() {
-		return value;
-	}
-
-	/**
-	 * Returns the value of the first child node with the specified name.
-	 *
-	 * @param childName
-	 *            The name of the child node
-	 * @return The value of the child node
-	 * @throws NullPointerException
-	 *             if the child node does not exist
-	 */
-	public String getValue(String childName) {
-		return getNode(childName).getValue();
-	}
-
-	/**
-	 * Returns the value of the first child node with the specified name, or the
-	 * default value if there is no child node with the given name.
-	 *
-	 * @param childName
-	 *            The name of the child node
-	 * @param defaultValue
-	 *            The default value to return if there is no child node with the
-	 *            given name
-	 * @return The value of the child node
-	 * @throws NullPointerException
-	 *             if the child node does not exist
-	 */
-	public String getValue(String childName, String defaultValue) {
-		SimpleXML childNode = getNode(childName);
-		if (childNode == null) {
-			return defaultValue;
-		}
-		return childNode.getValue();
-	}
-
-	/**
-	 * Creates a {@link Document} from this node and all its child nodes.
-	 *
-	 * @return The {@link Document} created from this node
-	 */
-	public Document getDocument() {
-		DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
-		try {
-			DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
-			Document document = documentBuilder.newDocument();
-			Element rootElement = document.createElement(name);
-			for (Entry<String, String> attributeEntry : attributes.entrySet()) {
-				rootElement.setAttribute(attributeEntry.getKey(), attributeEntry.getValue());
-			}
-			document.appendChild(rootElement);
-			addChildren(rootElement);
-			return document;
-		} catch (ParserConfigurationException e) {
-			/* ignore. */
-		}
-		return null;
-	}
-
-	/**
-	 * Appends all children of this node to the specified {@link Element}. If a
-	 * node has a value that is not <code>null</code> the value is appended as a
-	 * text node.
-	 *
-	 * @param rootElement
-	 *            The element to attach this node's children to
-	 */
-	private void addChildren(Element rootElement) {
-		for (SimpleXML child : children) {
-			Element childElement = rootElement.getOwnerDocument().createElement(child.name);
-			for (Entry<String, String> attributeEntry : child.attributes.entrySet()) {
-				childElement.setAttribute(attributeEntry.getKey(), attributeEntry.getValue());
-			}
-			rootElement.appendChild(childElement);
-			if (child.value != null) {
-				Text childText = rootElement.getOwnerDocument().createTextNode(child.value);
-				childElement.appendChild(childText);
-			} else {
-				child.addChildren(childElement);
-			}
-		}
-	}
-
-	/**
-	 * Creates a SimpleXML node from the specified {@link Document}. The
-	 * SimpleXML node of the document's top-level node is returned.
-	 *
-	 * @param document
-	 *            The {@link Document} to create a SimpleXML node from
-	 * @return The SimpleXML node created from the document's top-level node
-	 */
-	public static SimpleXML fromDocument(Document document) {
-		SimpleXML xmlDocument = new SimpleXML(document.getFirstChild().getNodeName());
-		NamedNodeMap attributes = document.getFirstChild().getAttributes();
-		for (int attributeIndex = 0, attributeCount = attributes.getLength(); attributeIndex < attributeCount; attributeIndex++) {
-			Node attribute = attributes.item(attributeIndex);
-			logger.log(Level.FINER, "adding attribute: " + attribute.getNodeName() + " = " + attribute.getNodeValue());
-			xmlDocument.setAttribute(attribute.getNodeName(), attribute.getNodeValue());
-		}
-		document.normalizeDocument();
-		/* look for first non-comment node */
-		Node firstChild = null;
-		NodeList children = document.getChildNodes();
-		for (int index = 0, count = children.getLength(); index < count; index++) {
-			Node child = children.item(index);
-			if ((child.getNodeType() != Node.COMMENT_NODE) && (child.getNodeType() != Node.PROCESSING_INSTRUCTION_NODE)) {
-				firstChild = child;
-				break;
-			}
-		}
-		return addDocumentChildren(xmlDocument, firstChild);
-	}
-
-	/**
-	 * Appends the child nodes of the specified {@link Document} to this node.
-	 * Text nodes are converted into a node's value.
-	 *
-	 * @param xmlDocument
-	 *            The SimpleXML node to append the child nodes to
-	 * @param document
-	 *            The document whose child nodes to append
-	 * @return The SimpleXML node the child nodes were appended to
-	 */
-	private static SimpleXML addDocumentChildren(SimpleXML xmlDocument, Node document) {
-		NodeList childNodes = document.getChildNodes();
-		for (int childIndex = 0, childCount = childNodes.getLength(); childIndex < childCount; childIndex++) {
-			Node childNode = childNodes.item(childIndex);
-			if ((childNode.getChildNodes().getLength() == 1) && (childNode.getFirstChild().getNodeName().equals("#text"))) {
-				SimpleXML newXML = xmlDocument.append(childNode.getNodeName(), childNode.getFirstChild().getNodeValue());
-				NamedNodeMap childNodeAttributes = childNode.getAttributes();
-				for (int attributeIndex = 0, attributeCount = childNodeAttributes.getLength(); attributeIndex < attributeCount; attributeIndex++) {
-					Node attribute = childNodeAttributes.item(attributeIndex);
-					logger.log(Level.FINER, "adding attribute: " + attribute.getNodeName() + " = " + attribute.getNodeValue());
-					newXML.setAttribute(attribute.getNodeName(), attribute.getNodeValue());
-				}
-			} else {
-				if ((childNode.getNodeType() == Node.ELEMENT_NODE) || (childNode.getChildNodes().getLength() != 0)) {
-					SimpleXML newXML = xmlDocument.append(childNode.getNodeName());
-					NamedNodeMap childNodeAttributes = childNode.getAttributes();
-					for (int attributeIndex = 0, attributeCount = childNodeAttributes.getLength(); attributeIndex < attributeCount; attributeIndex++) {
-						Node attribute = childNodeAttributes.item(attributeIndex);
-						logger.log(Level.FINER, "adding attribute: " + attribute.getNodeName() + " = " + attribute.getNodeValue());
-						newXML.setAttribute(attribute.getNodeName(), attribute.getNodeValue());
-					}
-					addDocumentChildren(newXML, childNode);
-				}
-			}
-		}
-		return xmlDocument;
-	}
-}
diff --git a/alien/src/net/pterodactylus/util/xml/XML.java b/alien/src/net/pterodactylus/util/xml/XML.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/xml/XML.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * utils - XML.java - Copyright © 2006-2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.xml;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStreamWriter;
-import java.io.Reader;
-import java.io.Writer;
-import java.nio.charset.Charset;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Result;
-import javax.xml.transform.Source;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
-import net.pterodactylus.util.io.Closer;
-import net.pterodactylus.util.logging.Logging;
-
-import org.w3c.dom.Document;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-/**
- * Contains method to transform DOM XML trees to byte arrays and vice versa.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class XML {
-
-	/** The logger. */
-	private static final Logger logger = Logging.getLogger(XML.class.getName());
-
-	/** Cached document builder factory. */
-	private static DocumentBuilderFactory documentBuilderFactory = null;
-
-	/** Cached document builder. */
-	private static DocumentBuilder documentBuilder = null;
-
-	/** Cached transformer factory. */
-	private static TransformerFactory transformerFactory = null;
-
-	/**
-	 * Returns a document builder factory. If possible the cached instance will
-	 * be returned.
-	 *
-	 * @return A document builder factory
-	 */
-	private static DocumentBuilderFactory getDocumentBuilderFactory() {
-		if (documentBuilderFactory != null) {
-			return documentBuilderFactory;
-		}
-		documentBuilderFactory = DocumentBuilderFactory.newInstance();
-		documentBuilderFactory.setXIncludeAware(true);
-		documentBuilderFactory.setNamespaceAware(true);
-		return documentBuilderFactory;
-	}
-
-	/**
-	 * Returns a document builder. If possible the cached instance will be
-	 * returned.
-	 *
-	 * @return A document builder
-	 */
-	private static DocumentBuilder getDocumentBuilder() {
-		if (documentBuilder != null) {
-			return documentBuilder;
-		}
-		try {
-			documentBuilder = getDocumentBuilderFactory().newDocumentBuilder();
-		} catch (ParserConfigurationException pce1) {
-			logger.log(Level.WARNING, "Could not create DocumentBuilder.", pce1);
-		}
-		return documentBuilder;
-	}
-
-	/**
-	 * Returns a transformer factory. If possible the cached instance will be
-	 * returned.
-	 *
-	 * @return A transformer factory
-	 */
-	private static TransformerFactory getTransformerFactory() {
-		if (transformerFactory != null) {
-			return transformerFactory;
-		}
-		transformerFactory = TransformerFactory.newInstance();
-		return transformerFactory;
-	}
-
-	/**
-	 * Creates a new XML document.
-	 *
-	 * @return A new XML document
-	 */
-	public static Document createDocument() {
-		return getDocumentBuilder().newDocument();
-	}
-
-	/**
-	 * Transforms the DOM XML document into a byte array.
-	 *
-	 * @param document
-	 *            The document to transform
-	 * @return The byte array containing the XML representation
-	 */
-	public static byte[] transformToByteArray(Document document) {
-		ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
-		OutputStreamWriter converter = new OutputStreamWriter(byteOutput, Charset.forName("UTF-8"));
-		writeToOutputStream(document, converter);
-		try {
-			converter.flush();
-			byteOutput.flush();
-			byte[] result = byteOutput.toByteArray();
-			return result;
-		} catch (IOException ioe1) {
-			return null;
-		} finally {
-			Closer.close(converter);
-			Closer.close(byteOutput);
-		}
-	}
-
-	/**
-	 * Writes the given document to the given writer.
-	 *
-	 * @param document
-	 *            The document to write
-	 * @param writer
-	 *            The writer to write the document to
-	 */
-	public static void writeToOutputStream(Document document, Writer writer) {
-		writeToOutputStream(document, writer, true);
-	}
-
-	/**
-	 * Writes the given document to the given writer.
-	 *
-	 * @param document
-	 *            The document to write
-	 * @param writer
-	 *            The writer to write the document to
-	 * @param preamble
-	 *            <code>true</code> to include the XML header,
-	 *            <code>false</code> to not include it
-	 */
-	public static void writeToOutputStream(Document document, Writer writer, boolean preamble) {
-		Result transformResult = new StreamResult(writer);
-		Source documentSource = new DOMSource(document);
-		try {
-			Transformer transformer = getTransformerFactory().newTransformer();
-			transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, preamble ? "no" : "yes");
-			transformer.transform(documentSource, transformResult);
-		} catch (TransformerConfigurationException tce1) {
-			logger.log(Level.WARNING, "Could create Transformer.", tce1);
-		} catch (TransformerException te1) {
-			logger.log(Level.WARNING, "Could not transform Document.", te1);
-		}
-	}
-
-	/**
-	 * Transforms the byte array into a DOM XML document.
-	 *
-	 * @param data
-	 *            The byte array to parse
-	 * @return The DOM XML document
-	 */
-	public static Document transformToDocument(byte[] data) {
-		return transformToDocument(new ByteArrayInputStream(data));
-	}
-
-	/**
-	 * Transforms the input stream into a DOM XML document.
-	 *
-	 * @param inputStream
-	 *            The input stream to parse
-	 * @return The DOM XML document
-	 */
-	public static Document transformToDocument(InputStream inputStream) {
-		return transformToDocument(new InputSource(inputStream));
-	}
-
-	/**
-	 * Transforms the reader into a DOM XML document.
-	 *
-	 * @param inputReader
-	 *            The reader to read the XML from
-	 * @return The DOM XML document
-	 */
-	public static Document transformToDocument(Reader inputReader) {
-		return transformToDocument(new InputSource(inputReader));
-	}
-
-	/**
-	 * Transforms the inout source into a DOM XML document.
-	 *
-	 * @param inputSource
-	 *            The source to read the XML from
-	 * @return The DOM XML document
-	 */
-	public static Document transformToDocument(InputSource inputSource) {
-		try {
-			DocumentBuilder documentBuilder = getDocumentBuilder();
-			return documentBuilder.parse(inputSource);
-		} catch (SAXException saxe1) {
-			logger.log(Level.WARNING, "Could not parse InputSource.", saxe1);
-		} catch (IOException ioe1) {
-			logger.log(Level.WARNING, "Could not read InputSource.", ioe1);
-		}
-		return null;
-	}
-
-}
diff --git a/alien/src/net/pterodactylus/util/xml/package-info.java b/alien/src/net/pterodactylus/util/xml/package-info.java
deleted file mode 100644
--- a/alien/src/net/pterodactylus/util/xml/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * Package for XML-related utility classes.
- *
- */
-package net.pterodactylus.util.xml;
\ No newline at end of file