OTR: Update to otr4j-0.22
authorDa Risk <da_risk@beem-project.com>
Sun, 15 Mar 2015 20:41:17 +0100
changeset 1047 9b965359eaea
parent 1046 6ca974ea549b
child 1048 cd41ebc93e78
OTR: Update to otr4j-0.22
app/build.gradle
app/libs/lcrypto-jdk16-146-20110415.jar
app/src/main/java/com/beem/project/beem/otr/BeemOtrManager.java
app/src/main/java/com/beem/project/beem/otr/OtrEngine.java
app/src/main/java/com/beem/project/beem/service/BeemChatManager.java
app/src/main/java/com/beem/project/beem/service/ChatAdapter.java
app/src/main/java/net/java/otr4j/OtrEngine.java
app/src/main/java/net/java/otr4j/OtrEngineHost.java
app/src/main/java/net/java/otr4j/OtrEngineImpl.java
app/src/main/java/net/java/otr4j/OtrEngineListener.java
app/src/main/java/net/java/otr4j/OtrException.java
app/src/main/java/net/java/otr4j/OtrKeyManager.java
app/src/main/java/net/java/otr4j/OtrKeyManagerImpl.java
app/src/main/java/net/java/otr4j/OtrKeyManagerListener.java
app/src/main/java/net/java/otr4j/OtrKeyManagerStore.java
app/src/main/java/net/java/otr4j/OtrPolicy.java
app/src/main/java/net/java/otr4j/OtrPolicyImpl.java
app/src/main/java/net/java/otr4j/crypto/OtrCryptoEngine.java
app/src/main/java/net/java/otr4j/crypto/OtrCryptoEngineImpl.java
app/src/main/java/net/java/otr4j/crypto/OtrCryptoException.java
app/src/main/java/net/java/otr4j/io/OtrInputStream.java
app/src/main/java/net/java/otr4j/io/OtrOutputStream.java
app/src/main/java/net/java/otr4j/io/SerializationConstants.java
app/src/main/java/net/java/otr4j/io/SerializationUtils.java
app/src/main/java/net/java/otr4j/io/messages/AbstractEncodedMessage.java
app/src/main/java/net/java/otr4j/io/messages/AbstractMessage.java
app/src/main/java/net/java/otr4j/io/messages/DHCommitMessage.java
app/src/main/java/net/java/otr4j/io/messages/DHKeyMessage.java
app/src/main/java/net/java/otr4j/io/messages/DataMessage.java
app/src/main/java/net/java/otr4j/io/messages/ErrorMessage.java
app/src/main/java/net/java/otr4j/io/messages/MysteriousT.java
app/src/main/java/net/java/otr4j/io/messages/PlainTextMessage.java
app/src/main/java/net/java/otr4j/io/messages/QueryMessage.java
app/src/main/java/net/java/otr4j/io/messages/RevealSignatureMessage.java
app/src/main/java/net/java/otr4j/io/messages/SignatureM.java
app/src/main/java/net/java/otr4j/io/messages/SignatureMessage.java
app/src/main/java/net/java/otr4j/io/messages/SignatureX.java
app/src/main/java/net/java/otr4j/session/AuthContext.java
app/src/main/java/net/java/otr4j/session/AuthContextImpl.java
app/src/main/java/net/java/otr4j/session/Session.java
app/src/main/java/net/java/otr4j/session/SessionID.java
app/src/main/java/net/java/otr4j/session/SessionImpl.java
app/src/main/java/net/java/otr4j/session/SessionKeys.java
app/src/main/java/net/java/otr4j/session/SessionKeysImpl.java
app/src/main/java/net/java/otr4j/session/SessionStatus.java
--- a/app/build.gradle	Sun Mar 15 18:57:24 2015 +0100
+++ b/app/build.gradle	Sun Mar 15 20:41:17 2015 +0100
@@ -26,7 +26,8 @@
 }
 
 dependencies {
-    compile fileTree(dir: 'libs', include: ['*.jar'])
+    compile fileTree(include: ['*.jar'], dir: 'libs')
+    compile 'org.jitsi:org.otr4j:0.22'
 }
 
 apply from: "$project.rootDir/tools/android-checkstyle.gradle"
Binary file app/libs/lcrypto-jdk16-146-20110415.jar has changed
--- a/app/src/main/java/com/beem/project/beem/otr/BeemOtrManager.java	Sun Mar 15 18:57:24 2015 +0100
+++ b/app/src/main/java/com/beem/project/beem/otr/BeemOtrManager.java	Sun Mar 15 20:41:17 2015 +0100
@@ -31,14 +31,14 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import net.java.otr4j.OtrEngine;
 import net.java.otr4j.OtrEngineHost;
-import net.java.otr4j.OtrEngineImpl;
 import net.java.otr4j.OtrEngineListener;
 import net.java.otr4j.OtrException;
 import net.java.otr4j.OtrKeyManagerImpl;
 import net.java.otr4j.OtrPolicy;
 import net.java.otr4j.OtrPolicyImpl;
+import net.java.otr4j.session.FragmenterInstructions;
+import net.java.otr4j.session.InstanceTag;
 import net.java.otr4j.session.SessionID;
 import net.java.otr4j.session.SessionStatus;
 import android.util.Log;
@@ -53,7 +53,7 @@
     private static final String TAG = "BeemOtrEngineHostImpl";
     private static BeemOtrManager INSTANCE;
     //We will have a global policy for Beem as long as we won't need to modify the policy per chat.
-    private static final OtrPolicy mGlobalPolicy = new OtrPolicyImpl(OtrPolicy.ALLOW_V2 | OtrPolicy.ERROR_START_AKE);
+    private static final OtrPolicy mGlobalPolicy = new OtrPolicyImpl(OtrPolicy.ALLOW_V2 | OtrPolicy.ALLOW_V3 | OtrPolicy.ERROR_START_AKE);
 
     private OtrEngine mOtrEngine;
     private OtrKeyManagerImpl mOtrKeyManager;
