@Override
	public Message decodeMessage(final ByteBuffer buffer) {

		int position = buffer.position();

		if (buffer.get() == BINARY_MESSAGE_PREFIX) {
			byte[] name = new byte[buffer.getShort()];

			buffer.get(name);

			String s = null;

			try {
				s = new String(name, "UTF-8");
			} catch (UnsupportedEncodingException e) {
				// never called
			}

			try {
				Object o = Class.forName(s).newInstance();

				if (o instanceof BinaryMessage) {
					BinaryMessage msg = (BinaryMessage) o;

					msg.decodeMessage(buffer);

					return msg;
				}

			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}

			return null;
		}

		buffer.position(position);

		byte[] buf = new byte[buffer.remaining()];

		buffer.get(buf);

		try (ByteArrayInputStream baos = new ByteArrayInputStream(buf);
				ObjectInputStream ois = new ObjectInputStream(baos)) {

			Object o = ois.readObject();

			if (o instanceof Message) {
				return (Message) o;
			}

		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		return null;
	}