@@ -65,8 +65,7 @@
      * Private constructor prevents instantiation from other classes.
      */
     private BeemOtrManager() {
-	mOtrEngine = new OtrEngineImpl(this);
-	mOtrEngine.addOtrEngineListener(new BeemOtrListener());
+	mOtrEngine = new OtrEngine(this, new BeemOtrListener());
 	try {
 	    mOtrKeyManager = new OtrKeyManagerImpl("/sdcard/beem.keystore");
 	} catch (IOException e) {
@@ -125,7 +124,7 @@
      * @param sessionId the current otr session
      */
     public void verifyRemoteFingerprint(final SessionID sessionId) {
-	mOtrKeyManager.verify(sessionId);
+        verify(sessionId, null, true);
     }
 
     /**
@@ -133,7 +132,7 @@
      * @param sessionId the current otr session
      */
     public void unverifyRemoteFingerprint(final SessionID sessionId) {
-	mOtrKeyManager.unverify(sessionId);
+        unverify(sessionId, null);
     }
 
     /**
@@ -152,8 +151,13 @@
     }
 
     @Override
-    public void showWarning(SessionID sessionID, String warning) {
-	Log.d(TAG, "Warning for " + sessionID + " : " + warning);
+    public void unreadableMessageReceived(SessionID sessionID) throws OtrException {
+
+    }
+
+    @Override
+    public void unencryptedMessageReceived(SessionID sessionID, String msg) throws OtrException {
+        mOtrEngine.endSession(sessionID);
     }
 
     @Override
@@ -162,12 +166,78 @@
     }
 
     @Override
+    public void smpError(SessionID sessionID, int tlvType, boolean cheated) throws OtrException {
+        Log.d(TAG, "SmpError for " + sessionID);
+    }
+
+    @Override
+    public void smpAborted(SessionID sessionID) throws OtrException {
+        Log.d(TAG, "SmpAborted for " + sessionID);
+    }
+
+    @Override
+    public void finishedSessionMessage(SessionID sessionID, String msgText) throws OtrException {
+
+    }
+
+    @Override
+    public void requireEncryptedMessage(SessionID sessionID, String msgText) throws OtrException {
+
+    }
+
+    @Override
     public OtrPolicy getSessionPolicy(SessionID sessionID) {
 	return mGlobalPolicy;
     }
 
     @Override
-    public KeyPair getKeyPair(SessionID sessionID) {
+    public FragmenterInstructions getFragmenterInstructions(SessionID sessionID) {
+        return null;
+    }
+
+
+    @Override
+    public byte[] getLocalFingerprintRaw(SessionID sessionID) {
+        return mOtrKeyManager.getLocalFingerprintRaw(sessionID);
+    }
+
+    @Override
+    public void askForSecret(SessionID sessionID, InstanceTag receiverTag, String question) {
+
+    }
+
+    @Override
+    public void verify(SessionID sessionID, String fingerprint, boolean approved) {
+        mOtrKeyManager.verify(sessionID);
+    }
+
+    @Override
+    public void unverify(SessionID sessionID, String fingerprint) {
+        mOtrKeyManager.unverify(sessionID);
+    }
+
+    @Override
+    public String getReplyForUnreadableMessage(SessionID sessionID) {
+        return null;
+    }
+
+    @Override
+    public String getFallbackMessage(SessionID sessionID) {
+        return null;
+    }
+
+    @Override
+    public void messageFromAnotherInstanceReceived(SessionID sessionID) {
+
+    }
+
+    @Override
+    public void multipleInstancesDetected(SessionID sessionID) {
+
+    }
+
+    @Override
+    public KeyPair getLocalKeyPair(SessionID sessionID) throws OtrException {
 	KeyPair kp = mOtrKeyManager.loadLocalKeyPair(sessionID);
 
 	if (kp != null)
@@ -206,5 +276,15 @@
 		}
 	    }
 	}
+
+        @Override
+        public void multipleInstancesDetected(SessionID sessionID) {
+
+        }
+
+        @Override
+        public void outgoingSessionChanged(SessionID sessionID) {
+
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/com/beem/project/beem/otr/OtrEngine.java	Sun Mar 15 20:41:17 2015 +0100
@@ -0,0 +1,75 @@
+
+package com.beem.project.beem.otr;
+
+import net.java.otr4j.OtrEngineHost;
+import net.java.otr4j.OtrEngineListener;
+import net.java.otr4j.OtrException;
+import net.java.otr4j.session.Session;
+import net.java.otr4j.session.SessionID;
+import net.java.otr4j.session.SessionImpl;
+import net.java.otr4j.session.SessionStatus;
+
+import java.security.PublicKey;
+import java.util.Hashtable;
+import java.util.Map;
+
+public class OtrEngine {
+
+	public OtrEngine(OtrEngineHost host, OtrEngineListener listener) {
+		this.host = host;
+		this.listener = listener;
+	}
+
+	private OtrEngineHost host;
+	private Map<SessionID, Session> sessions;
+
+	private Session getSession(SessionID sessionID) {
+
+		if (sessionID == null || sessionID.equals(SessionID.Empty))
+			throw new IllegalArgumentException();
+
+		if (sessions == null)
+			sessions = new Hashtable<SessionID, Session>();
+
+		if (!sessions.containsKey(sessionID)) {
+			Session session = new SessionImpl(sessionID, host);
+			sessions.put(sessionID, session);
+
+			session.addOtrEngineListener(listener);
+			return session;
+		} else
+			return sessions.get(sessionID);
+	}
+
+	public SessionStatus getSessionStatus(SessionID sessionID) {
+		return this.getSession(sessionID).getSessionStatus();
+	}
+
+	public String transformReceiving(SessionID sessionID, String msgText)
+			throws OtrException {
+		return this.getSession(sessionID).transformReceiving(msgText);
+	}
+
+	public String[] transformSending(SessionID sessionID, String msgText)
+			throws OtrException {
+		return this.getSession(sessionID).transformSending(msgText, null);
+	}
+
+	public void endSession(SessionID sessionID) throws OtrException {
+		this.getSession(sessionID).endSession();
+	}
+
+	public void startSession(SessionID sessionID) throws OtrException {
+		this.getSession(sessionID).startSession();
+	}
+
+	public void refreshSession(SessionID sessionID) throws OtrException {
+		this.getSession(sessionID).refreshSession();
+	}
+
+	public PublicKey getRemotePublicKey(SessionID sessionID) {
+		return this.getSession(sessionID).getRemotePublicKey();
+	}
+
+	private final OtrEngineListener listener;
+}
--- a/app/src/main/java/com/beem/project/beem/service/BeemChatManager.java	Sun Mar 15 18:57:24 2015 +0100
+++ b/app/src/main/java/com/beem/project/beem/service/BeemChatManager.java	Sun Mar 15 20:41:17 2015 +0100
@@ -397,7 +397,7 @@
 		return;
 	    }
 
-	    if (Status.getStatusFromPresence(presence) >= Status.CONTACT_STATUS_DISCONNECT) {
+	    if (Status.getStatusFromPresence(presence) <= Status.CONTACT_STATUS_DISCONNECT) {
 		try {
 		    mChats.get(key).localEndOtrSession();
 		} catch (OtrException e) {
--- a/app/src/main/java/com/beem/project/beem/service/ChatAdapter.java	Sun Mar 15 18:57:24 2015 +0100
+++ b/app/src/main/java/com/beem/project/beem/service/ChatAdapter.java	Sun Mar 15 20:41:17 2015 +0100
@@ -332,10 +332,15 @@
 
 	if (mOtrSessionId != null && unencrypted != null && unencrypted.getBody() != null) {
 	    try {
-		String body = BeemOtrManager.getInstance().getOtrManager()
+
+		String[] bodies = BeemOtrManager.getInstance().getOtrManager()
 		    .transformSending(mOtrSessionId, unencrypted.getBody());
+			StringBuilder concatBody = new StringBuilder();
+			for(String body: bodies) {
+				concatBody.append(body);
+			}
 		Message result = new Message(unencrypted.getTo(), unencrypted.getType());
-		result.setBody(body);
+		result.setBody(concatBody.toString());
 		return result;
 	    } catch (OtrException e) {
 		Log.e(TAG, "OTR: Unable to encrypt message", e);
--- a/app/src/main/java/net/java/otr4j/OtrEngine.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-package net.java.otr4j;
-
-import java.security.PublicKey;
-
-import net.java.otr4j.session.SessionID;
-import net.java.otr4j.session.SessionStatus;
-
-/**
- * 
- * @author George Politis
- * 
- */
-public interface OtrEngine {
-
-	/**
-	 * 
-	 * @param sessionID
-	 *            The session identifier.
-	 * @param content
-	 *            The message content to be transformed.
-	 * @return The transformed message content.
-	 * @throws OtrException 
-	 */
-	public abstract String transformReceiving(SessionID sessionID,
-			String content) throws OtrException;
-
-	/**
-	 * 
-	 * @param sessionID
-	 *            The session identifier.
-	 * @param content
-	 *            The message content to be transformed.
-	 * @return The transformed message content.
-	 * @throws OtrException 
-	 */
-	public abstract String transformSending(SessionID sessionID, String content) throws OtrException;
-
-	/**
-	 * Starts an Off-the-Record session, if there is no active one.
-	 * 
-	 * @param sessionID
-	 *            The session identifier.
-	 * @throws OtrException 
-	 */
-	public abstract void startSession(SessionID sessionID) throws OtrException;
-
-	/**
-	 * Ends the Off-the-Record session, if exists.
-	 * 
-	 * @param sessionID
-	 *            The session identifier.
-	 * @throws OtrException 
-	 */
-	public abstract void endSession(SessionID sessionID) throws OtrException;
-
-	/**
-	 * Stops/Starts the Off-the-Record session.
-	 * 
-	 * @param sessionID
-	 *            The session identifier.
-	 * @throws OtrException 
-	 */
-	public abstract void refreshSession(SessionID sessionID) throws OtrException;
-
-	/**
-	 * 
-	 * @param sessionID
-	 *            The session identifier.
-	 * @return The status of an Off-the-Record session.
-	 */
-	public abstract SessionStatus getSessionStatus(SessionID sessionID);
-
-	/**
-	 * 
-	 * @param sessionID
-	 *            The session identifier.
-	 * @return The remote public key.
-	 */
-	public abstract PublicKey getRemotePublicKey(SessionID sessionID);
-
-	public abstract void addOtrEngineListener(OtrEngineListener l);
-
-	public abstract void removeOtrEngineListener(OtrEngineListener l);
-}
--- a/app/src/main/java/net/java/otr4j/OtrEngineHost.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j;
-
-import java.security.KeyPair;
-
-import net.java.otr4j.session.SessionID;
-
-/**
- * 
- * This interface should be implemented by the host application. It is required
- * for otr4j to work properly.
- * 
- * @author George Politis
- * 
- */
-public abstract interface OtrEngineHost {
-	public abstract void injectMessage(SessionID sessionID, String msg);
-
-	public abstract void showWarning(SessionID sessionID, String warning);
-
-	public abstract void showError(SessionID sessionID, String error);
-
-	public abstract OtrPolicy getSessionPolicy(SessionID sessionID);
-
-	public abstract KeyPair getKeyPair(SessionID sessionID);
-}
--- a/app/src/main/java/net/java/otr4j/OtrEngineImpl.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
- * otr4j, the open source java otr librar
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-package net.java.otr4j;
-
-import java.security.PublicKey;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-import java.util.Vector;
-
-import net.java.otr4j.session.Session;
-import net.java.otr4j.session.SessionID;
-import net.java.otr4j.session.SessionImpl;
-import net.java.otr4j.session.SessionStatus;
-
-/**
- * 
- * @author George Politis
- * 
- */
-public class OtrEngineImpl implements OtrEngine {
-
-	public OtrEngineImpl(OtrEngineHost host) {
-		if (host == null)
-			throw new IllegalArgumentException("OtrEgineHost is required.");
-
-		this.setHost(host);
-	}
-
-	private OtrEngineHost host;
-	private Map<SessionID, Session> sessions;
-
-	private Session getSession(SessionID sessionID) {
-
-		if (sessionID == null || sessionID.equals(SessionID.Empty))
-			throw new IllegalArgumentException();
-
-		if (sessions == null)
-			sessions = new Hashtable<SessionID, Session>();
-
-		if (!sessions.containsKey(sessionID)) {
-			Session session = new SessionImpl(sessionID, getHost());
-			sessions.put(sessionID, session);
-
-			session.addOtrEngineListener(new OtrEngineListener() {
-
-				public void sessionStatusChanged(SessionID sessionID) {
-					for (OtrEngineListener l : listeners)
-						l.sessionStatusChanged(sessionID);
-				}
-			});
-			return session;
-		} else
-			return sessions.get(sessionID);
-	}
-
-	public SessionStatus getSessionStatus(SessionID sessionID) {
-		return this.getSession(sessionID).getSessionStatus();
-	}
-
-	public String transformReceiving(SessionID sessionID, String msgText)
-			throws OtrException {
-		return this.getSession(sessionID).transformReceiving(msgText);
-	}
-
-	public String transformSending(SessionID sessionID, String msgText)
-			throws OtrException {
-		return this.getSession(sessionID).transformSending(msgText, null);
-	}
-
-	public void endSession(SessionID sessionID) throws OtrException {
-		this.getSession(sessionID).endSession();
-	}
-
-	public void startSession(SessionID sessionID) throws OtrException {
-		this.getSession(sessionID).startSession();
-	}
-
-	private void setHost(OtrEngineHost host) {
-		this.host = host;
-	}
-
-	private OtrEngineHost getHost() {
-		return host;
-	}
-
-	public void refreshSession(SessionID sessionID) throws OtrException {
-		this.getSession(sessionID).refreshSession();
-	}
-
-	public PublicKey getRemotePublicKey(SessionID sessionID) {
-		return this.getSession(sessionID).getRemotePublicKey();
-	}
-
-	private List<OtrEngineListener> listeners = new Vector<OtrEngineListener>();
-
-	public void addOtrEngineListener(OtrEngineListener l) {
-		synchronized (listeners) {
-			if (!listeners.contains(l))
-				listeners.add(l);
-		}
-	}
-
-	public void removeOtrEngineListener(OtrEngineListener l) {
-		synchronized (listeners) {
-			listeners.remove(l);
-		}
-	}
-}
--- a/app/src/main/java/net/java/otr4j/OtrEngineListener.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-package net.java.otr4j;
-
-import net.java.otr4j.session.SessionID;
-
-/**
- * This interface should be implemented by the host application. It notifies
- * about session status changes.
- * 
- * @author George Politis
- * 
- */
-public interface OtrEngineListener {
-	public abstract void sessionStatusChanged(SessionID sessionID);
-}
--- a/app/src/main/java/net/java/otr4j/OtrException.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-package net.java.otr4j;
-
-
-public class OtrException extends Exception {
-    private static final long serialVersionUID = 1L;
-
-    public OtrException(Exception e){
-	super(e);
-    }
-}
--- a/app/src/main/java/net/java/otr4j/OtrKeyManager.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-package net.java.otr4j;
-
-import java.security.KeyPair;
-import java.security.PublicKey;
-
-import net.java.otr4j.session.SessionID;
-
-public abstract interface OtrKeyManager {
-
-	public abstract void addListener(OtrKeyManagerListener l);
-
-	public abstract void removeListener(OtrKeyManagerListener l);
-
-	public abstract void verify(SessionID sessionID);
-
-	public abstract void unverify(SessionID sessionID);
-
-	public abstract boolean isVerified(SessionID sessionID);
-
-	public abstract String getRemoteFingerprint(SessionID sessionID);
-
-	public abstract String getLocalFingerprint(SessionID sessionID);
-
-	public abstract void savePublicKey(SessionID sessionID, PublicKey pubKey);
-
-	public abstract PublicKey loadRemotePublicKey(SessionID sessionID);
-
-	public abstract KeyPair loadLocalKeyPair(SessionID sessionID);
-
-	public abstract void generateLocalKeyPair(SessionID sessionID);
-}
--- a/app/src/main/java/net/java/otr4j/OtrKeyManagerImpl.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,304 +0,0 @@
-package net.java.otr4j;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.List;
-import java.util.Properties;
-import java.util.Vector;
-
-import org.bouncycastle2.util.encoders.Base64;
-
-import net.java.otr4j.crypto.OtrCryptoEngineImpl;
-import net.java.otr4j.crypto.OtrCryptoException;
-import net.java.otr4j.session.SessionID;
-
-public class OtrKeyManagerImpl implements OtrKeyManager {
-
-	private OtrKeyManagerStore store;
-
-	public OtrKeyManagerImpl(OtrKeyManagerStore store) {
-		this.store = store;
-	}
-
-	class DefaultPropertiesStore implements OtrKeyManagerStore {
-		private final Properties properties = new Properties();
-		private String filepath;
-
-		public DefaultPropertiesStore(String filepath) throws IOException {
-			if (filepath == null || filepath.length() < 1)
-				throw new IllegalArgumentException();
-			this.filepath = filepath;
-			properties.clear();
-
-			InputStream in = new BufferedInputStream(new FileInputStream(
-					getConfigurationFile()));
-			try {
-				properties.load(in);
-			} finally {
-				in.close();
-			}
-		}
-
-		private File getConfigurationFile() throws IOException {
-			File configFile = new File(filepath);
-			if (!configFile.exists())
-				configFile.createNewFile();
-			return configFile;
-		}
-
-		public void setProperty(String id, boolean value) {
-			properties.setProperty(id, "true");
-			try {
-				this.store();
-			} catch (Exception e) {
-				e.printStackTrace();
-			}
-		}
-
-		private void store() throws FileNotFoundException, IOException {
-			OutputStream out = new FileOutputStream(getConfigurationFile());
-			properties.store(out, null);
-			out.close();
-		}
-
-		public void setProperty(String id, byte[] value) {
-			properties.setProperty(id, new String(Base64.encode(value)));
-			try {
-				this.store();
-			} catch (Exception e) {
-				e.printStackTrace();
-			}
-		}
-
-		public void removeProperty(String id) {
-			properties.remove(id);
-
-		}
-
-		public byte[] getPropertyBytes(String id) {
-			String value = properties.getProperty(id);
-			if (value == null)
-			    return null;
-			return Base64.decode(value);
-		}
-
-		public boolean getPropertyBoolean(String id, boolean defaultValue) {
-			try {
-				return Boolean.valueOf(properties.get(id).toString());
-			} catch (Exception e) {
-				return defaultValue;
-			}
-		}
-	}
-
-	public OtrKeyManagerImpl(String filepath) throws IOException {
-		this.store = new DefaultPropertiesStore(filepath);
-	}
-
-	private List<OtrKeyManagerListener> listeners = new Vector<OtrKeyManagerListener>();
-
-	public void addListener(OtrKeyManagerListener l) {
-		synchronized (listeners) {
-			if (!listeners.contains(l))
-				listeners.add(l);
-		}
-	}
-
-	public void removeListener(OtrKeyManagerListener l) {
-		synchronized (listeners) {
-			listeners.remove(l);
-		}
-	}
-
-	public void generateLocalKeyPair(SessionID sessionID) {
-		if (sessionID == null)
-			return;
-
-		String accountID = sessionID.getAccountID();
-		KeyPair keyPair;
-		try {
-			keyPair = KeyPairGenerator.getInstance("DSA").genKeyPair();
-		} catch (NoSuchAlgorithmException e) {
-			e.printStackTrace();
-			return;
-		}
-
-		// Store Public Key.
-		PublicKey pubKey = keyPair.getPublic();
-		X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(pubKey
-				.getEncoded());
-
-		this.store.setProperty(accountID + ".publicKey", x509EncodedKeySpec
-				.getEncoded());
-
-		// Store Private Key.
-		PrivateKey privKey = keyPair.getPrivate();
-		PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
-				privKey.getEncoded());
-
-		this.store.setProperty(accountID + ".privateKey", pkcs8EncodedKeySpec
-				.getEncoded());
-	}
-
-	public String getLocalFingerprint(SessionID sessionID) {
-		KeyPair keyPair = loadLocalKeyPair(sessionID);
-
-		if (keyPair == null)
-			return null;
-
-		PublicKey pubKey = keyPair.getPublic();
-
-		try {
-			return new OtrCryptoEngineImpl().getFingerprint(pubKey);
-		} catch (OtrCryptoException e) {
-			e.printStackTrace();
-			return null;
-		}
-	}
-
-	public String getRemoteFingerprint(SessionID sessionID) {
-		PublicKey remotePublicKey = loadRemotePublicKey(sessionID);
-		if (remotePublicKey == null)
-			return null;
-		try {
-			return new OtrCryptoEngineImpl().getFingerprint(remotePublicKey);
-		} catch (OtrCryptoException e) {
-			e.printStackTrace();
-			return null;
-		}
-	}
-
-	public boolean isVerified(SessionID sessionID) {
-		if (sessionID == null)
-			return false;
-
-		return this.store.getPropertyBoolean(sessionID.getUserID()
-				+ ".publicKey.verified", false);
-	}
-
-	public KeyPair loadLocalKeyPair(SessionID sessionID) {
-		if (sessionID == null)
-			return null;
-
-		String accountID = sessionID.getAccountID();
-		// Load Private Key.
-		byte[] b64PrivKey = this.store.getPropertyBytes(accountID
-				+ ".privateKey");
-		if (b64PrivKey == null)
-			return null;
-
-		PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(b64PrivKey);
-
-		// Load Public Key.
-		byte[] b64PubKey = this.store
-				.getPropertyBytes(accountID + ".publicKey");
-		if (b64PubKey == null)
-			return null;
-
-		X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(b64PubKey);
-
-		PublicKey publicKey;
-		PrivateKey privateKey;
-
-		// Generate KeyPair.
-		KeyFactory keyFactory;
-		try {
-			keyFactory = KeyFactory.getInstance("DSA");
-			publicKey = keyFactory.generatePublic(publicKeySpec);
-			privateKey = keyFactory.generatePrivate(privateKeySpec);
-		} catch (NoSuchAlgorithmException e) {
-			e.printStackTrace();
-			return null;
-		} catch (InvalidKeySpecException e) {
-			e.printStackTrace();
-			return null;
-		}
-
-		return new KeyPair(publicKey, privateKey);
-	}
-
-	public PublicKey loadRemotePublicKey(SessionID sessionID) {
-		if (sessionID == null)
-			return null;
-
-		String userID = sessionID.getUserID();
-
-		byte[] b64PubKey = this.store.getPropertyBytes(userID + ".publicKey");
-		if (b64PubKey == null)
-			return null;
-
-		X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(b64PubKey);
-
-		// Generate KeyPair.
-		KeyFactory keyFactory;
-		try {
-			keyFactory = KeyFactory.getInstance("DSA");
-			return keyFactory.generatePublic(publicKeySpec);
-		} catch (NoSuchAlgorithmException e) {
-			e.printStackTrace();
-			return null;
-		} catch (InvalidKeySpecException e) {
-			e.printStackTrace();
-			return null;
-		}
-	}
-
-	public void savePublicKey(SessionID sessionID, PublicKey pubKey) {
-		if (sessionID == null)
-			return;
-
-		X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(pubKey
-				.getEncoded());
-
-		String userID = sessionID.getUserID();
-		this.store.setProperty(userID + ".publicKey", x509EncodedKeySpec
-				.getEncoded());
-
-		this.store.removeProperty(userID + ".publicKey.verified");
-	}
-
-	public void unverify(SessionID sessionID) {
-		if (sessionID == null)
-			return;
-
-		if (!isVerified(sessionID))
-			return;
-
-		this.store
-				.removeProperty(sessionID.getUserID() + ".publicKey.verified");
-
-		for (OtrKeyManagerListener l : listeners)
-			l.verificationStatusChanged(sessionID);
-
-	}
-
-	public void verify(SessionID sessionID) {
-		if (sessionID == null)
-			return;
-
-		if (this.isVerified(sessionID))
-			return;
-
-		this.store.setProperty(sessionID.getUserID() + ".publicKey.verified",
-				true);
-
-		for (OtrKeyManagerListener l : listeners)
-			l.verificationStatusChanged(sessionID);
-	}
-
-}
--- a/app/src/main/java/net/java/otr4j/OtrKeyManagerListener.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-package net.java.otr4j;
-
-import net.java.otr4j.session.SessionID;
-
-public interface OtrKeyManagerListener {
-	public abstract void verificationStatusChanged(SessionID session);
-}
--- a/app/src/main/java/net/java/otr4j/OtrKeyManagerStore.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-package net.java.otr4j;
-
-public interface OtrKeyManagerStore {
-	public abstract byte[] getPropertyBytes(String id);
-
-	public abstract boolean getPropertyBoolean(String id, boolean defaultValue);
-
-	public abstract void setProperty(String id, byte[] value);
-
-	public abstract void setProperty(String id, boolean value);
-
-	public abstract void removeProperty(String id);
-}
--- a/app/src/main/java/net/java/otr4j/OtrPolicy.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j;
-
-/**
- * 
- * @author George Politis
- * 
- */
-public interface OtrPolicy {
-
-	public static final int ALLOW_V1 = 0x01;
-	public static final int ALLOW_V2 = 0x02;
-	public static final int REQUIRE_ENCRYPTION = 0x04;
-	public static final int SEND_WHITESPACE_TAG = 0x08;
-	public static final int WHITESPACE_START_AKE = 0x10;
-	public static final int ERROR_START_AKE = 0x20;
-	public static final int VERSION_MASK = (ALLOW_V1 | ALLOW_V2);
-
-	// The four old version 1 policies correspond to the following combinations
-	// of flags (adding an allowance for version 2 of the protocol):
-
-	public static final int NEVER = 0x00;
-	public static final int OPPORTUNISTIC = (ALLOW_V1 | ALLOW_V2
-			| SEND_WHITESPACE_TAG | WHITESPACE_START_AKE | ERROR_START_AKE);
-	public static final int OTRL_POLICY_MANUAL = (ALLOW_V1 | ALLOW_V2);
-	public static final int OTRL_POLICY_ALWAYS = (ALLOW_V1 | ALLOW_V2
-			| REQUIRE_ENCRYPTION | WHITESPACE_START_AKE | ERROR_START_AKE);
-	public static final int OTRL_POLICY_DEFAULT = OPPORTUNISTIC;
-
-	public abstract boolean getAllowV1();
-
-	public abstract boolean getAllowV2();
-
-	public abstract boolean getRequireEncryption();
-
-	public abstract boolean getSendWhitespaceTag();
-
-	public abstract boolean getWhitespaceStartAKE();
-
-	public abstract boolean getErrorStartAKE();
-
-	public abstract int getPolicy();
-
-	public abstract void setAllowV1(boolean value);
-
-	public abstract void setAllowV2(boolean value);
-
-	public abstract void setRequireEncryption(boolean value);
-
-	public abstract void setSendWhitespaceTag(boolean value);
-
-	public abstract void setWhitespaceStartAKE(boolean value);
-
-	public abstract void setErrorStartAKE(boolean value);
-
-	public abstract void setEnableAlways(boolean value);
-
-	public abstract boolean getEnableAlways();
-
-	public abstract void setEnableManual(boolean value);
-
-	public abstract boolean getEnableManual();
-}
--- a/app/src/main/java/net/java/otr4j/OtrPolicyImpl.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-package net.java.otr4j;
-
-public class OtrPolicyImpl implements OtrPolicy {
-
-	public OtrPolicyImpl() {
-		this.setPolicy(NEVER);
-	}
-
-	public OtrPolicyImpl(int policy) {
-		this.setPolicy(policy);
-	}
-
-	private int policy;
-
-	public int getPolicy() {
-		return policy;
-	}
-
-	private void setPolicy(int policy) {
-		this.policy = policy;
-	}
-
-	public boolean getAllowV1() {
-		return (policy & OtrPolicy.ALLOW_V1) != 0;
-	}
-
-	public boolean getAllowV2() {
-		return (policy & OtrPolicy.ALLOW_V2) != 0;
-	}
-
-	public boolean getErrorStartAKE() {
-		return (policy & OtrPolicy.ERROR_START_AKE) != 0;
-	}
-
-	public boolean getRequireEncryption() {
-		return getEnableManual()
-				&& (policy & OtrPolicy.REQUIRE_ENCRYPTION) != 0;
-	}
-
-	public boolean getSendWhitespaceTag() {
-		return (policy & OtrPolicy.SEND_WHITESPACE_TAG) != 0;
-	}
-
-	public boolean getWhitespaceStartAKE() {
-		return (policy & OtrPolicy.WHITESPACE_START_AKE) != 0;
-	}
-
-	public void setAllowV1(boolean value) {
-		if (value)
-			policy |= ALLOW_V1;
-		else
-			policy &= ~ALLOW_V1;
-	}
-
-	public void setAllowV2(boolean value) {
-		if (value)
-			policy |= ALLOW_V2;
-		else
-			policy &= ~ALLOW_V2;
-	}
-
-	public void setErrorStartAKE(boolean value) {
-		if (value)
-			policy |= ERROR_START_AKE;
-		else
-			policy &= ~ERROR_START_AKE;
-	}
-
-	public void setRequireEncryption(boolean value) {
-		if (value)
-			policy |= REQUIRE_ENCRYPTION;
-		else
-			policy &= ~REQUIRE_ENCRYPTION;
-	}
-
-	public void setSendWhitespaceTag(boolean value) {
-		if (value)
-			policy |= SEND_WHITESPACE_TAG;
-		else
-			policy &= ~SEND_WHITESPACE_TAG;
-	}
-
-	public void setWhitespaceStartAKE(boolean value) {
-		if (value)
-			policy |= WHITESPACE_START_AKE;
-		else
-			policy &= ~WHITESPACE_START_AKE;
-	}
-
-	public boolean getEnableAlways() {
-		return getEnableManual() && getErrorStartAKE()
-				&& getSendWhitespaceTag() && getWhitespaceStartAKE();
-	}
-
-	public void setEnableAlways(boolean value) {
-		if (value)
-			setEnableManual(true);
-
-		setErrorStartAKE(value);
-		setSendWhitespaceTag(value);
-		setWhitespaceStartAKE(value);
-
-	}
-
-	public boolean getEnableManual() {
-		return getAllowV1() && getAllowV2();
-	}
-
-	public void setEnableManual(boolean value) {
-		setAllowV1(value);
-		setAllowV2(value);
-	}
-
-	public boolean equals(Object obj) {
-		if (obj == this)
-			return true;
-		if (obj == null || obj.getClass() != this.getClass())
-			return false;
-
-		OtrPolicy policy = (OtrPolicy) obj;
-
-		return policy.getPolicy() == this.getPolicy();
-	}
-
-	public int hashCode() {
-		return this.getPolicy();
-	}
-}
--- a/app/src/main/java/net/java/otr4j/crypto/OtrCryptoEngine.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-package net.java.otr4j.crypto;
-
-import java.math.BigInteger;
-import java.security.KeyPair;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-
-import javax.crypto.interfaces.DHPublicKey;
-
-/**
- * 
- * @author George Politis
- * 
- */
-public interface OtrCryptoEngine {
-
-	public static final String MODULUS_TEXT = "00FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF";
-	public static final BigInteger MODULUS = new BigInteger(MODULUS_TEXT, 16);
-	public static final BigInteger BIGINTEGER_TWO = BigInteger.valueOf(2);
-	public static final BigInteger MODULUS_MINUS_TWO = MODULUS
-			.subtract(BIGINTEGER_TWO);
-
-	public static String GENERATOR_TEXT = "2";
-	public static BigInteger GENERATOR = new BigInteger(GENERATOR_TEXT, 10);
-
-	public static final int AES_KEY_BYTE_LENGTH = 16;
-	public static final int SHA256_HMAC_KEY_BYTE_LENGTH = 32;
-	public static final int DH_PRIVATE_KEY_MINIMUM_BIT_LENGTH = 320;
-	public static final byte[] ZERO_CTR = new byte[] { 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00 };
-
-	public static final int DSA_PUB_TYPE = 0;
-
-	public abstract KeyPair generateDHKeyPair() throws OtrCryptoException;
-
-	public abstract DHPublicKey getDHPublicKey(byte[] mpiBytes)
-			throws OtrCryptoException;
-
-	public abstract DHPublicKey getDHPublicKey(BigInteger mpi)
-			throws OtrCryptoException;
-
-	public abstract byte[] sha256Hmac(byte[] b, byte[] key)
-			throws OtrCryptoException;
-
-	public abstract byte[] sha256Hmac(byte[] b, byte[] key, int length)
-			throws OtrCryptoException;
-
-	public abstract byte[] sha1Hmac(byte[] b, byte[] key, int length)
-			throws OtrCryptoException;
-
-	public abstract byte[] sha256Hmac160(byte[] b, byte[] key)
-			throws OtrCryptoException;
-
-	public abstract byte[] sha256Hash(byte[] b) throws OtrCryptoException;
-
-	public abstract byte[] sha1Hash(byte[] b) throws OtrCryptoException;
-
-	public abstract byte[] aesDecrypt(byte[] key, byte[] ctr, byte[] b)
-			throws OtrCryptoException;
-
-	public abstract byte[] aesEncrypt(byte[] key, byte[] ctr, byte[] b)
-			throws OtrCryptoException;
-
-	public abstract BigInteger generateSecret(PrivateKey privKey,
-			PublicKey pubKey) throws OtrCryptoException;
-
-	public abstract byte[] sign(byte[] b, PrivateKey privatekey)
-			throws OtrCryptoException;
-
-	public abstract boolean verify(byte[] b, PublicKey pubKey, byte[] rs)
-			throws OtrCryptoException;
-
-	public abstract String getFingerprint(PublicKey pubKey)
-			throws OtrCryptoException;
-}
--- a/app/src/main/java/net/java/otr4j/crypto/OtrCryptoEngineImpl.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,393 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.crypto;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.security.InvalidKeyException;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.interfaces.DSAPublicKey;
-
-import javax.crypto.KeyAgreement;
-import javax.crypto.interfaces.DHPrivateKey;
-import javax.crypto.interfaces.DHPublicKey;
-import javax.crypto.spec.DHPrivateKeySpec;
-import javax.crypto.spec.DHPublicKeySpec;
-import javax.crypto.spec.SecretKeySpec;
-
-import net.java.otr4j.io.SerializationUtils;
-
-import org.bouncycastle2.crypto.AsymmetricCipherKeyPair;
-import org.bouncycastle2.crypto.BufferedBlockCipher;
-import org.bouncycastle2.crypto.engines.AESFastEngine;
-import org.bouncycastle2.crypto.generators.DHKeyPairGenerator;
-import org.bouncycastle2.crypto.modes.SICBlockCipher;
-import org.bouncycastle2.crypto.params.DHKeyGenerationParameters;
-import org.bouncycastle2.crypto.params.DHParameters;
-import org.bouncycastle2.crypto.params.DHPrivateKeyParameters;
-import org.bouncycastle2.crypto.params.DHPublicKeyParameters;
-import org.bouncycastle2.crypto.params.DSAParameters;
-import org.bouncycastle2.crypto.params.DSAPrivateKeyParameters;
-import org.bouncycastle2.crypto.params.DSAPublicKeyParameters;
-import org.bouncycastle2.crypto.params.KeyParameter;
-import org.bouncycastle2.crypto.params.ParametersWithIV;
-import org.bouncycastle2.crypto.signers.DSASigner;
-import org.bouncycastle2.util.BigIntegers;
-
-/**
- * 
- * @author George Politis
- * 
- */
-public class OtrCryptoEngineImpl implements OtrCryptoEngine {
-
-	public KeyPair generateDHKeyPair() throws OtrCryptoException {
-
-		// Generate a AsymmetricCipherKeyPair using BC.
-		DHParameters dhParams = new DHParameters(MODULUS, GENERATOR, null,
-				DH_PRIVATE_KEY_MINIMUM_BIT_LENGTH);
-		DHKeyGenerationParameters params = new DHKeyGenerationParameters(
-				new SecureRandom(), dhParams);
-		DHKeyPairGenerator kpGen = new DHKeyPairGenerator();
-
-		kpGen.init(params);
-		AsymmetricCipherKeyPair pair = kpGen.generateKeyPair();
-
-		// Convert this AsymmetricCipherKeyPair to a standard JCE KeyPair.
-		DHPublicKeyParameters pub = (DHPublicKeyParameters) pair.getPublic();
-		DHPrivateKeyParameters priv = (DHPrivateKeyParameters) pair
-				.getPrivate();
-
-		try {
-			KeyFactory keyFac = KeyFactory.getInstance("DH");
-
-			DHPublicKeySpec pubKeySpecs = new DHPublicKeySpec(pub.getY(),
-					MODULUS, GENERATOR);
-			DHPublicKey pubKey = (DHPublicKey) keyFac
-					.generatePublic(pubKeySpecs);
-
-			DHParameters dhParameters = priv.getParameters();
-			DHPrivateKeySpec privKeySpecs = new DHPrivateKeySpec(priv.getX(),
-					dhParameters.getP(), dhParameters.getG());
-			DHPrivateKey privKey = (DHPrivateKey) keyFac
-					.generatePrivate(privKeySpecs);
-
-			return new KeyPair(pubKey, privKey);
-		} catch (Exception e) {
-			throw new OtrCryptoException(e);
-		}
-	}
-
-	public DHPublicKey getDHPublicKey(byte[] mpiBytes)
-			throws OtrCryptoException {
-		return getDHPublicKey(new BigInteger(mpiBytes));
-	}
-
-	public DHPublicKey getDHPublicKey(BigInteger mpi) throws OtrCryptoException {
-		DHPublicKeySpec pubKeySpecs = new DHPublicKeySpec(mpi, MODULUS,
-				GENERATOR);
-		try {
-			KeyFactory keyFac = KeyFactory.getInstance("DH");
-			return (DHPublicKey) keyFac.generatePublic(pubKeySpecs);
-		} catch (Exception e) {
-			throw new OtrCryptoException(e);
-		}
-	}
-
-	public byte[] sha256Hmac(byte[] b, byte[] key) throws OtrCryptoException {
-		return this.sha256Hmac(b, key, 0);
-	}
-
-	public byte[] sha256Hmac(byte[] b, byte[] key, int length)
-			throws OtrCryptoException {
-
-		SecretKeySpec keyspec = new SecretKeySpec(key, "HmacSHA256");
-		javax.crypto.Mac mac;
-		try {
-			mac = javax.crypto.Mac.getInstance("HmacSHA256");
-		} catch (NoSuchAlgorithmException e) {
-			throw new OtrCryptoException(e);
-		}
-		try {
-			mac.init(keyspec);
-		} catch (InvalidKeyException e) {
-			throw new OtrCryptoException(e);
-		}
-
-		byte[] macBytes = mac.doFinal(b);
-
-		if (length > 0) {
-			byte[] bytes = new byte[length];
-			ByteBuffer buff = ByteBuffer.wrap(macBytes);
-			buff.get(bytes);
-			return bytes;
-		} else {
-			return macBytes;
-		}
-	}
-
-	public byte[] sha1Hmac(byte[] b, byte[] key, int length)
-			throws OtrCryptoException {
-
-		try {
-			SecretKeySpec keyspec = new SecretKeySpec(key, "HmacSHA1");
-			javax.crypto.Mac mac = javax.crypto.Mac.getInstance("HmacSHA1");
-			mac.init(keyspec);
-
-			byte[] macBytes = mac.doFinal(b);
-
-			if (length > 0) {
-				byte[] bytes = new byte[length];
-				ByteBuffer buff = ByteBuffer.wrap(macBytes);
-				buff.get(bytes);
-				return bytes;
-			} else {
-				return macBytes;
-			}
-		} catch (Exception e) {
-			throw new OtrCryptoException(e);
-		}
-	}
-
-	public byte[] sha256Hmac160(byte[] b, byte[] key) throws OtrCryptoException {
-		return sha256Hmac(b, key, 20);
-	}
-
-	public byte[] sha256Hash(byte[] b) throws OtrCryptoException {
-		try {
-			MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
-			sha256.update(b, 0, b.length);
-			return sha256.digest();
-		} catch (Exception e) {
-			throw new OtrCryptoException(e);
-		}
-	}
-
-	public byte[] sha1Hash(byte[] b) throws OtrCryptoException {
-		try {
-			MessageDigest sha256 = MessageDigest.getInstance("SHA-1");
-			sha256.update(b, 0, b.length);
-			return sha256.digest();
-		} catch (Exception e) {
-			throw new OtrCryptoException(e);
-		}
-	}
-
-	public byte[] aesDecrypt(byte[] key, byte[] ctr, byte[] b)
-			throws OtrCryptoException {
-
-		AESFastEngine aesDec = new AESFastEngine();
-		SICBlockCipher sicAesDec = new SICBlockCipher(aesDec);
-		BufferedBlockCipher bufSicAesDec = new BufferedBlockCipher(sicAesDec);
-
-		// Create initial counter value 0.
-		if (ctr == null)
-			ctr = ZERO_CTR;
-		bufSicAesDec.init(false, new ParametersWithIV(new KeyParameter(key),
-				ctr));
-		byte[] aesOutLwDec = new byte[b.length];
-		int done = bufSicAesDec.processBytes(b, 0, b.length, aesOutLwDec, 0);
-		try {
-			bufSicAesDec.doFinal(aesOutLwDec, done);
-		} catch (Exception e) {
-			throw new OtrCryptoException(e);
-		}
-
-		return aesOutLwDec;
-	}
-
-	public byte[] aesEncrypt(byte[] key, byte[] ctr, byte[] b)
-			throws OtrCryptoException {
-
-		AESFastEngine aesEnc = new AESFastEngine();
-		SICBlockCipher sicAesEnc = new SICBlockCipher(aesEnc);
-		BufferedBlockCipher bufSicAesEnc = new BufferedBlockCipher(sicAesEnc);
-
-		// Create initial counter value 0.
-		if (ctr == null)
-			ctr = ZERO_CTR;
-		bufSicAesEnc.init(true,
-				new ParametersWithIV(new KeyParameter(key), ctr));
-		byte[] aesOutLwEnc = new byte[b.length];
-		int done = bufSicAesEnc.processBytes(b, 0, b.length, aesOutLwEnc, 0);
-		try {
-			bufSicAesEnc.doFinal(aesOutLwEnc, done);
-		} catch (Exception e) {
-			throw new OtrCryptoException(e);
-		}
-		return aesOutLwEnc;
-	}
-
-	public BigInteger generateSecret(PrivateKey privKey, PublicKey pubKey)
-			throws OtrCryptoException {
-		try {
-			KeyAgreement ka = KeyAgreement.getInstance("DH");
-			ka.init(privKey);
-			ka.doPhase(pubKey, true);
-			byte[] sb = ka.generateSecret();
-			BigInteger s = new BigInteger(1, sb);
-			return s;
-
-		} catch (Exception e) {
-			throw new OtrCryptoException(e);
-		}
-	}
-
-	public byte[] sign(byte[] b, PrivateKey privatekey)
-			throws OtrCryptoException {
-
-		if (!(privatekey instanceof DSAPrivateKey))
-			throw new IllegalArgumentException();
-
-		DSAParams dsaParams = ((DSAPrivateKey) privatekey).getParams();
-		DSAParameters bcDSAParameters = new DSAParameters(dsaParams.getP(),
-				dsaParams.getQ(), dsaParams.getG());
-
-		DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) privatekey;
-		DSAPrivateKeyParameters bcDSAPrivateKeyParms = new DSAPrivateKeyParameters(
-				dsaPrivateKey.getX(), bcDSAParameters);
-
-		DSASigner dsaSigner = new DSASigner();
-		dsaSigner.init(true, bcDSAPrivateKeyParms);
-
-		BigInteger q = dsaParams.getQ();
-
-		// Ian: Note that if you can get the standard DSA implementation you're
-		// using to not hash its input, you should be able to pass it ((256-bit
-		// value) mod q), (rather than truncating the 256-bit value) and all
-		// should be well.
-		// ref: Interop problems with libotr - DSA signature
-		BigInteger bmpi = new BigInteger(1, b);
-		BigInteger[] rs = dsaSigner.generateSignature(BigIntegers
-				.asUnsignedByteArray(bmpi.mod(q)));
-
-		int siglen = q.bitLength() / 4;
-		int rslen = siglen / 2;
-		byte[] rb = BigIntegers.asUnsignedByteArray(rs[0]);
-		byte[] sb = BigIntegers.asUnsignedByteArray(rs[1]);
-
-		// Create the final signature array, padded with zeros if necessary.
-		byte[] sig = new byte[siglen];
-		Boolean writeR = false;
-		Boolean writeS = false;
-		for (int i = 0; i < siglen; i++) {
-			if (i < rslen) {
-				if (!writeR)
-					writeR = rb.length >= rslen - i;
-				sig[i] = (writeR) ? rb[i] : (byte) 0x0;
-			} else {
-				int j = i - rslen; // Rebase.
-				if (!writeS)
-					writeS = sb.length >= rslen - j;
-				sig[i] = (writeS) ? sb[j] : (byte) 0x0;
-			}
-		}
-		return sig;
-	}
-
-	public boolean verify(byte[] b, PublicKey pubKey, byte[] rs)
-			throws OtrCryptoException {
-
-		if (!(pubKey instanceof DSAPublicKey))
-			throw new IllegalArgumentException();
-
-		DSAParams dsaParams = ((DSAPublicKey) pubKey).getParams();
-		int qlen = dsaParams.getQ().bitLength() / 8;
-		ByteBuffer buff = ByteBuffer.wrap(rs);
-		byte[] r = new byte[qlen];
-		buff.get(r);
-		byte[] s = new byte[qlen];
-		buff.get(s);
-		return verify(b, pubKey, r, s);
-	}
-
-	private Boolean verify(byte[] b, PublicKey pubKey, byte[] r, byte[] s)
-			throws OtrCryptoException {
-		Boolean result = verify(b, pubKey, new BigInteger(1, r),
-				new BigInteger(1, s));
-		return result;
-	}
-
-	private Boolean verify(byte[] b, PublicKey pubKey, BigInteger r,
-			BigInteger s) throws OtrCryptoException {
-
-		if (!(pubKey instanceof DSAPublicKey))
-			throw new IllegalArgumentException();
-
-		DSAParams dsaParams = ((DSAPublicKey) pubKey).getParams();
-
-		BigInteger q = dsaParams.getQ();
-		DSAParameters bcDSAParams = new DSAParameters(dsaParams.getP(), q,
-				dsaParams.getG());
-
-		DSAPublicKey dsaPrivateKey = (DSAPublicKey) pubKey;
-		DSAPublicKeyParameters dsaPrivParms = new DSAPublicKeyParameters(
-				dsaPrivateKey.getY(), bcDSAParams);
-
-		// Ian: Note that if you can get the standard DSA implementation you're
-		// using to not hash its input, you should be able to pass it ((256-bit
-		// value) mod q), (rather than truncating the 256-bit value) and all
-		// should be well.
-		// ref: Interop problems with libotr - DSA signature
-		DSASigner dsaSigner = new DSASigner();
-		dsaSigner.init(false, dsaPrivParms);
-
-		BigInteger bmpi = new BigInteger(1, b);
-		Boolean result = dsaSigner.verifySignature(BigIntegers
-				.asUnsignedByteArray(bmpi.mod(q)), r, s);
-		return result;
-	}
-
-	public String getFingerprint(PublicKey pubKey) throws OtrCryptoException {
-		byte[] b;
-		try {
-			byte[] bRemotePubKey = SerializationUtils.writePublicKey(pubKey);
-
-			if (pubKey.getAlgorithm().equals("DSA")) {
-				byte[] trimmed = new byte[bRemotePubKey.length - 2];
-				System.arraycopy(bRemotePubKey, 2, trimmed, 0, trimmed.length);
-				b = new OtrCryptoEngineImpl().sha1Hash(trimmed);
-			} else
-				b = new OtrCryptoEngineImpl().sha1Hash(bRemotePubKey);
-		} catch (IOException e) {
-			throw new OtrCryptoException(e);
-		}
-		return this.byteArrayToHexString(b);
-	}
-
-	private String byteArrayToHexString(byte in[]) {
-		byte ch = 0x00;
-		int i = 0;
-		if (in == null || in.length <= 0)
-			return null;
-		String pseudo[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
-				"A", "B", "C", "D", "E", "F" };
-		StringBuffer out = new StringBuffer(in.length * 2);
-		while (i < in.length) {
-			ch = (byte) (in[i] & 0xF0);
-			ch = (byte) (ch >>> 4);
-			ch = (byte) (ch & 0x0F);
-			out.append(pseudo[(int) ch]);
-			ch = (byte) (in[i] & 0x0F);
-			out.append(pseudo[(int) ch]);
-			i++;
-		}
-
-		String rslt = new String(out);
-		return rslt;
-
-	}
-}
--- a/app/src/main/java/net/java/otr4j/crypto/OtrCryptoException.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-package net.java.otr4j.crypto;
-
-import net.java.otr4j.OtrException;
-
-@SuppressWarnings("serial")
-public class OtrCryptoException extends OtrException {
-
-	public OtrCryptoException(Exception e) {
-		super(e);
-	}
-
-}
--- a/app/src/main/java/net/java/otr4j/io/OtrInputStream.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-package net.java.otr4j.io;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPublicKey;
-import java.security.spec.DSAPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
-
-import javax.crypto.interfaces.DHPublicKey;
-
-import net.java.otr4j.crypto.OtrCryptoEngineImpl;
-import net.java.otr4j.io.messages.SignatureX;
-
-public class OtrInputStream extends FilterInputStream implements
-		SerializationConstants {
-
-	public OtrInputStream(InputStream in) {
-		super(in);
-	}
-
-	private int readNumber(int length) throws IOException {
-		byte[] b = new byte[length];
-		read(b);
-
-		int value = 0;
-		for (int i = 0; i < b.length; i++) {
-			int shift = (b.length - 1 - i) * 8;
-			value += (b[i] & 0x000000FF) << shift;
-		}
-
-		return value;
-	}
-
-	public int readByte() throws IOException {
-		return readNumber(TYPE_LEN_BYTE);
-	}
-
-	public int readInt() throws IOException {
-		return readNumber(TYPE_LEN_INT);
-	}
-
-	public int readShort() throws IOException {
-		return readNumber(TYPE_LEN_SHORT);
-	}
-
-	public byte[] readCtr() throws IOException {
-		byte[] b = new byte[TYPE_LEN_CTR];
-		read(b);
-		return b;
-	}
-
-	public byte[] readMac() throws IOException {
-		byte[] b = new byte[TYPE_LEN_MAC];
-		read(b);
-		return b;
-	}
-
-	public BigInteger readBigInt() throws IOException {
-		byte[] b = readData();
-		return new BigInteger(1, b);
-	}
-
-	public byte[] readData() throws IOException {
-		int dataLen = readNumber(DATA_LEN);
-		byte[] b = new byte[dataLen];
-		read(b);
-		return b;
-	}
-
-	public PublicKey readPublicKey() throws IOException {
-		int type = readShort();
-		switch (type) {
-		case 0:
-			BigInteger p = readBigInt();
-			BigInteger q = readBigInt();
-			BigInteger g = readBigInt();
-			BigInteger y = readBigInt();
-			DSAPublicKeySpec keySpec = new DSAPublicKeySpec(y, p, q, g);
-			KeyFactory keyFactory;
-			try {
-				keyFactory = KeyFactory.getInstance("DSA");
-			} catch (NoSuchAlgorithmException e) {
-				throw new IOException();
-			}
-			try {
-				return keyFactory.generatePublic(keySpec);
-			} catch (InvalidKeySpecException e) {
-				throw new IOException();
-			}
-		default:
-			throw new UnsupportedOperationException();
-		}
-	}
-
-	public DHPublicKey readDHPublicKey() throws IOException {
-		BigInteger gyMpi = readBigInt();
-		try {
-			return new OtrCryptoEngineImpl().getDHPublicKey(gyMpi);
-		} catch (Exception ex) {
-			throw new IOException();
-		}
-	}
-
-	public byte[] readTlvData() throws IOException {
-		int len = readNumber(TYPE_LEN_BYTE);
-
-		byte[] b = new byte[len];
-		in.read(b);
-		return b;
-	}
-
-	public byte[] readSignature(PublicKey pubKey) throws IOException {
-		if (!pubKey.getAlgorithm().equals("DSA"))
-			throw new UnsupportedOperationException();
-
-		DSAPublicKey dsaPubKey = (DSAPublicKey) pubKey;
-		DSAParams dsaParams = dsaPubKey.getParams();
-		byte[] sig = new byte[dsaParams.getQ().bitLength() / 4];
-		read(sig);
-		return sig;
-	}
-
-	public SignatureX readMysteriousX() throws IOException {
-		PublicKey pubKey = readPublicKey();
-		int dhKeyID = readInt();
-		byte[] sig = readSignature(pubKey);
-		return new SignatureX(pubKey, dhKeyID, sig);
-	}
-}
--- a/app/src/main/java/net/java/otr4j/io/OtrOutputStream.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-package net.java.otr4j.io;
-
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.math.BigInteger;
-import java.security.PublicKey;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPublicKey;
-
-import javax.crypto.interfaces.DHPublicKey;
-
-import net.java.otr4j.io.messages.SignatureM;
-import net.java.otr4j.io.messages.MysteriousT;
-import net.java.otr4j.io.messages.SignatureX;
-
-import org.bouncycastle2.util.BigIntegers;
-
-public class OtrOutputStream extends FilterOutputStream implements
-		SerializationConstants {
-
-	public OtrOutputStream(OutputStream out) {
-		super(out);
-	}
-
-	private void writeNumber(int value, int length) throws IOException {
-		byte[] b = new byte[length];
-		for (int i = 0; i < length; i++) {
-			int offset = (b.length - 1 - i) * 8;
-			b[i] = (byte) ((value >>> offset) & 0xFF);
-		}
-		write(b);
-	}
-
-	public void writeBigInt(BigInteger bi) throws IOException {
-		byte[] b = BigIntegers.asUnsignedByteArray(bi);
-		writeData(b);
-	}
-
-	public void writeByte(int b) throws IOException {
-		writeNumber(b, TYPE_LEN_BYTE);
-	}
-
-	public void writeData(byte[] b) throws IOException {
-		int len = (b == null || b.length < 0) ? 0 : b.length;
-		writeNumber(len, DATA_LEN);
-		if (len > 0)
-			write(b);
-	}
-
-	public void writeInt(int i) throws IOException {
-		writeNumber(i, TYPE_LEN_INT);
-
-	}
-
-	public void writeShort(int s) throws IOException {
-		writeNumber(s, TYPE_LEN_SHORT);
-
-	}
-
-	public void writeMac(byte[] mac) throws IOException {
-		if (mac == null || mac.length != TYPE_LEN_MAC)
-			throw new IllegalArgumentException();
-
-		write(mac);
-	}
-
-	public void writeCtr(byte[] ctr) throws IOException {
-		if (ctr == null || ctr.length < 1)
-			return;
-
-		int i = 0;
-		while (i < TYPE_LEN_CTR && i < ctr.length) {
-			write(ctr[i]);
-			i++;
-		}
-	}
-
-	public void writeDHPublicKey(DHPublicKey dhPublicKey) throws IOException {
-		byte[] b = BigIntegers.asUnsignedByteArray(dhPublicKey.getY());
-		writeData(b);
-	}
-
-	public void writePublicKey(PublicKey pubKey) throws IOException {
-		if (!(pubKey instanceof DSAPublicKey))
-			throw new UnsupportedOperationException(
-					"Key types other than DSA are not supported at the moment.");
-
-		DSAPublicKey dsaKey = (DSAPublicKey) pubKey;
-
-		writeShort(0);
-
-		DSAParams dsaParams = dsaKey.getParams();
-		writeBigInt(dsaParams.getP());
-		writeBigInt(dsaParams.getQ());
-		writeBigInt(dsaParams.getG());
-		writeBigInt(dsaKey.getY());
-
-	}
-
-	public void writeTlvData(byte[] b) throws IOException {
-		int len = (b == null || b.length < 0) ? 0 : b.length;
-		writeNumber(len, TLV_LEN);
-		if (len > 0)
-			write(b);
-	}
-
-	public void writeSignature(byte[] signature, PublicKey pubKey)
-			throws IOException {
-		if (!pubKey.getAlgorithm().equals("DSA"))
-			throw new UnsupportedOperationException();
-		out.write(signature);
-	}
-
-	public void writeMysteriousX(SignatureX x) throws IOException {
-		writePublicKey(x.longTermPublicKey);
-		writeInt(x.dhKeyID);
-		writeSignature(x.signature, x.longTermPublicKey);
-	}
-
-	public void writeMysteriousX(SignatureM m) throws IOException {
-		writeBigInt(m.localPubKey.getY());
-		writeBigInt(m.remotePubKey.getY());
-		writePublicKey(m.localLongTermPubKey);
-		writeInt(m.keyPairID);
-	}
-
-	public void writeMysteriousT(MysteriousT t) throws IOException {
-		writeShort(t.protocolVersion);
-		writeByte(t.messageType);
-		writeByte(t.flags);
-
-		writeInt(t.senderKeyID);
-		writeInt(t.recipientKeyID);
-		writeDHPublicKey(t.nextDH);
-		writeCtr(t.ctr);
-		writeData(t.encryptedMessage);
-
-	}
-}
--- a/app/src/main/java/net/java/otr4j/io/SerializationConstants.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.io;
-
-/**
- * 
- * @author George Politis
- */
-public interface SerializationConstants {
-
-	public static final String HEAD = "?OTR";
-	public static final char HEAD_ENCODED = ':';
-	public static final char HEAD_ERROR = ' ';
-	public static final char HEAD_QUERY_Q = '?';
-	public static final char HEAD_QUERY_V = 'v';
-
-	public static final int TYPE_LEN_BYTE = 1;
-	public static final int TYPE_LEN_SHORT = 2;
-	public static final int TYPE_LEN_INT = 4;
-	public static final int TYPE_LEN_MAC = 20;
-	public static final int TYPE_LEN_CTR = 8;
-
-	public static final int DATA_LEN = TYPE_LEN_INT;
-	public static final int TLV_LEN = TYPE_LEN_SHORT;
-}
--- a/app/src/main/java/net/java/otr4j/io/SerializationUtils.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,341 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.io;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.math.BigInteger;
-import java.security.PublicKey;
-import java.util.List;
-import java.util.Vector;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.crypto.interfaces.DHPublicKey;
-
-import org.bouncycastle2.util.encoders.Base64;
-
-import net.java.otr4j.io.messages.AbstractEncodedMessage;
-import net.java.otr4j.io.messages.AbstractMessage;
-import net.java.otr4j.io.messages.DHCommitMessage;
-import net.java.otr4j.io.messages.DHKeyMessage;
-import net.java.otr4j.io.messages.DataMessage;
-import net.java.otr4j.io.messages.ErrorMessage;
-import net.java.otr4j.io.messages.MysteriousT;
-import net.java.otr4j.io.messages.PlainTextMessage;
-import net.java.otr4j.io.messages.QueryMessage;
-import net.java.otr4j.io.messages.RevealSignatureMessage;
-import net.java.otr4j.io.messages.SignatureM;
-import net.java.otr4j.io.messages.SignatureMessage;
-import net.java.otr4j.io.messages.SignatureX;
-
-/**
- * 
- * @author George Politis
- */
-public class SerializationUtils {
-	// Mysterious X IO.
-	public static SignatureX toMysteriousX(byte[] b) throws IOException {
-		ByteArrayInputStream in = new ByteArrayInputStream(b);
-		OtrInputStream ois = new OtrInputStream(in);
-		SignatureX x = ois.readMysteriousX();
-		ois.close();
-		return x;
-	}
-
-	public static byte[] toByteArray(SignatureX x) throws IOException {
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		OtrOutputStream oos = new OtrOutputStream(out);
-		oos.writeMysteriousX(x);
-		byte[] b = out.toByteArray();
-		oos.close();
-		return b;
-	}
-
-	// Mysterious M IO.
-	public static byte[] toByteArray(SignatureM m) throws IOException {
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		OtrOutputStream oos = new OtrOutputStream(out);
-		oos.writeMysteriousX(m);
-		byte[] b = out.toByteArray();
-		oos.close();
-		return b;
-	}
-
-	// Mysterious T IO.
-	public static byte[] toByteArray(MysteriousT t) throws IOException {
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		OtrOutputStream oos = new OtrOutputStream(out);
-		oos.writeMysteriousT(t);
-		byte[] b = out.toByteArray();
-		oos.close();
-		return b;
-	}
-
-	// Basic IO.
-	public static byte[] writeData(byte[] b) throws IOException {
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		OtrOutputStream oos = new OtrOutputStream(out);
-		oos.writeData(b);
-		byte[] otrb = out.toByteArray();
-		oos.close();
-		return otrb;
-	}
-
-	// BigInteger IO.
-	public static byte[] writeMpi(BigInteger bigInt) throws IOException {
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		OtrOutputStream oos = new OtrOutputStream(out);
-		oos.writeBigInt(bigInt);
-		byte[] b = out.toByteArray();
-		oos.close();
-		return b;
-	}
-
-	public static BigInteger readMpi(byte[] b) throws IOException {
-		ByteArrayInputStream in = new ByteArrayInputStream(b);
-		OtrInputStream ois = new OtrInputStream(in);
-		BigInteger bigint = ois.readBigInt();
-		ois.close();
-		return bigint;
-	}
-
-	// Public Key IO.
-	public static byte[] writePublicKey(PublicKey pubKey) throws IOException {
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		OtrOutputStream oos = new OtrOutputStream(out);
-		oos.writePublicKey(pubKey);
-		byte[] b = out.toByteArray();
-		oos.close();
-		return b;
-	}
-
-	// Message IO.
-	public static String toString(AbstractMessage m) throws IOException {
-		StringWriter writer = new StringWriter();
-		writer.write(SerializationConstants.HEAD);
-
-		switch (m.messageType) {
-		case AbstractMessage.MESSAGE_ERROR:
-			ErrorMessage error = (ErrorMessage) m;
-			writer.write(SerializationConstants.HEAD_ERROR);
-			writer.write(error.error);
-			break;
-		case AbstractMessage.MESSAGE_PLAINTEXT:
-			PlainTextMessage plaintxt = (PlainTextMessage) m;
-			writer.write(plaintxt.cleanText);
-			if (plaintxt.versions != null && plaintxt.versions.size() > 0) {
-				writer.write(" \\t  \\t\\t\\t\\t \\t \\t \\t  ");
-				for (int version : plaintxt.versions) {
-					if (version == 1)
-						writer.write("  \\t\\t  \\t ");
-
-					if (version == 2)
-						writer.write(" \\t \\t  \\t ");
-				}
-			}
-			break;
-		case AbstractMessage.MESSAGE_QUERY:
-			QueryMessage query = (QueryMessage) m;
-			if (query.versions.size() == 1 && query.versions.get(0) == 1) {
-				writer.write(SerializationConstants.HEAD_QUERY_Q);
-			} else {
-				writer.write(SerializationConstants.HEAD_QUERY_V);
-				for (int version : query.versions)
-					writer.write(String.valueOf(version));
-
-				writer.write(SerializationConstants.HEAD_QUERY_Q);
-			}
-			break;
-		case AbstractEncodedMessage.MESSAGE_DHKEY:
-		case AbstractEncodedMessage.MESSAGE_REVEALSIG:
-		case AbstractEncodedMessage.MESSAGE_SIGNATURE:
-		case AbstractEncodedMessage.MESSAGE_DH_COMMIT:
-		case AbstractEncodedMessage.MESSAGE_DATA:
-			ByteArrayOutputStream o = new ByteArrayOutputStream();
-			OtrOutputStream s = new OtrOutputStream(o);
-
-			switch (m.messageType) {
-			case AbstractEncodedMessage.MESSAGE_DHKEY:
-				DHKeyMessage dhkey = (DHKeyMessage) m;
-				s.writeShort(dhkey.protocolVersion);
-				s.writeByte(dhkey.messageType);
-				s.writeDHPublicKey(dhkey.dhPublicKey);
-				break;
-			case AbstractEncodedMessage.MESSAGE_REVEALSIG:
-				RevealSignatureMessage revealsig = (RevealSignatureMessage) m;
-				s.writeShort(revealsig.protocolVersion);
-				s.writeByte(revealsig.messageType);
-				s.writeData(revealsig.revealedKey);
-				s.writeData(revealsig.xEncrypted);
-				s.writeMac(revealsig.xEncryptedMAC);
-				break;
-			case AbstractEncodedMessage.MESSAGE_SIGNATURE:
-				SignatureMessage sig = (SignatureMessage) m;
-				s.writeShort(sig.protocolVersion);
-				s.writeByte(sig.messageType);
-				s.writeData(sig.xEncrypted);
-				s.writeMac(sig.xEncryptedMAC);
-				break;
-			case AbstractEncodedMessage.MESSAGE_DH_COMMIT:
-				DHCommitMessage dhcommit = (DHCommitMessage) m;
-				s.writeShort(dhcommit.protocolVersion);
-				s.writeByte(dhcommit.messageType);
-				s.writeData(dhcommit.dhPublicKeyEncrypted);
-				s.writeData(dhcommit.dhPublicKeyHash);
-				break;
-			case AbstractEncodedMessage.MESSAGE_DATA:
-				DataMessage data = (DataMessage) m;
-				s.writeShort(data.protocolVersion);
-				s.writeByte(data.messageType);
-				s.writeByte(data.flags);
-				s.writeInt(data.senderKeyID);
-				s.writeInt(data.recipientKeyID);
-				s.writeDHPublicKey(data.nextDH);
-				s.writeCtr(data.ctr);
-				s.writeData(data.encryptedMessage);
-				s.writeMac(data.mac);
-				s.writeData(data.oldMACKeys);
-				break;
-			}
-
-			writer.write(SerializationConstants.HEAD_ENCODED);
-			writer.write(new String(Base64.encode(o.toByteArray())));
-			writer.write(".");
-			break;
-		default:
-			throw new IOException("Illegal message type.");
-		}
-
-		return writer.toString();
-	}
-
-	static final Pattern patternWhitespace = Pattern
-			.compile("( \\t  \\t\\t\\t\\t \\t \\t \\t  )(  \\t\\t  \\t )?( \\t \\t  \\t )?");
-
-	public static AbstractMessage toMessage(String s) throws IOException {
-		if (s == null || s.length() <= 1)
-			return null;
-
-		if (s.indexOf(SerializationConstants.HEAD) != 0
-				|| s.length() <= SerializationConstants.HEAD.length()) {
-			// Try to detect whitespace tag.
-			final Matcher matcher = patternWhitespace.matcher(s);
-
-			boolean v1 = false;
-			boolean v2 = false;
-			while (matcher.find()) {
-				if (!v1 && matcher.start(2) > -1)
-					v1 = true;
-
-				if (!v2 && matcher.start(3) > -1)
-					v2 = true;
-
-				if (v1 && v2)
-					break;
-			}
-
-			String cleanText = matcher.replaceAll("");
-			List<Integer> versions;
-			if (v1 && v2) {
-				versions = new Vector<Integer>(2);
-				versions.add(0, 1);
-				versions.add(0, 2);
-			} else if (v1) {
-				versions = new Vector<Integer>(1);
-				versions.add(0, 1);
-			} else if (v2) {
-				versions = new Vector<Integer>(1);
-				versions.add(2);
-			} else
-				versions = null;
-
-			return new PlainTextMessage(versions, cleanText);
-		} else {
-			char contentType = s.charAt(SerializationConstants.HEAD.length());
-			String content = s
-					.substring(SerializationConstants.HEAD.length() + 1);
-			switch (contentType) {
-			case SerializationConstants.HEAD_ENCODED:
-				ByteArrayInputStream bin = new ByteArrayInputStream(Base64
-						.decode(content.getBytes()));
-				OtrInputStream otr = new OtrInputStream(bin);
-				// We have an encoded message.
-				int protocolVersion = otr.readShort();
-				int messageType = otr.readByte();
-				switch (messageType) {
-				case AbstractEncodedMessage.MESSAGE_DATA:
-					int flags = otr.readByte();
-					int senderKeyID = otr.readInt();
-					int recipientKeyID = otr.readInt();
-					DHPublicKey nextDH = otr.readDHPublicKey();
-					byte[] ctr = otr.readCtr();
-					byte[] encryptedMessage = otr.readData();
-					byte[] mac = otr.readMac();
-					byte[] oldMacKeys = otr.readMac();
-					return new DataMessage(protocolVersion, flags, senderKeyID,
-							recipientKeyID, nextDH, ctr, encryptedMessage, mac,
-							oldMacKeys);
-				case AbstractEncodedMessage.MESSAGE_DH_COMMIT:
-					byte[] dhPublicKeyEncrypted = otr.readData();
-					byte[] dhPublicKeyHash = otr.readData();
-					return new DHCommitMessage(protocolVersion,
-							dhPublicKeyHash, dhPublicKeyEncrypted);
-				case AbstractEncodedMessage.MESSAGE_DHKEY:
-					DHPublicKey dhPublicKey = otr.readDHPublicKey();
-					return new DHKeyMessage(protocolVersion, dhPublicKey);
-				case AbstractEncodedMessage.MESSAGE_REVEALSIG: {
-					byte[] revealedKey = otr.readData();
-					byte[] xEncrypted = otr.readData();
-					byte[] xEncryptedMac = otr.readMac();
-					return new RevealSignatureMessage(protocolVersion,
-							xEncrypted, xEncryptedMac, revealedKey);
-				}
-				case AbstractEncodedMessage.MESSAGE_SIGNATURE: {
-					byte[] xEncryted = otr.readData();
-					byte[] xEncryptedMac = otr.readMac();
-					return new SignatureMessage(protocolVersion, xEncryted,
-							xEncryptedMac);
-				}
-				default:
-					throw new IOException("Illegal message type.");
-				}
-			case SerializationConstants.HEAD_ERROR:
-				return new ErrorMessage(AbstractMessage.MESSAGE_ERROR, content);
-			case SerializationConstants.HEAD_QUERY_V:
-			case SerializationConstants.HEAD_QUERY_Q:
-				List<Integer> versions = new Vector<Integer>();
-				String versionString = null;
-				if (SerializationConstants.HEAD_QUERY_Q == contentType) {
-					versions.add(1);
-					if (content.charAt(0) == 'v') {
-						versionString = content.substring(1, content
-								.indexOf('?'));
-					}
-				} else if (SerializationConstants.HEAD_QUERY_V == contentType) {
-					versionString = content.substring(0, content.indexOf('?'));
-				}
-
-				if (versionString != null) {
-					StringReader sr = new StringReader(versionString);
-					int c;
-					while ((c = sr.read()) != -1)
-						if (!versions.contains(c))
-							versions.add(Integer.parseInt(String
-									.valueOf((char) c)));
-				}
-				QueryMessage query = new QueryMessage(versions);
-				return query;
-			default:
-				throw new IOException("Uknown message type.");
-			}
-		}
-	}
-}
--- a/app/src/main/java/net/java/otr4j/io/messages/AbstractEncodedMessage.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.io.messages;
-
-/**
- * 
- * @author George Politis
- */
-public abstract class AbstractEncodedMessage extends AbstractMessage {
-	// Fields.
-	public int protocolVersion;
-
-	// Ctor.
-	public AbstractEncodedMessage(int messageType, int protocolVersion) {
-		super(messageType);
-		this.protocolVersion = protocolVersion;
-	}
-
-	// Methods.
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		result = prime * result + protocolVersion;
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		AbstractEncodedMessage other = (AbstractEncodedMessage) obj;
-		if (protocolVersion != other.protocolVersion)
-			return false;
-		return true;
-	}
-
-	// Encoded Message Types
-	public static final int MESSAGE_DH_COMMIT = 0x02;
-	public static final int MESSAGE_DATA = 0x03;
-	public static final int MESSAGE_DHKEY = 0x0a;
-	public static final int MESSAGE_REVEALSIG = 0x11;
-	public static final int MESSAGE_SIGNATURE = 0x12;
-}
--- a/app/src/main/java/net/java/otr4j/io/messages/AbstractMessage.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.io.messages;
-
-/**
- * 
- * @author George Politis
- */
-public abstract class AbstractMessage {
-	// Fields.
-	public int messageType;
-
-	// Ctor.
-	public AbstractMessage(int messageType) {
-		this.messageType = messageType;
-	}
-
-	// Methods.
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + messageType;
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		AbstractMessage other = (AbstractMessage) obj;
-		if (messageType != other.messageType)
-			return false;
-		return true;
-	}
-
-	// Unencoded
-	public static final int MESSAGE_ERROR = 0xff;
-	public static final int MESSAGE_QUERY = 0x100;
-	public static final int MESSAGE_PLAINTEXT = 0x102;
-}
--- a/app/src/main/java/net/java/otr4j/io/messages/DHCommitMessage.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.io.messages;
-
-import java.util.Arrays;
-
-/**
- * 
- * @author George Politis
- */
-public class DHCommitMessage extends AbstractEncodedMessage {
-
-	// Fields.
-	public byte[] dhPublicKeyEncrypted;
-	public byte[] dhPublicKeyHash;
-
-	// Ctor.
-	public DHCommitMessage(int protocolVersion, byte[] dhPublicKeyHash,
-			byte[] dhPublicKeyEncrypted) {
-		super(MESSAGE_DH_COMMIT, protocolVersion);
-		this.dhPublicKeyEncrypted = dhPublicKeyEncrypted;
-		this.dhPublicKeyHash = dhPublicKeyHash;
-	}
-
-	// Methods.
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		result = prime * result + Arrays.hashCode(dhPublicKeyEncrypted);
-		result = prime * result + Arrays.hashCode(dhPublicKeyHash);
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		DHCommitMessage other = (DHCommitMessage) obj;
-		if (!Arrays.equals(dhPublicKeyEncrypted, other.dhPublicKeyEncrypted))
-			return false;
-		if (!Arrays.equals(dhPublicKeyHash, other.dhPublicKeyHash))
-			return false;
-		return true;
-	}
-
-}
--- a/app/src/main/java/net/java/otr4j/io/messages/DHKeyMessage.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.io.messages;
-
-import javax.crypto.interfaces.DHPublicKey;
-
-/**
- * 
- * @author George Politis
- */
-public class DHKeyMessage extends AbstractEncodedMessage {
-
-	// Fields.
-	public DHPublicKey dhPublicKey;
-
-	// Ctor.
-	public DHKeyMessage(int protocolVersion, DHPublicKey dhPublicKey) {
-		super(MESSAGE_DHKEY, protocolVersion);
-		this.dhPublicKey = dhPublicKey;
-	}
-
-	// Methods.
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		// TODO: Needs work.
-		result = prime * result
-				+ ((dhPublicKey == null) ? 0 : dhPublicKey.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		DHKeyMessage other = (DHKeyMessage) obj;
-		if (dhPublicKey == null) {
-			if (other.dhPublicKey != null)
-				return false;
-		} else if (dhPublicKey.getY().compareTo(other.dhPublicKey.getY()) != 0)
-			return false;
-		return true;
-	}
-}
--- a/app/src/main/java/net/java/otr4j/io/messages/DataMessage.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.io.messages;
-
-import java.util.Arrays;
-
-import javax.crypto.interfaces.DHPublicKey;
-
-/**
- * 
- * @author George Politis
- */
-public class DataMessage extends AbstractEncodedMessage {
-
-	// Fields.
-	public byte[] mac;
-	public byte[] oldMACKeys;
-
-	public int flags;
-	public int senderKeyID;
-	public int recipientKeyID;
-	public DHPublicKey nextDH;
-	public byte[] ctr;
-	public byte[] encryptedMessage;
-
-	// Ctor.
-	public DataMessage(int protocolVersion, int flags, int senderKeyID,
-			int recipientKeyID, DHPublicKey nextDH, byte[] ctr,
-			byte[] encryptedMessage, byte[] mac, byte[] oldMacKeys) {
-		super(MESSAGE_DATA, protocolVersion);
-
-		this.flags = flags;
-		this.senderKeyID = senderKeyID;
-		this.recipientKeyID = recipientKeyID;
-		this.nextDH = nextDH;
-		this.ctr = ctr;
-		this.encryptedMessage = encryptedMessage;
-		this.mac = mac;
-		this.oldMACKeys = oldMacKeys;
-	}
-
-	public DataMessage(MysteriousT t, byte[] mac, byte[] oldMacKeys) {
-		this(t.protocolVersion, t.flags, t.senderKeyID, t.recipientKeyID,
-				t.nextDH, t.ctr, t.encryptedMessage, mac, oldMacKeys);
-	}
-
-	// Methods.
-	public MysteriousT getT() {
-		return new MysteriousT(protocolVersion, flags, senderKeyID,
-				recipientKeyID, nextDH, ctr, encryptedMessage);
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		result = prime * result + Arrays.hashCode(ctr);
-		result = prime * result + Arrays.hashCode(encryptedMessage);
-		result = prime * result + flags;
-		result = prime * result + Arrays.hashCode(mac);
-		// TODO: Needs work.
-		result = prime * result + ((nextDH == null) ? 0 : nextDH.hashCode());
-		result = prime * result + Arrays.hashCode(oldMACKeys);
-		result = prime * result + recipientKeyID;
-		result = prime * result + senderKeyID;
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		DataMessage other = (DataMessage) obj;
-		if (!Arrays.equals(ctr, other.ctr))
-			return false;
-		if (!Arrays.equals(encryptedMessage, other.encryptedMessage))
-			return false;
-		if (flags != other.flags)
-			return false;
-		if (!Arrays.equals(mac, other.mac))
-			return false;
-		if (nextDH == null) {
-			if (other.nextDH != null)
-				return false;
-		} else if (!nextDH.equals(other.nextDH))
-			return false;
-		if (!Arrays.equals(oldMACKeys, other.oldMACKeys))
-			return false;
-		if (recipientKeyID != other.recipientKeyID)
-			return false;
-		if (senderKeyID != other.senderKeyID)
-			return false;
-		return true;
-	}
-}
--- a/app/src/main/java/net/java/otr4j/io/messages/ErrorMessage.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.io.messages;
-
-/**
- * 
- * @author George Politis
- */
-public class ErrorMessage extends AbstractMessage {
-	// Fields.
-	public String error;
-	
-	// Ctor.
-	public ErrorMessage(int messageType, String error) {
-		super(messageType);
-		this.error = error;
-	}
-
-	// Methods.
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		result = prime * result + ((error == null) ? 0 : error.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		ErrorMessage other = (ErrorMessage) obj;
-		if (error == null) {
-			if (other.error != null)
-				return false;
-		} else if (!error.equals(other.error))
-			return false;
-		return true;
-	}
-}
--- a/app/src/main/java/net/java/otr4j/io/messages/MysteriousT.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-package net.java.otr4j.io.messages;
-
-import java.util.Arrays;
-
-import javax.crypto.interfaces.DHPublicKey;
-
-public class MysteriousT {
-	// Fields.
-	public int protocolVersion;
-	public int messageType;
-	public int flags;
-	public int senderKeyID;
-	public int recipientKeyID;
-	public DHPublicKey nextDH;
-	public byte[] ctr;
-	public byte[] encryptedMessage;
-
-	// Ctor.
-	public MysteriousT(int protocolVersion, int flags, int senderKeyID,
-			int recipientKeyID, DHPublicKey nextDH, byte[] ctr,
-			byte[] encryptedMessage) {
-
-		this.protocolVersion = protocolVersion;
-		this.messageType = AbstractEncodedMessage.MESSAGE_DATA;
-		this.flags = flags;
-		this.senderKeyID = senderKeyID;
-		this.recipientKeyID = recipientKeyID;
-		this.nextDH = nextDH;
-		this.ctr = ctr;
-		this.encryptedMessage = encryptedMessage;
-	}
-
-	// Methods.
-	@Override
-	public int hashCode() {
-		// TODO: Needs work.
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + Arrays.hashCode(ctr);
-		result = prime * result + Arrays.hashCode(encryptedMessage);
-		result = prime * result + flags;
-		result = prime * result + messageType;
-		result = prime * result + ((nextDH == null) ? 0 : nextDH.hashCode());
-		result = prime * result + protocolVersion;
-		result = prime * result + recipientKeyID;
-		result = prime * result + senderKeyID;
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		// TODO: Needs work.
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		MysteriousT other = (MysteriousT) obj;
-		if (!Arrays.equals(ctr, other.ctr))
-			return false;
-		if (!Arrays.equals(encryptedMessage, other.encryptedMessage))
-			return false;
-		if (flags != other.flags)
-			return false;
-		if (messageType != other.messageType)
-			return false;
-		if (nextDH == null) {
-			if (other.nextDH != null)
-				return false;
-		} else if (!nextDH.equals(other.nextDH))
-			return false;
-		if (protocolVersion != other.protocolVersion)
-			return false;
-		if (recipientKeyID != other.recipientKeyID)
-			return false;
-		if (senderKeyID != other.senderKeyID)
-			return false;
-		return true;
-	}
-
-}
--- a/app/src/main/java/net/java/otr4j/io/messages/PlainTextMessage.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.io.messages;
-
-import java.util.List;
-
-/**
- * 
- * @author George Politis
- */
-public class PlainTextMessage extends QueryMessage {
-	// Fields.
-	public String cleanText;
-
-	// Ctor.
-	public PlainTextMessage(List<Integer> versions, String cleanText) {
-		super(MESSAGE_PLAINTEXT, versions);
-		this.cleanText = cleanText;
-	}
-
-	// Methods.
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		result = prime * result
-				+ ((cleanText == null) ? 0 : cleanText.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		PlainTextMessage other = (PlainTextMessage) obj;
-		if (cleanText == null) {
-			if (other.cleanText != null)
-				return false;
-		} else if (!cleanText.equals(other.cleanText))
-			return false;
-		return true;
-	}
-
-}
--- a/app/src/main/java/net/java/otr4j/io/messages/QueryMessage.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.io.messages;
-
-import java.util.List;
-
-/**
- * 
- * @author George Politis
- */
-public class QueryMessage extends AbstractMessage {
-	// Fields.
-	public List<Integer> versions;
-
-	// Ctor.
-	protected QueryMessage(int messageType, List<Integer> versions) {
-		super(messageType);
-		this.versions = versions;
-	}
-
-	public QueryMessage(List<Integer> versions) {
-		this(MESSAGE_QUERY, versions);
-	}
-
-	// Methods.
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		result = prime * result
-				+ ((versions == null) ? 0 : versions.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		QueryMessage other = (QueryMessage) obj;
-		if (versions == null) {
-			if (other.versions != null)
-				return false;
-		} else if (!versions.equals(other.versions))
-			return false;
-		return true;
-	}
-
-}
--- a/app/src/main/java/net/java/otr4j/io/messages/RevealSignatureMessage.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.io.messages;
-
-import java.util.Arrays;
-
-/**
- * 
- * @author George Politis
- */
-public class RevealSignatureMessage extends SignatureMessage {
-	// Fields.
-	public byte[] revealedKey;
-
-	// Ctor.
-	public RevealSignatureMessage(int protocolVersion, byte[] xEncrypted,
-			byte[] xEncryptedMAC, byte[] revealedKey) {
-		super(MESSAGE_REVEALSIG, protocolVersion, xEncrypted, xEncryptedMAC);
-
-		this.revealedKey = revealedKey;
-	}
-
-	// Methods.
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		result = prime * result + Arrays.hashCode(revealedKey);
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		RevealSignatureMessage other = (RevealSignatureMessage) obj;
-		if (!Arrays.equals(revealedKey, other.revealedKey))
-			return false;
-		return true;
-	}
-}
--- a/app/src/main/java/net/java/otr4j/io/messages/SignatureM.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.io.messages;
-
-import java.security.PublicKey;
-
-import javax.crypto.interfaces.DHPublicKey;
-
-/**
- * 
- * @author George Politis
- */
-public class SignatureM {
-	// Fields.
-	public DHPublicKey localPubKey;
-	public DHPublicKey remotePubKey;
-	public PublicKey localLongTermPubKey;
-	public int keyPairID;
-	
-	// Ctor.
-	public SignatureM(DHPublicKey localPubKey, DHPublicKey remotePublicKey,
-			PublicKey localLongTermPublicKey, int keyPairID) {
-
-		this.localPubKey = localPubKey;
-		this.remotePubKey = remotePublicKey;
-		this.localLongTermPubKey = localLongTermPublicKey;
-		this.keyPairID = keyPairID;
-	}
-
-	// Methods.
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + keyPairID;
-		// TODO: Needs work.
-		result = prime
-				* result
-				+ ((localLongTermPubKey == null) ? 0 : localLongTermPubKey
-						.hashCode());
-		result = prime * result
-				+ ((localPubKey == null) ? 0 : localPubKey.hashCode());
-		result = prime * result
-				+ ((remotePubKey == null) ? 0 : remotePubKey.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		// TODO: Needs work.
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		SignatureM other = (SignatureM) obj;
-		if (keyPairID != other.keyPairID)
-			return false;
-		if (localLongTermPubKey == null) {
-			if (other.localLongTermPubKey != null)
-				return false;
-		} else if (!localLongTermPubKey.equals(other.localLongTermPubKey))
-			return false;
-		if (localPubKey == null) {
-			if (other.localPubKey != null)
-				return false;
-		} else if (!localPubKey.equals(other.localPubKey))
-			return false;
-		if (remotePubKey == null) {
-			if (other.remotePubKey != null)
-				return false;
-		} else if (!remotePubKey.equals(other.remotePubKey))
-			return false;
-		return true;
-	}
-
-}
--- a/app/src/main/java/net/java/otr4j/io/messages/SignatureMessage.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.io.messages;
-