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;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-import net.java.otr4j.OtrException;
-import net.java.otr4j.crypto.OtrCryptoEngineImpl;
-import net.java.otr4j.io.SerializationUtils;
-
-/**
- * 
- * @author George Politis
- */
-public class SignatureMessage extends AbstractEncodedMessage {
-	// Fields.
-	public byte[] xEncrypted;
-	public byte[] xEncryptedMAC;
-
-	// Ctor.
-	protected SignatureMessage(int messageType, int protocolVersion,
-			byte[] xEncrypted, byte[] xEncryptedMAC) {
-		super(messageType, protocolVersion);
-		this.xEncrypted = xEncrypted;
-		this.xEncryptedMAC = xEncryptedMAC;
-	}
-
-	public SignatureMessage(int protocolVersion, byte[] xEncrypted,
-			byte[] xEncryptedMAC) {
-		this(MESSAGE_SIGNATURE, protocolVersion, xEncrypted, xEncryptedMAC);
-	}
-
-	// Memthods.
-	public byte[] decrypt(byte[] key) throws OtrException {
-		return new OtrCryptoEngineImpl().aesDecrypt(key, null, xEncrypted);
-	}
-
-	public boolean verify(byte[] key) throws OtrException {
-		// Hash the key.
-		byte[] xbEncrypted;
-		try {
-			xbEncrypted = SerializationUtils.writeData(xEncrypted);
-		} catch (IOException e) {
-			throw new OtrException(e);
-		}
-
-		byte[] xEncryptedMAC = new OtrCryptoEngineImpl().sha256Hmac160(
-				xbEncrypted, key);
-		// Verify signature.
-		return Arrays.equals(xEncryptedMAC, xEncryptedMAC);
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		result = prime * result + Arrays.hashCode(xEncrypted);
-		result = prime * result + Arrays.hashCode(xEncryptedMAC);
-		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;
-		SignatureMessage other = (SignatureMessage) obj;
-		if (!Arrays.equals(xEncrypted, other.xEncrypted))
-			return false;
-		if (!Arrays.equals(xEncryptedMAC, other.xEncryptedMAC))
-			return false;
-		return true;
-	}
-}
--- a/app/src/main/java/net/java/otr4j/io/messages/SignatureX.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +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 java.util.Arrays;
-
-/**
- * 
- * @author George Politis
- */
-public class SignatureX {
-	// Fields.
-	public PublicKey longTermPublicKey;
-	public int dhKeyID;
-	public byte[] signature;
-
-	// Ctor.
-	public SignatureX(PublicKey ourLongTermPublicKey, int ourKeyID,
-			byte[] signature) {
-		this.longTermPublicKey = ourLongTermPublicKey;
-		this.dhKeyID = ourKeyID;
-		this.signature = signature;
-	}
-
-	// Methods.
-	@Override
-	public int hashCode() {
-		// TODO: Needs work.
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + dhKeyID;
-		result = prime
-				* result
-				+ ((longTermPublicKey == null) ? 0 : longTermPublicKey
-						.hashCode());
-		result = prime * result + Arrays.hashCode(signature);
-		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;
-		SignatureX other = (SignatureX) obj;
-		if (dhKeyID != other.dhKeyID)
-			return false;
-		if (longTermPublicKey == null) {
-			if (other.longTermPublicKey != null)
-				return false;
-		} else if (!longTermPublicKey.equals(other.longTermPublicKey))
-			return false;
-		if (!Arrays.equals(signature, other.signature))
-			return false;
-		return true;
-	}
-
-}
--- a/app/src/main/java/net/java/otr4j/session/AuthContext.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.session;
-
-import java.math.BigInteger;
-import java.security.KeyPair;
-import java.security.PublicKey;
-
-import javax.crypto.interfaces.DHPublicKey;
-
-import net.java.otr4j.OtrException;
-import net.java.otr4j.io.messages.AbstractMessage;
-
-/**
- * 
- * @author George Politis
- */
-interface AuthContext {
-
-	public static final int NONE = 0;
-	public static final int AWAITING_DHKEY = 1;
-	public static final int AWAITING_REVEALSIG = 2;
-	public static final int AWAITING_SIG = 3;
-	public static final int V1_SETUP = 4;
-	public static final byte C_START = (byte) 0x01;
-	public static final byte M1_START = (byte) 0x02;
-	public static final byte M2_START = (byte) 0x03;
-	public static final byte M1p_START = (byte) 0x04;
-	public static final byte M2p_START = (byte) 0x05;
-
-	public abstract void reset();
-
-	public abstract boolean getIsSecure();
-
-	public abstract DHPublicKey getRemoteDHPublicKey();
-
-	public abstract KeyPair getLocalDHKeyPair() throws OtrException;
-
-	public abstract BigInteger getS() throws OtrException;
-
-	public abstract void handleReceivingMessage(AbstractMessage m)
-			throws OtrException;
-
-	public abstract void startV2Auth() throws OtrException;
-
-	public abstract void respondV2Auth() throws OtrException;
-
-	public abstract PublicKey getRemoteLongTermPublicKey();
-
-	public abstract KeyPair getLocalLongTermKeyPair();
-}
\ No newline at end of file
--- a/app/src/main/java/net/java/otr4j/session/AuthContextImpl.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,766 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.session;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.security.KeyPair;
-import java.security.PublicKey;
-import java.util.Arrays;
-import java.util.Random;
-import java.util.Vector;
-import java.util.logging.Logger;
-
-import javax.crypto.interfaces.DHPublicKey;
-
-import net.java.otr4j.OtrException;
-import net.java.otr4j.crypto.OtrCryptoEngine;
-import net.java.otr4j.crypto.OtrCryptoEngineImpl;
-import net.java.otr4j.io.SerializationUtils;
-import net.java.otr4j.io.messages.DHCommitMessage;
-import net.java.otr4j.io.messages.DHKeyMessage;
-import net.java.otr4j.io.messages.AbstractEncodedMessage;
-import net.java.otr4j.io.messages.AbstractMessage;
-import net.java.otr4j.io.messages.SignatureM;
-import net.java.otr4j.io.messages.SignatureX;
-import net.java.otr4j.io.messages.QueryMessage;
-import net.java.otr4j.io.messages.RevealSignatureMessage;
-import net.java.otr4j.io.messages.SignatureMessage;
-
-/**
- * 
- * @author George Politis
- */
-class AuthContextImpl implements AuthContext {
-
-	public AuthContextImpl(Session session) {
-		this.setSession(session);
-		this.reset();
-	}
-
-	private Session session;
-
-	private int authenticationState;
-	private byte[] r;
-
-	private DHPublicKey remoteDHPublicKey;
-	private byte[] remoteDHPublicKeyEncrypted;
-	private byte[] remoteDHPublicKeyHash;
-
-	private KeyPair localDHKeyPair;
-	private int localDHPrivateKeyID;
-	private byte[] localDHPublicKeyBytes;
-	private byte[] localDHPublicKeyHash;
-	private byte[] localDHPublicKeyEncrypted;
-
-	private BigInteger s;
-	private byte[] c;
-	private byte[] m1;
-	private byte[] m2;
-	private byte[] cp;
-	private byte[] m1p;
-	private byte[] m2p;
-
-	private KeyPair localLongTermKeyPair;
-	private Boolean isSecure = false;
-	private int protocolVersion;
-
-	private int getProtocolVersion() {
-		return this.protocolVersion;
-	}
-
-	private void setProtocolVersion(int protoVersion) {
-		this.protocolVersion = protoVersion;
-	}
-
-	private static Logger logger = Logger.getLogger(AuthContextImpl.class
-			.getName());
-
-	class MessageFactory {
-
-		private QueryMessage getQueryMessage() {
-			Vector<Integer> versions = new Vector<Integer>();
-			versions.add(2);
-			return new QueryMessage(versions);
-		}
-
-		private DHCommitMessage getDHCommitMessage() throws OtrException {
-			return new DHCommitMessage(getProtocolVersion(),
-					getLocalDHPublicKeyHash(), getLocalDHPublicKeyEncrypted());
-		}
-
-		private DHKeyMessage getDHKeyMessage() throws OtrException {
-			return new DHKeyMessage(getProtocolVersion(),
-					(DHPublicKey) getLocalDHKeyPair().getPublic());
-		}
-
-		private RevealSignatureMessage getRevealSignatureMessage()
-				throws OtrException {
-			try {
-				SignatureM m = new SignatureM((DHPublicKey) getLocalDHKeyPair()
-						.getPublic(), getRemoteDHPublicKey(),
-						getLocalLongTermKeyPair().getPublic(),
-						getLocalDHKeyPairID());
-
-				OtrCryptoEngine otrCryptoEngine = new OtrCryptoEngineImpl();
-				byte[] mhash = otrCryptoEngine.sha256Hmac(SerializationUtils
-						.toByteArray(m), getM1());
-				byte[] signature = otrCryptoEngine.sign(mhash,
-						getLocalLongTermKeyPair().getPrivate());
-
-				SignatureX mysteriousX = new SignatureX(
-						getLocalLongTermKeyPair().getPublic(),
-						getLocalDHKeyPairID(), signature);
-				byte[] xEncrypted = otrCryptoEngine.aesEncrypt(getC(), null,
-						SerializationUtils.toByteArray(mysteriousX));
-
-				byte[] tmp = SerializationUtils.writeData(xEncrypted);
-
-				byte[] xEncryptedHash = otrCryptoEngine.sha256Hmac160(tmp,
-						getM2());
-				return new RevealSignatureMessage(getProtocolVersion(),
-						xEncrypted, xEncryptedHash, getR());
-			} catch (IOException e) {
-				throw new OtrException(e);
-			}
-		}
-
-		private SignatureMessage getSignatureMessage() throws OtrException {
-			SignatureM m = new SignatureM((DHPublicKey) getLocalDHKeyPair()
-					.getPublic(), getRemoteDHPublicKey(),
-					getLocalLongTermKeyPair().getPublic(),
-					getLocalDHKeyPairID());
-
-			OtrCryptoEngine otrCryptoEngine = new OtrCryptoEngineImpl();
-			byte[] mhash;
-			try {
-				mhash = otrCryptoEngine.sha256Hmac(SerializationUtils
-						.toByteArray(m), getM1p());
-			} catch (IOException e) {
-				throw new OtrException(e);
-			}
-
-			byte[] signature = otrCryptoEngine.sign(mhash,
-					getLocalLongTermKeyPair().getPrivate());
-
-			SignatureX mysteriousX = new SignatureX(getLocalLongTermKeyPair()
-					.getPublic(), getLocalDHKeyPairID(), signature);
-
-			byte[] xEncrypted;
-			try {
-				xEncrypted = otrCryptoEngine.aesEncrypt(getCp(), null,
-						SerializationUtils.toByteArray(mysteriousX));
-				byte[] tmp = SerializationUtils.writeData(xEncrypted);
-				byte[] xEncryptedHash = otrCryptoEngine.sha256Hmac160(tmp,
-						getM2p());
-				return new SignatureMessage(getProtocolVersion(), xEncrypted,
-						xEncryptedHash);
-			} catch (IOException e) {
-				throw new OtrException(e);
-			}
-		}
-	}
-
-	private MessageFactory messageFactory = new MessageFactory();
-
-	public void reset() {
-		logger.finest("Resetting authentication state.");
-		authenticationState = AuthContext.NONE;
-		r = null;
-
-		remoteDHPublicKey = null;
-		remoteDHPublicKeyEncrypted = null;
-		remoteDHPublicKeyHash = null;
-
-		localDHKeyPair = null;
-		localDHPrivateKeyID = 1;
-		localDHPublicKeyBytes = null;
-		localDHPublicKeyHash = null;
-		localDHPublicKeyEncrypted = null;
-
-		s = null;
-		c = m1 = m2 = cp = m1p = m2p = null;
-
-		localLongTermKeyPair = null;
-		protocolVersion = 0;
-		setIsSecure(false);
-	}
-
-	private void setIsSecure(Boolean isSecure) {
-		this.isSecure = isSecure;
-	}
-
-	public boolean getIsSecure() {
-		return isSecure;
-	}
-
-	private void setAuthenticationState(int authenticationState) {
-		this.authenticationState = authenticationState;
-	}
-
-	private int getAuthenticationState() {
-		return authenticationState;
-	}
-
-	private byte[] getR() {
-		if (r == null) {
-			logger.finest("Picking random key r.");
-			r = new byte[OtrCryptoEngine.AES_KEY_BYTE_LENGTH];
-			new Random().nextBytes(r);
-		}
-		return r;
-	}
-
-	private void setRemoteDHPublicKey(DHPublicKey dhPublicKey) {
-		// Verifies that Alice's gy is a legal value (2 <= gy <= modulus-2)
-		if (dhPublicKey.getY().compareTo(OtrCryptoEngine.MODULUS_MINUS_TWO) > 0) {
-			throw new IllegalArgumentException(
-					"Illegal D-H Public Key value, Ignoring message.");
-		} else if (dhPublicKey.getY().compareTo(OtrCryptoEngine.BIGINTEGER_TWO) < 0) {
-			throw new IllegalArgumentException(
-					"Illegal D-H Public Key value, Ignoring message.");
-		}
-		logger.finest("Received D-H Public Key is a legal value.");
-
-		this.remoteDHPublicKey = dhPublicKey;
-	}
-
-	public DHPublicKey getRemoteDHPublicKey() {
-		return remoteDHPublicKey;
-	}
-
-	private void setRemoteDHPublicKeyEncrypted(byte[] remoteDHPublicKeyEncrypted) {
-		logger.finest("Storing encrypted remote public key.");
-		this.remoteDHPublicKeyEncrypted = remoteDHPublicKeyEncrypted;
-	}
-
-	private byte[] getRemoteDHPublicKeyEncrypted() {
-		return remoteDHPublicKeyEncrypted;
-	}
-
-	private void setRemoteDHPublicKeyHash(byte[] remoteDHPublicKeyHash) {
-		logger.finest("Storing encrypted remote public key hash.");
-		this.remoteDHPublicKeyHash = remoteDHPublicKeyHash;
-	}
-
-	private byte[] getRemoteDHPublicKeyHash() {
-		return remoteDHPublicKeyHash;
-	}
-
-	public KeyPair getLocalDHKeyPair() throws OtrException {
-		if (localDHKeyPair == null) {
-			localDHKeyPair = new OtrCryptoEngineImpl().generateDHKeyPair();
-			logger.finest("Generated local D-H key pair.");
-		}
-		return localDHKeyPair;
-	}
-
-	private int getLocalDHKeyPairID() {
-		return localDHPrivateKeyID;
-	}
-
-	private byte[] getLocalDHPublicKeyHash() throws OtrException {
-		if (localDHPublicKeyHash == null) {
-			localDHPublicKeyHash = new OtrCryptoEngineImpl()
-					.sha256Hash(getLocalDHPublicKeyBytes());
-			logger.finest("Hashed local D-H public key.");
-		}
-		return localDHPublicKeyHash;
-	}
-
-	private byte[] getLocalDHPublicKeyEncrypted() throws OtrException {
-		if (localDHPublicKeyEncrypted == null) {
-			localDHPublicKeyEncrypted = new OtrCryptoEngineImpl().aesEncrypt(
-					getR(), null, getLocalDHPublicKeyBytes());
-			logger.finest("Encrypted our D-H public key.");
-		}
-		return localDHPublicKeyEncrypted;
-	}
-
-	public BigInteger getS() throws OtrException {
-		if (s == null) {
-			s = new OtrCryptoEngineImpl().generateSecret(this
-					.getLocalDHKeyPair().getPrivate(), this
-					.getRemoteDHPublicKey());
-			logger.finest("Generated shared secret.");
-		}
-		return s;
-	}
-
-	private byte[] getC() throws OtrException {
-		if (c != null)
-			return c;
-
-		byte[] h2 = h2(C_START);
-		ByteBuffer buff = ByteBuffer.wrap(h2);
-		this.c = new byte[OtrCryptoEngine.AES_KEY_BYTE_LENGTH];
-		buff.get(this.c);
-		logger.finest("Computed c.");
-		return c;
-
-	}
-
-	private byte[] getM1() throws OtrException {
-		if (m1 != null)
-			return m1;
-
-		byte[] h2 = h2(M1_START);
-		ByteBuffer buff = ByteBuffer.wrap(h2);
-		byte[] m1 = new byte[OtrCryptoEngine.SHA256_HMAC_KEY_BYTE_LENGTH];
-		buff.get(m1);
-		logger.finest("Computed m1.");
-		this.m1 = m1;
-		return m1;
-	}
-
-	private byte[] getM2() throws OtrException {
-		if (m2 != null)
-			return m2;
-
-		byte[] h2 = h2(M2_START);
-		ByteBuffer buff = ByteBuffer.wrap(h2);
-		byte[] m2 = new byte[OtrCryptoEngine.SHA256_HMAC_KEY_BYTE_LENGTH];
-		buff.get(m2);
-		logger.finest("Computed m2.");
-		this.m2 = m2;
-		return m2;
-	}
-
-	private byte[] getCp() throws OtrException {
-		if (cp != null)
-			return cp;
-
-		byte[] h2 = h2(C_START);
-		ByteBuffer buff = ByteBuffer.wrap(h2);
-		byte[] cp = new byte[OtrCryptoEngine.AES_KEY_BYTE_LENGTH];
-		buff.position(OtrCryptoEngine.AES_KEY_BYTE_LENGTH);
-		buff.get(cp);
-		logger.finest("Computed c'.");
-		this.cp = cp;
-		return cp;
-	}
-
-	private byte[] getM1p() throws OtrException {
-		if (m1p != null)
-			return m1p;
-
-		byte[] h2 = h2(M1p_START);
-		ByteBuffer buff = ByteBuffer.wrap(h2);
-		byte[] m1p = new byte[OtrCryptoEngine.SHA256_HMAC_KEY_BYTE_LENGTH];
-		buff.get(m1p);
-		this.m1p = m1p;
-		logger.finest("Computed m1'.");
-		return m1p;
-	}
-
-	private byte[] getM2p() throws OtrException {
-		if (m2p != null)
-			return m2p;
-
-		byte[] h2 = h2(M2p_START);
-		ByteBuffer buff = ByteBuffer.wrap(h2);
-		byte[] m2p = new byte[OtrCryptoEngine.SHA256_HMAC_KEY_BYTE_LENGTH];
-		buff.get(m2p);
-		this.m2p = m2p;
-		logger.finest("Computed m2'.");
-		return m2p;
-	}
-
-	public KeyPair getLocalLongTermKeyPair() {
-		if (localLongTermKeyPair == null) {
-			localLongTermKeyPair = getSession().getLocalKeyPair();
-		}
-		return localLongTermKeyPair;
-	}
-
-	private byte[] h2(byte b) throws OtrException {
-		byte[] secbytes;
-		try {
-			secbytes = SerializationUtils.writeMpi(getS());
-		} catch (IOException e) {
-			throw new OtrException(e);
-		}
-
-		int len = secbytes.length + 1;
-		ByteBuffer buff = ByteBuffer.allocate(len);
-		buff.put(b);
-		buff.put(secbytes);
-		byte[] sdata = buff.array();
-		return new OtrCryptoEngineImpl().sha256Hash(sdata);
-	}
-
-	private byte[] getLocalDHPublicKeyBytes() throws OtrException {
-		if (localDHPublicKeyBytes == null) {
-			try {
-				this.localDHPublicKeyBytes = SerializationUtils
-						.writeMpi(((DHPublicKey) getLocalDHKeyPair()
-								.getPublic()).getY());
-
-			} catch (IOException e) {
-				throw new OtrException(e);
-			}
-
-		}
-		return localDHPublicKeyBytes;
-	}
-
-	public void handleReceivingMessage(AbstractMessage m) throws OtrException {
-
-		switch (m.messageType) {
-		case AbstractEncodedMessage.MESSAGE_DH_COMMIT:
-			handleDHCommitMessage((DHCommitMessage) m);
-			break;
-		case AbstractEncodedMessage.MESSAGE_DHKEY:
-			handleDHKeyMessage((DHKeyMessage) m);
-			break;
-		case AbstractEncodedMessage.MESSAGE_REVEALSIG:
-			handleRevealSignatureMessage((RevealSignatureMessage) m);
-			break;
-		case AbstractEncodedMessage.MESSAGE_SIGNATURE:
-			handleSignatureMessage((SignatureMessage) m);
-			break;
-		default:
-			throw new UnsupportedOperationException();
-		}
-	}
-
-	private void handleSignatureMessage(SignatureMessage m) throws OtrException {
-		Session session = getSession();
-		SessionID sessionID = session.getSessionID();
-		logger.finest(sessionID.getAccountID()
-				+ " received a signature message from " + sessionID.getUserID()
-				+ " throught " + sessionID.getProtocolName() + ".");
-		if (!session.getSessionPolicy().getAllowV2()) {
-			logger.finest("Policy does not allow OTRv2, ignoring message.");
-			return;
-		}
-
-		switch (this.getAuthenticationState()) {
-		case AWAITING_SIG:
-			// Verify MAC.
-			if (!m.verify(this.getM2p())) {
-				logger
-						.finest("Signature MACs are not equal, ignoring message.");
-				return;
-			}
-
-			// Decrypt X.
-			byte[] remoteXDecrypted = m.decrypt(this.getCp());
-			SignatureX remoteX;
-			try {
-				remoteX = SerializationUtils.toMysteriousX(remoteXDecrypted);
-			} catch (IOException e) {
-				throw new OtrException(e);
-			}
-			// Compute signature.
-			PublicKey remoteLongTermPublicKey = remoteX.longTermPublicKey;
-			SignatureM remoteM = new SignatureM(this.getRemoteDHPublicKey(),
-					(DHPublicKey) this.getLocalDHKeyPair().getPublic(),
-					remoteLongTermPublicKey, remoteX.dhKeyID);
-			OtrCryptoEngine otrCryptoEngine = new OtrCryptoEngineImpl();
-			// Verify signature.
-			byte[] signature;
-			try {
-				signature = otrCryptoEngine.sha256Hmac(SerializationUtils
-						.toByteArray(remoteM), this.getM1p());
-			} catch (IOException e) {
-				throw new OtrException(e);
-			}
-			if (!otrCryptoEngine.verify(signature, remoteLongTermPublicKey,
-					remoteX.signature)) {
-				logger.finest("Signature verification failed.");
-				return;
-			}
-
-			this.setIsSecure(true);
-			this.setRemoteLongTermPublicKey(remoteLongTermPublicKey);
-			break;
-		default:
-			logger
-					.finest("We were not expecting a signature, ignoring message.");
-			return;
-		}
-	}
-
-	private void handleRevealSignatureMessage(RevealSignatureMessage m)
-			throws OtrException {
-		Session session = getSession();
-		SessionID sessionID = session.getSessionID();
-		logger.finest(sessionID.getAccountID()
-				+ " received a reveal signature message from "
-				+ sessionID.getUserID() + " throught "
-				+ sessionID.getProtocolName() + ".");
-
-		if (!session.getSessionPolicy().getAllowV2()) {
-			logger.finest("Policy does not allow OTRv2, ignoring message.");
-			return;
-		}
-
-		switch (this.getAuthenticationState()) {
-		case AWAITING_REVEALSIG:
-			// Use the received value of r to decrypt the value of gx
-			// received
-			// in the D-H Commit Message, and verify the hash therein.
-			// Decrypt
-			// the encrypted signature, and verify the signature and the
-			// MACs.
-			// If everything checks out:
-
-			// * Reply with a Signature Message.
-			// * Transition authstate to AUTHSTATE_NONE.
-			// * Transition msgstate to MSGSTATE_ENCRYPTED.
-			// * TODO If there is a recent stored message, encrypt it and
-			// send
-			// it as a Data Message.
-
-			OtrCryptoEngine otrCryptoEngine = new OtrCryptoEngineImpl();
-			// Uses r to decrypt the value of gx sent earlier
-			byte[] remoteDHPublicKeyDecrypted = otrCryptoEngine.aesDecrypt(
-					m.revealedKey, null, this.getRemoteDHPublicKeyEncrypted());
-
-			// Verifies that HASH(gx) matches the value sent earlier
-			byte[] remoteDHPublicKeyHash = otrCryptoEngine
-					.sha256Hash(remoteDHPublicKeyDecrypted);
-			if (!Arrays.equals(remoteDHPublicKeyHash, this
-					.getRemoteDHPublicKeyHash())) {
-				logger.finest("Hashes don't match, ignoring message.");
-				return;
-			}
-
-			// Verifies that Bob's gx is a legal value (2 <= gx <=
-			// modulus-2)
-			BigInteger remoteDHPublicKeyMpi;
-			try {
-				remoteDHPublicKeyMpi = SerializationUtils
-						.readMpi(remoteDHPublicKeyDecrypted);
-			} catch (IOException e) {
-				throw new OtrException(e);
-			}
-
-			this.setRemoteDHPublicKey(otrCryptoEngine
-					.getDHPublicKey(remoteDHPublicKeyMpi));
-
-			// Verify received Data.
-			if (!m.verify(this.getM2())) {
-				logger
-						.finest("Signature MACs are not equal, ignoring message.");
-				return;
-			}
-
-			// Decrypt X.
-			byte[] remoteXDecrypted = m.decrypt(this.getC());
-			SignatureX remoteX;
-			try {
-				remoteX = SerializationUtils.toMysteriousX(remoteXDecrypted);
-			} catch (IOException e) {
-				throw new OtrException(e);
-			}
-
-			// Compute signature.
-			PublicKey remoteLongTermPublicKey = remoteX.longTermPublicKey;
-			SignatureM remoteM = new SignatureM(this.getRemoteDHPublicKey(),
-					(DHPublicKey) this.getLocalDHKeyPair().getPublic(),
-					remoteLongTermPublicKey, remoteX.dhKeyID);
-
-			// Verify signature.
-			byte[] signature;
-			try {
-				signature = otrCryptoEngine.sha256Hmac(SerializationUtils
-						.toByteArray(remoteM), this.getM1());
-			} catch (IOException e) {
-				throw new OtrException(e);
-			}
-
-			if (!otrCryptoEngine.verify(signature, remoteLongTermPublicKey,
-					remoteX.signature)) {
-				logger.finest("Signature verification failed.");
-				return;
-			}
-
-			logger.finest("Signature verification succeeded.");
-
-			this.setAuthenticationState(AuthContext.NONE);
-			this.setIsSecure(true);
-			this.setRemoteLongTermPublicKey(remoteLongTermPublicKey);
-			getSession().injectMessage(messageFactory.getSignatureMessage());
-			break;
-		default:
-			logger.finest("Ignoring message.");
-			break;
-		}
-	}
-
-	private void handleDHKeyMessage(DHKeyMessage m) throws OtrException {
-		Session session = getSession();
-		SessionID sessionID = session.getSessionID();
-		logger.finest(sessionID.getAccountID()
-				+ " received a D-H key message from " + sessionID.getUserID()
-				+ " throught " + sessionID.getProtocolName() + ".");
-
-		if (!session.getSessionPolicy().getAllowV2()) {
-			logger.finest("If ALLOW_V2 is not set, ignore this message.");
-			return;
-		}
-
-		switch (this.getAuthenticationState()) {
-		case AWAITING_DHKEY:
-			// Reply with a Reveal Signature Message and transition
-			// authstate to
-			// AUTHSTATE_AWAITING_SIG
-			this.setRemoteDHPublicKey(m.dhPublicKey);
-			this.setAuthenticationState(AuthContext.AWAITING_SIG);
-			getSession().injectMessage(
-					messageFactory.getRevealSignatureMessage());
-			logger.finest("Sent Reveal Signature.");
-			break;
-		case AWAITING_SIG:
-
-			if (m.dhPublicKey.getY().equals(this.getRemoteDHPublicKey().getY())) {
-				// If this D-H Key message is the same the one you received
-				// earlier (when you entered AUTHSTATE_AWAITING_SIG):
-				// Retransmit
-				// your Reveal Signature Message.
-				getSession().injectMessage(
-						messageFactory.getRevealSignatureMessage());
-				logger.finest("Resent Reveal Signature.");
-			} else {
-				// Otherwise: Ignore the message.
-				logger.finest("Ignoring message.");
-			}
-			break;
-		default:
-			// Ignore the message
-			break;
-		}
-	}
-
-	private void handleDHCommitMessage(DHCommitMessage m) throws OtrException {
-		Session session = getSession();
-		SessionID sessionID = session.getSessionID();
-		logger.finest(sessionID.getAccountID()
-				+ " received a D-H commit message from "
-				+ sessionID.getUserID() + " throught "
-				+ sessionID.getProtocolName() + ".");
-
-		if (!session.getSessionPolicy().getAllowV2()) {
-			logger.finest("ALLOW_V2 is not set, ignore this message.");
-			return;
-		}
-
-		switch (this.getAuthenticationState()) {
-		case NONE:
-			// Reply with a D-H Key Message, and transition authstate to
-			// AUTHSTATE_AWAITING_REVEALSIG.
-			this.reset();
-			this.setProtocolVersion(2);
-			this.setRemoteDHPublicKeyEncrypted(m.dhPublicKeyEncrypted);
-			this.setRemoteDHPublicKeyHash(m.dhPublicKeyHash);
-			this.setAuthenticationState(AuthContext.AWAITING_REVEALSIG);
-			getSession().injectMessage(messageFactory.getDHKeyMessage());
-			logger.finest("Sent D-H key.");
-			break;
-
-		case AWAITING_DHKEY:
-			// This is the trickiest transition in the whole protocol. It
-			// indicates that you have already sent a D-H Commit message to
-			// your
-			// correspondent, but that he either didn't receive it, or just
-			// didn't receive it yet, and has sent you one as well. The
-			// symmetry
-			// will be broken by comparing the hashed gx you sent in your
-			// D-H
-			// Commit Message with the one you received, considered as
-			// 32-byte
-			// unsigned big-endian values.
-			BigInteger ourHash = new BigInteger(1, this
-					.getLocalDHPublicKeyHash());
-			BigInteger theirHash = new BigInteger(1, m.dhPublicKeyHash);
-
-			if (theirHash.compareTo(ourHash) == -1) {
-				// Ignore the incoming D-H Commit message, but resend your
-				// D-H
-				// Commit message.
-				getSession().injectMessage(messageFactory.getDHCommitMessage());
-				logger
-						.finest("Ignored the incoming D-H Commit message, but resent our D-H Commit message.");
-			} else {
-				// *Forget* your old gx value that you sent (encrypted)
-				// earlier,
-				// and pretend you're in AUTHSTATE_NONE; i.e. reply with a
-				// D-H
-				// Key Message, and transition authstate to
-				// AUTHSTATE_AWAITING_REVEALSIG.
-				this.reset();
-				this.setProtocolVersion(2);
-				this.setRemoteDHPublicKeyEncrypted(m.dhPublicKeyEncrypted);
-				this.setRemoteDHPublicKeyHash(m.dhPublicKeyHash);
-				this.setAuthenticationState(AuthContext.AWAITING_REVEALSIG);
-				getSession().injectMessage(messageFactory.getDHKeyMessage());
-				logger
-						.finest("Forgot our old gx value that we sent (encrypted) earlier, and pretended we're in AUTHSTATE_NONE -> Sent D-H key.");
-			}
-			break;
-
-		case AWAITING_REVEALSIG:
-			// Retransmit your D-H Key Message (the same one as you sent
-			// when
-			// you entered AUTHSTATE_AWAITING_REVEALSIG). Forget the old D-H
-			// Commit message, and use this new one instead.
-			this.setRemoteDHPublicKeyEncrypted(m.dhPublicKeyEncrypted);
-			this.setRemoteDHPublicKeyHash(m.dhPublicKeyHash);
-			getSession().injectMessage(messageFactory.getDHKeyMessage());
-			logger.finest("Sent D-H key.");
-			break;
-		case AWAITING_SIG:
-			// Reply with a new D-H Key message, and transition authstate to
-			// AUTHSTATE_AWAITING_REVEALSIG
-			this.reset();
-			this.setRemoteDHPublicKeyEncrypted(m.dhPublicKeyEncrypted);
-			this.setRemoteDHPublicKeyHash(m.dhPublicKeyHash);
-			this.setAuthenticationState(AuthContext.AWAITING_REVEALSIG);
-			getSession().injectMessage(messageFactory.getDHKeyMessage());
-			logger.finest("Sent D-H key.");
-			break;
-		case V1_SETUP:
-			throw new UnsupportedOperationException();
-		}
-	}
-
-	public void startV2Auth() throws OtrException {
-		logger
-				.finest("Starting Authenticated Key Exchange, sending query message");
-		getSession().injectMessage(messageFactory.getQueryMessage());
-	}
-
-	public void respondV2Auth() throws OtrException {
-		logger.finest("Responding to Query Message");
-		this.reset();
-		this.setProtocolVersion(2);
-		this.setAuthenticationState(AuthContext.AWAITING_DHKEY);
-		logger.finest("Sending D-H Commit.");
-		getSession().injectMessage(messageFactory.getDHCommitMessage());
-	}
-
-	private void setSession(Session session) {
-		this.session = session;
-	}
-
-	private Session getSession() {
-		return session;
-	}
-
-	private PublicKey remoteLongTermPublicKey;
-
-	public PublicKey getRemoteLongTermPublicKey() {
-		return remoteLongTermPublicKey;
-	}
-
-	private void setRemoteLongTermPublicKey(PublicKey pubKey) {
-		this.remoteLongTermPublicKey = pubKey;
-	}
-}
--- a/app/src/main/java/net/java/otr4j/session/Session.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-package net.java.otr4j.session;
-
-import java.security.KeyPair;
-import java.security.PublicKey;
-import java.util.List;
-
-import net.java.otr4j.OtrEngineListener;
-import net.java.otr4j.OtrException;
-import net.java.otr4j.OtrPolicy;
-import net.java.otr4j.io.messages.AbstractMessage;
-import net.java.otr4j.session.SessionImpl.TLV;
-
-public interface Session {
-
-	public abstract SessionStatus getSessionStatus();
-
-	public abstract SessionID getSessionID();
-
-	public abstract void injectMessage(AbstractMessage m) throws OtrException;
-
-	public abstract KeyPair getLocalKeyPair();
-
-	public abstract OtrPolicy getSessionPolicy();
-
-	public abstract String transformReceiving(String content)
-			throws OtrException;
-
-	public abstract String transformSending(String content, List<TLV> tlvs)
-			throws OtrException;
-
-	public abstract void startSession() throws OtrException;
-
-	public abstract void endSession() throws OtrException;
-
-	public abstract void refreshSession() throws OtrException;
-
-	public abstract PublicKey getRemotePublicKey();
-
-	public abstract void addOtrEngineListener(OtrEngineListener l);
-
-	public abstract void removeOtrEngineListener(OtrEngineListener l);
-}
\ No newline at end of file
--- a/app/src/main/java/net/java/otr4j/session/SessionID.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.session;
-
-/**
- * 
- * @author George Politis
- * 
- */
-public final class SessionID {
-
-	public SessionID(String accountID, String userID, String protocolName) {
-		this.setAccountID(accountID);
-		this.setUserID(userID);
-		this.setProtocolName(protocolName);
-	}
-
-	private String accountID;
-	private String userID;
-	private String protocolName;
-	public static final SessionID Empty = new SessionID(null, null, null);
-
-	public void setAccountID(String accountID) {
-		this.accountID = accountID;
-	}
-
-	public String getAccountID() {
-		return accountID;
-	}
-
-	private void setUserID(String userID) {
-		this.userID = userID;
-	}
-
-	public String getUserID() {
-		return userID;
-	}
-
-	private void setProtocolName(String protocolName) {
-		this.protocolName = protocolName;
-	}
-
-	public String getProtocolName() {
-		return protocolName;
-	}
-
-	public String toString() {
-		return this.getAccountID() + "_" + this.getProtocolName() + "_"
-				+ this.getUserID();
-	}
-
-	public boolean equals(Object obj) {
-		if (obj == this)
-			return true;
-		if (obj == null || obj.getClass() != this.getClass())
-			return false;
-
-		SessionID sessionID = (SessionID) obj;
-
-		return this.toString().equals(sessionID.toString());
-	}
-
-	public int hashCode() {
-		return this.toString().hashCode();
-	}
-}
--- a/app/src/main/java/net/java/otr4j/session/SessionImpl.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,792 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-package net.java.otr4j.session;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.security.KeyPair;
-import java.security.PublicKey;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Vector;
-import java.util.logging.Logger;
-import javax.crypto.interfaces.DHPublicKey;
-
-import net.java.otr4j.OtrEngineHost;
-import net.java.otr4j.OtrEngineListener;
-import net.java.otr4j.OtrException;
-import net.java.otr4j.OtrPolicy;
-import net.java.otr4j.crypto.OtrCryptoEngine;
-import net.java.otr4j.crypto.OtrCryptoEngineImpl;
-import net.java.otr4j.io.OtrInputStream;
-import net.java.otr4j.io.OtrOutputStream;
-import net.java.otr4j.io.SerializationConstants;
-import net.java.otr4j.io.SerializationUtils;
-import net.java.otr4j.io.messages.DataMessage;
-import net.java.otr4j.io.messages.AbstractEncodedMessage;
-import net.java.otr4j.io.messages.ErrorMessage;
-import net.java.otr4j.io.messages.AbstractMessage;
-import net.java.otr4j.io.messages.MysteriousT;
-import net.java.otr4j.io.messages.PlainTextMessage;
-import net.java.otr4j.io.messages.QueryMessage;
-
-/**
- * 
- * @author George Politis
- */
-public class SessionImpl implements Session {
-
-	class TLV {
-		public TLV(int type, byte[] value) {
-			this.setType(type);
-			this.setValue(value);
-		}
-
-		public void setType(int type) {
-			this.type = type;
-		}
-
-		public int getType() {
-			return type;
-		}
-
-		public void setValue(byte[] value) {
-			this.value = value;
-		}
-
-		public byte[] getValue() {
-			return value;
-		}
-
-		private int type;
-		private byte[] value;
-	}
-
-	private SessionID sessionID;
-	private OtrEngineHost host;
-	private SessionStatus sessionStatus;
-	private AuthContext authContext;
-	private SessionKeys[][] sessionKeys;
-	private Vector<byte[]> oldMacKeys;
-	private static Logger logger = Logger
-			.getLogger(SessionImpl.class.getName());
-
-	public SessionImpl(SessionID sessionID, OtrEngineHost listener) {
-
-		this.setSessionID(sessionID);
-		this.setHost(listener);
-
-		// client application calls OtrEngine.getSessionStatus()
-		// -> create new session if it does not exist, end up here
-		// -> setSessionStatus() fires statusChangedEvent
-		// -> client application calls OtrEngine.getSessionStatus()
-		this.sessionStatus = SessionStatus.PLAINTEXT;
-	}
-
-	private SessionKeys getEncryptionSessionKeys() {
-		logger.finest("Getting encryption keys");
-		return getSessionKeysByIndex(SessionKeys.Previous, SessionKeys.Current);
-	}
-
-	private SessionKeys getMostRecentSessionKeys() {
-		logger.finest("Getting most recent keys.");
-		return getSessionKeysByIndex(SessionKeys.Current, SessionKeys.Current);
-	}
-
-	private SessionKeys getSessionKeysByID(int localKeyID, int remoteKeyID) {
-		logger
-				.finest("Searching for session keys with (localKeyID, remoteKeyID) = ("
-						+ localKeyID + "," + remoteKeyID + ")");
-
-		for (int i = 0; i < getSessionKeys().length; i++) {
-			for (int j = 0; j < getSessionKeys()[i].length; j++) {
-				SessionKeys current = getSessionKeysByIndex(i, j);
-				if (current.getLocalKeyID() == localKeyID
-						&& current.getRemoteKeyID() == remoteKeyID) {
-					logger.finest("Matching keys found.");
-					return current;
-				}
-			}
-		}
-
-		return null;
-	}
-
-	private SessionKeys getSessionKeysByIndex(int localKeyIndex,
-			int remoteKeyIndex) {
-		if (getSessionKeys()[localKeyIndex][remoteKeyIndex] == null)
-			getSessionKeys()[localKeyIndex][remoteKeyIndex] = new SessionKeysImpl(
-					localKeyIndex, remoteKeyIndex);
-
-		return getSessionKeys()[localKeyIndex][remoteKeyIndex];
-	}
-
-	private void rotateRemoteSessionKeys(DHPublicKey pubKey)
-			throws OtrException {
-
-		logger.finest("Rotating remote keys.");
-		SessionKeys sess1 = getSessionKeysByIndex(SessionKeys.Current,
-				SessionKeys.Previous);
-		if (sess1.getIsUsedReceivingMACKey()) {
-			logger
-					.finest("Detected used Receiving MAC key. Adding to old MAC keys to reveal it.");
-			getOldMacKeys().add(sess1.getReceivingMACKey());
-		}
-
-		SessionKeys sess2 = getSessionKeysByIndex(SessionKeys.Previous,
-				SessionKeys.Previous);
-		if (sess2.getIsUsedReceivingMACKey()) {
-			logger
-					.finest("Detected used Receiving MAC key. Adding to old MAC keys to reveal it.");
-			getOldMacKeys().add(sess2.getReceivingMACKey());
-		}
-
-		SessionKeys sess3 = getSessionKeysByIndex(SessionKeys.Current,
-				SessionKeys.Current);
-		sess1
-				.setRemoteDHPublicKey(sess3.getRemoteKey(), sess3
-						.getRemoteKeyID());
-
-		SessionKeys sess4 = getSessionKeysByIndex(SessionKeys.Previous,
-				SessionKeys.Current);
-		sess2
-				.setRemoteDHPublicKey(sess4.getRemoteKey(), sess4
-						.getRemoteKeyID());
-
-		sess3.setRemoteDHPublicKey(pubKey, sess3.getRemoteKeyID() + 1);
-		sess4.setRemoteDHPublicKey(pubKey, sess4.getRemoteKeyID() + 1);
-	}
-
-	private void rotateLocalSessionKeys() throws OtrException {
-
-		logger.finest("Rotating local keys.");
-		SessionKeys sess1 = getSessionKeysByIndex(SessionKeys.Previous,
-				SessionKeys.Current);
-		if (sess1.getIsUsedReceivingMACKey()) {
-			logger
-					.finest("Detected used Receiving MAC key. Adding to old MAC keys to reveal it.");
-			getOldMacKeys().add(sess1.getReceivingMACKey());
-		}
-
-		SessionKeys sess2 = getSessionKeysByIndex(SessionKeys.Previous,
-				SessionKeys.Previous);
-		if (sess2.getIsUsedReceivingMACKey()) {
-			logger
-					.finest("Detected used Receiving MAC key. Adding to old MAC keys to reveal it.");
-			getOldMacKeys().add(sess2.getReceivingMACKey());
-		}
-
-		SessionKeys sess3 = getSessionKeysByIndex(SessionKeys.Current,
-				SessionKeys.Current);
-		sess1.setLocalPair(sess3.getLocalPair(), sess3.getLocalKeyID());
-		SessionKeys sess4 = getSessionKeysByIndex(SessionKeys.Current,
-				SessionKeys.Previous);
-		sess2.setLocalPair(sess4.getLocalPair(), sess4.getLocalKeyID());
-
-		KeyPair newPair = new OtrCryptoEngineImpl().generateDHKeyPair();
-		sess3.setLocalPair(newPair, sess3.getLocalKeyID() + 1);
-		sess4.setLocalPair(newPair, sess4.getLocalKeyID() + 1);
-	}
-
-	private byte[] collectOldMacKeys() {
-		logger.finest("Collecting old MAC keys to be revealed.");
-		int len = 0;
-		for (int i = 0; i < getOldMacKeys().size(); i++)
-			len += getOldMacKeys().get(i).length;
-
-		ByteBuffer buff = ByteBuffer.allocate(len);
-		for (int i = 0; i < getOldMacKeys().size(); i++)
-			buff.put(getOldMacKeys().get(i));
-
-		getOldMacKeys().clear();
-		return buff.array();
-	}
-
-	private void setSessionStatus(SessionStatus sessionStatus)
-			throws OtrException {
-
-		if (sessionStatus == this.sessionStatus)
-			return;
-
-		switch (sessionStatus) {
-		case ENCRYPTED:
-			AuthContext auth = this.getAuthContext();
-			logger.finest("Setting most recent session keys from auth.");
-			for (int i = 0; i < this.getSessionKeys()[0].length; i++) {
-				SessionKeys current = getSessionKeysByIndex(0, i);
-				current.setLocalPair(auth.getLocalDHKeyPair(), 1);
-				current.setRemoteDHPublicKey(auth.getRemoteDHPublicKey(), 1);
-				current.setS(auth.getS());
-			}
-
-			KeyPair nextDH = new OtrCryptoEngineImpl().generateDHKeyPair();
-			for (int i = 0; i < this.getSessionKeys()[1].length; i++) {
-				SessionKeys current = getSessionKeysByIndex(1, i);
-				current.setRemoteDHPublicKey(auth.getRemoteDHPublicKey(), 1);
-				current.setLocalPair(nextDH, 2);
-			}
-
-			this.setRemotePublicKey(auth.getRemoteLongTermPublicKey());
-
-			auth.reset();
-			break;
-		}
-
-		this.sessionStatus = sessionStatus;
-
-		for (OtrEngineListener l : this.listeners)
-			l.sessionStatusChanged(getSessionID());
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see net.java.otr4j.session.ISession#getSessionStatus()
-	 */
-
-	public SessionStatus getSessionStatus() {
-		return sessionStatus;
-	}
-
-	private void setSessionID(SessionID sessionID) {
-		this.sessionID = sessionID;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see net.java.otr4j.session.ISession#getSessionID()
-	 */
-	public SessionID getSessionID() {
-		return sessionID;
-	}
-
-	private void setHost(OtrEngineHost host) {
-		this.host = host;
-	}
-
-	private OtrEngineHost getHost() {
-		return host;
-	}
-
-	private SessionKeys[][] getSessionKeys() {
-		if (sessionKeys == null)
-			sessionKeys = new SessionKeys[2][2];
-		return sessionKeys;
-	}
-
-	private AuthContext getAuthContext() {
-		if (authContext == null)
-			authContext = new AuthContextImpl(this);
-		return authContext;
-	}
-
-	private Vector<byte[]> getOldMacKeys() {
-		if (oldMacKeys == null)
-			oldMacKeys = new Vector<byte[]>();
-		return oldMacKeys;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see
-	 * net.java.otr4j.session.ISession#handleReceivingMessage(java.lang.String)
-	 */
-	public String transformReceiving(String msgText) throws OtrException {
-		OtrPolicy policy = getSessionPolicy();
-		if (!policy.getAllowV1() && !policy.getAllowV2()) {
-			logger
-					.finest("Policy does not allow neither V1 not V2, ignoring message.");
-			return msgText;
-		}
-
-		AbstractMessage m;
-		try {
-			m = SerializationUtils.toMessage(msgText);
-		} catch (IOException e) {
-			throw new OtrException(e);
-		}
-		
-		if (m == null)
-			return msgText; // Propably null or empty.
-
-		switch (m.messageType) {
-		case AbstractEncodedMessage.MESSAGE_DATA:
-			return handleDataMessage((DataMessage) m);
-		case AbstractMessage.MESSAGE_ERROR:
-			handleErrorMessage((ErrorMessage) m);
-			return null;
-		case AbstractMessage.MESSAGE_PLAINTEXT:
-			return handlePlainTextMessage((PlainTextMessage) m);
-		case AbstractMessage.MESSAGE_QUERY:
-			handleQueryMessage((QueryMessage) m);
-			return null;
-		case AbstractEncodedMessage.MESSAGE_DH_COMMIT:
-		case AbstractEncodedMessage.MESSAGE_DHKEY:
-		case AbstractEncodedMessage.MESSAGE_REVEALSIG:
-		case AbstractEncodedMessage.MESSAGE_SIGNATURE:
-			AuthContext auth = this.getAuthContext();
-			auth.handleReceivingMessage(m);
-
-			if (auth.getIsSecure()) {
-				this.setSessionStatus(SessionStatus.ENCRYPTED);
-				logger.finest("Gone Secure.");
-			}
-			return null;
-		default:
-			throw new UnsupportedOperationException(
-					"Received an uknown message type.");
-		}
-	}
-
-	private void handleQueryMessage(QueryMessage queryMessage)
-			throws OtrException {
-		logger.finest(getSessionID().getAccountID()
-				+ " received a query message from "
-				+ getSessionID().getUserID() + " throught "
-				+ getSessionID().getProtocolName() + ".");
-
-		setSessionStatus(SessionStatus.PLAINTEXT);
-
-		OtrPolicy policy = getSessionPolicy();
-		if (queryMessage.versions.contains(2) && policy.getAllowV2()) {
-			logger.finest("Query message with V2 support found.");
-			getAuthContext().respondV2Auth();
-		} else if (queryMessage.versions.contains(1) && policy.getAllowV1()) {
-			throw new UnsupportedOperationException();
-		}
-	}
-
-	private void handleErrorMessage(ErrorMessage errorMessage)
-			throws OtrException {
-		logger.finest(getSessionID().getAccountID()
-				+ " received an error message from "
-				+ getSessionID().getUserID() + " throught "
-				+ getSessionID().getUserID() + ".");
-
-		getHost().showError(this.getSessionID(), errorMessage.error);
-
-		OtrPolicy policy = getSessionPolicy();
-		if (policy.getErrorStartAKE()) {
-			logger.finest("Error message starts AKE.");
-			Vector<Integer> versions = new Vector<Integer>();
-			if (policy.getAllowV1())
-				versions.add(1);
-
-			if (policy.getAllowV2())
-				versions.add(2);
-
-			logger.finest("Sending Query");
-			injectMessage(new QueryMessage(versions));
-		}
-	}
-
-	private String handleDataMessage(DataMessage data) throws OtrException {
-		logger.finest(getSessionID().getAccountID()
-				+ " received a data message from " + getSessionID().getUserID()
-				+ ".");
-
-		switch (this.getSessionStatus()) {
-		case ENCRYPTED:
-			logger
-					.finest("Message state is ENCRYPTED. Trying to decrypt message.");
-
-			// Find matching session keys.
-			int senderKeyID = data.senderKeyID;
-			int receipientKeyID = data.recipientKeyID;
-			SessionKeys matchingKeys = this.getSessionKeysByID(receipientKeyID,
-					senderKeyID);
-
-			if (matchingKeys == null) {
-				logger.finest("No matching keys found.");
-				return null;
-			}
-
-			// Verify received MAC with a locally calculated MAC.
-			logger
-					.finest("Transforming T to byte[] to calculate it's HmacSHA1.");
-
-			byte[] serializedT;
-			try {
-				serializedT = SerializationUtils.toByteArray(data.getT());
-			} catch (IOException e) {
-				throw new OtrException(e);
-			}
-
-			OtrCryptoEngine otrCryptoEngine = new OtrCryptoEngineImpl();
-
-			byte[] computedMAC = otrCryptoEngine.sha1Hmac(serializedT,
-					matchingKeys.getReceivingMACKey(),
-					SerializationConstants.TYPE_LEN_MAC);
-
-			if (!Arrays.equals(computedMAC, data.mac)) {
-				logger.finest("MAC verification failed, ignoring message");
-				return null;
-			}
-
-			logger.finest("Computed HmacSHA1 value matches sent one.");
-
-			// Mark this MAC key as old to be revealed.
-			matchingKeys.setIsUsedReceivingMACKey(true);
-
-			matchingKeys.setReceivingCtr(data.ctr);
-
-			byte[] dmc = otrCryptoEngine.aesDecrypt(matchingKeys
-					.getReceivingAESKey(), matchingKeys.getReceivingCtr(),
-					data.encryptedMessage);
-			String decryptedMsgContent;
-			try {
-				// Expect bytes to be text encoded in UTF-8.
-				decryptedMsgContent = new String(dmc, "UTF-8");
-			} catch (UnsupportedEncodingException e) {
-				throw new OtrException(e);
-			}
-
-			logger.finest("Decrypted message: \"" + decryptedMsgContent + "\"");
-
-			// Rotate keys if necessary.
-			SessionKeys mostRecent = this.getMostRecentSessionKeys();
-			if (mostRecent.getLocalKeyID() == receipientKeyID)
-				this.rotateLocalSessionKeys();
-
-			if (mostRecent.getRemoteKeyID() == senderKeyID)
-				this.rotateRemoteSessionKeys(data.nextDH);
-
-			// Handle TLVs
-			List<TLV> tlvs = null;
-			int tlvIndex = decryptedMsgContent.indexOf((char) 0x0);
-			if (tlvIndex > -1) {
-				decryptedMsgContent = decryptedMsgContent
-						.substring(0, tlvIndex);
-				tlvIndex++;
-				byte[] tlvsb = new byte[dmc.length - tlvIndex];
-				System.arraycopy(dmc, tlvIndex, tlvsb, 0, tlvsb.length);
-
-				tlvs = new Vector<TLV>();
-				ByteArrayInputStream tin = new ByteArrayInputStream(tlvsb);
-				while (tin.available() > 0) {
-					int type;
-					byte[] tdata;
-					OtrInputStream eois = new OtrInputStream(tin);
-					try {
-						type = eois.readShort();
-						tdata = eois.readTlvData();
-						eois.close();
-					} catch (IOException e) {
-						throw new OtrException(e);
-					}
-
-					tlvs.add(new TLV(type, tdata));
-				}
-			}
-			if (tlvs != null && tlvs.size() > 0) {
-				for (TLV tlv : tlvs) {
-					switch (tlv.getType()) {
-					case 1:
-						this.setSessionStatus(SessionStatus.FINISHED);
-						return null;
-					default:
-						return decryptedMsgContent;
-					}
-				}
-			}
-
-			return decryptedMsgContent;
-
-		case FINISHED:
-		case PLAINTEXT:
-			getHost().showWarning(this.getSessionID(),
-					"Unreadable encrypted message was received.");
-
-			injectMessage(new ErrorMessage(AbstractMessage.MESSAGE_ERROR,
-					"You sent me an unreadable encrypted message.."));
-			break;
-		}
-
-		return null;
-	}
-
-	public void injectMessage(AbstractMessage m) throws OtrException {
-		String msg;
-		try {
-			msg = SerializationUtils.toString(m);
-		} catch (IOException e) {
-			throw new OtrException(e);
-		}
-		getHost().injectMessage(getSessionID(), msg);
-	}
-
-	private String handlePlainTextMessage(PlainTextMessage plainTextMessage)
-			throws OtrException {
-		logger.finest(getSessionID().getAccountID()
-				+ " received a plaintext message from "
-				+ getSessionID().getUserID() + " throught "
-				+ getSessionID().getProtocolName() + ".");
-
-		OtrPolicy policy = getSessionPolicy();
-		List<Integer> versions = plainTextMessage.versions;
-		if (versions == null || versions.size() < 1) {
-			logger
-					.finest("Received plaintext message without the whitespace tag.");
-			switch (this.getSessionStatus()) {
-			case ENCRYPTED:
-			case FINISHED:
-				// Display the message to the user, but warn him that the
-				// message was received unencrypted.
-				getHost().showWarning(this.getSessionID(),
-						"The message was received unencrypted.");
-				return plainTextMessage.cleanText;
-			case PLAINTEXT:
-				// Simply display the message to the user. If
-				// REQUIRE_ENCRYPTION
-				// is set, warn him that the message was received
-				// unencrypted.
-				if (policy.getRequireEncryption()) {
-					getHost().showWarning(this.getSessionID(),
-							"The message was received unencrypted.");
-				}
-				return plainTextMessage.cleanText;
-			}
-		} else {
-			logger
-					.finest("Received plaintext message with the whitespace tag.");
-			switch (this.getSessionStatus()) {
-			case ENCRYPTED:
-			case FINISHED:
-				// Remove the whitespace tag and display the message to the
-				// user, but warn him that the message was received
-				// unencrypted.
-				getHost().showWarning(this.getSessionID(),
-						"The message was received unencrypted.");
-			case PLAINTEXT:
-				// Remove the whitespace tag and display the message to the
-				// user. If REQUIRE_ENCRYPTION is set, warn him that the
-				// message
-				// was received unencrypted.
-				if (policy.getRequireEncryption())
-					getHost().showWarning(this.getSessionID(),
-							"The message was received unencrypted.");
-			}
-
-			if (policy.getWhitespaceStartAKE()) {
-				logger.finest("WHITESPACE_START_AKE is set");
-
-				if (plainTextMessage.versions.contains(2)
-						&& policy.getAllowV2()) {
-					logger.finest("V2 tag found.");
-					getAuthContext().respondV2Auth();
-				} else if (plainTextMessage.versions.contains(1)
-						&& policy.getAllowV1()) {
-					throw new UnsupportedOperationException();
-				}
-			}
-		}
-
-		return plainTextMessage.cleanText;
-	}
-
-	// Retransmit last sent message. Spec document does not mention where or
-	// when that should happen, must check libotr code.
-	private String lastSentMessage;
-
-	public String transformSending(String msgText, List<TLV> tlvs)
-			throws OtrException {
-
-		switch (this.getSessionStatus()) {
-		case PLAINTEXT:
-			if (getSessionPolicy().getRequireEncryption()) {
-				this.lastSentMessage = msgText;
-				this.startSession();
-			} else
-				// TODO this does not precisly behave according to
-				// specification.
-				return msgText;
-		case ENCRYPTED:
-			this.lastSentMessage = msgText;
-			logger.finest(getSessionID().getAccountID()
-					+ " sends an encrypted message to "
-					+ getSessionID().getUserID() + " throught "
-					+ getSessionID().getProtocolName() + ".");
-
-			// Get encryption keys.
-			SessionKeys encryptionKeys = this.getEncryptionSessionKeys();
-			int senderKeyID = encryptionKeys.getLocalKeyID();
-			int receipientKeyID = encryptionKeys.getRemoteKeyID();
-
-			// Increment CTR.
-			encryptionKeys.incrementSendingCtr();
-			byte[] ctr = encryptionKeys.getSendingCtr();
-
-			ByteArrayOutputStream out = new ByteArrayOutputStream();
-			if (msgText != null && msgText.length() > 0)
-				try {
-					out.write(msgText.getBytes("UTF8"));
-				} catch (IOException e) {
-					throw new OtrException(e);
-				}
-
-			// Append tlvs
-			if (tlvs != null && tlvs.size() > 0) {
-				out.write((byte) 0x00);
-
-				OtrOutputStream eoos = new OtrOutputStream(out);
-				for (TLV tlv : tlvs) {
-					try {
-						eoos.writeShort(tlv.type);
-						eoos.writeTlvData(tlv.value);
-					} catch (IOException e) {
-						throw new OtrException(e);
-					}
-				}
-			}
-
-			OtrCryptoEngine otrCryptoEngine = new OtrCryptoEngineImpl();
-
-			byte[] data = out.toByteArray();
-			// Encrypt message.
-			logger
-					.finest("Encrypting message with keyids (localKeyID, remoteKeyID) = ("
-							+ senderKeyID + ", " + receipientKeyID + ")");
-			byte[] encryptedMsg = otrCryptoEngine.aesEncrypt(encryptionKeys
-					.getSendingAESKey(), ctr, data);
-
-			// Get most recent keys to get the next D-H public key.
-			SessionKeys mostRecentKeys = this.getMostRecentSessionKeys();
-			DHPublicKey nextDH = (DHPublicKey) mostRecentKeys.getLocalPair()
-					.getPublic();
-
-			// Calculate T.
-			MysteriousT t = new MysteriousT(2, 0, senderKeyID, receipientKeyID,
-					nextDH, ctr, encryptedMsg);
-
-			// Calculate T hash.
-			byte[] sendingMACKey = encryptionKeys.getSendingMACKey();
-
-			logger
-					.finest("Transforming T to byte[] to calculate it's HmacSHA1.");
-			byte[] serializedT;
-			try {
-				serializedT = SerializationUtils.toByteArray(t);
-			} catch (IOException e) {
-				throw new OtrException(e);
-			}
-
-			byte[] mac = otrCryptoEngine.sha1Hmac(serializedT, sendingMACKey,
-					SerializationConstants.TYPE_LEN_MAC);
-
-			// Get old MAC keys to be revealed.
-			byte[] oldKeys = this.collectOldMacKeys();
-			DataMessage m = new DataMessage(t, mac, oldKeys);
-
-			try {
-				return SerializationUtils.toString(m);
-			} catch (IOException e) {
-				throw new OtrException(e);
-			}
-		case FINISHED:
-			this.lastSentMessage = msgText;
-			getHost()
-					.showError(
-							sessionID,
-							"Your message to "
-									+ sessionID.getUserID()
-									+ " was not sent.  Either end your private conversation, or restart it.");
-			return null;
-		default:
-			logger.finest("Uknown message state, not processing.");
-			return msgText;
-		}
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see net.java.otr4j.session.ISession#startSession()
-	 */
-	public void startSession() throws OtrException {
-		if (this.getSessionStatus() == SessionStatus.ENCRYPTED)
-			return;
-
-		if (!getSessionPolicy().getAllowV2())
-			throw new UnsupportedOperationException();
-
-		this.getAuthContext().startV2Auth();
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see net.java.otr4j.session.ISession#endSession()
-	 */
-	public void endSession() throws OtrException {
-		SessionStatus status = this.getSessionStatus();
-		switch (status) {
-		case ENCRYPTED:
-			Vector<TLV> tlvs = new Vector<TLV>();
-			tlvs.add(new TLV(1, null));
-
-			String msg = this.transformSending(null, tlvs);
-			getHost().injectMessage(getSessionID(), msg);
-			this.setSessionStatus(SessionStatus.PLAINTEXT);
-			break;
-		case FINISHED:
-			this.setSessionStatus(SessionStatus.PLAINTEXT);
-			break;
-		case PLAINTEXT:
-			return;
-		}
-
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see net.java.otr4j.session.ISession#refreshSession()
-	 */
-	public void refreshSession() throws OtrException {
-		this.endSession();
-		this.startSession();
-	}
-
-	private PublicKey remotePublicKey;
-
-	private void setRemotePublicKey(PublicKey pubKey) {
-		this.remotePublicKey = pubKey;
-	}
-
-	public PublicKey getRemotePublicKey() {
-		return remotePublicKey;
-	}
-
-	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);
-		}
-	}
-
-	public OtrPolicy getSessionPolicy() {
-		return getHost().getSessionPolicy(getSessionID());
-	}
-
-	public KeyPair getLocalKeyPair() {
-		return getHost().getKeyPair(this.getSessionID());
-	}
-}
--- a/app/src/main/java/net/java/otr4j/session/SessionKeys.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-package net.java.otr4j.session;
-
-import java.math.BigInteger;
-import java.security.KeyPair;
-
-import javax.crypto.interfaces.DHPublicKey;
-
-import net.java.otr4j.OtrException;
-
-interface SessionKeys {
-
-	public static final int Previous = 0;
-	public static final int Current = 1;
-	public static final byte HIGH_SEND_BYTE = (byte) 0x01;
-	public static final byte HIGH_RECEIVE_BYTE = (byte) 0x02;
-	public static final byte LOW_SEND_BYTE = (byte) 0x02;
-	public static final byte LOW_RECEIVE_BYTE = (byte) 0x01;
-
-	public abstract void setLocalPair(KeyPair keyPair, int localPairKeyID);
-
-	public abstract void setRemoteDHPublicKey(DHPublicKey pubKey,
-			int remoteKeyID);
-
-	public abstract void incrementSendingCtr();
-
-	public abstract byte[] getSendingCtr();
-
-	public abstract byte[] getReceivingCtr();
-
-	public abstract void setReceivingCtr(byte[] ctr);
-
-	public abstract byte[] getSendingAESKey() throws OtrException;
-
-	public abstract byte[] getReceivingAESKey() throws OtrException;
-
-	public abstract byte[] getSendingMACKey() throws OtrException;
-
-	public abstract byte[] getReceivingMACKey() throws OtrException;
-
-	public abstract void setS(BigInteger s);
-
-	public abstract void setIsUsedReceivingMACKey(Boolean isUsedReceivingMACKey);
-
-	public abstract Boolean getIsUsedReceivingMACKey();
-
-	public abstract int getLocalKeyID();
-
-	public abstract int getRemoteKeyID();
-
-	public abstract DHPublicKey getRemoteKey();
-
-	public abstract KeyPair getLocalPair();
-
-}
\ No newline at end of file
--- a/app/src/main/java/net/java/otr4j/session/SessionKeysImpl.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,240 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.session;
-
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.security.KeyPair;
-import java.util.Arrays;
-import java.util.logging.Logger;
-
-import javax.crypto.interfaces.DHPublicKey;
-
-import net.java.otr4j.OtrException;
-import net.java.otr4j.crypto.OtrCryptoEngine;
-import net.java.otr4j.crypto.OtrCryptoEngineImpl;
-import net.java.otr4j.io.SerializationUtils;
-
-/**
- * 
- * @author George Politis
- */
-class SessionKeysImpl implements SessionKeys {
-
-	private static Logger logger = Logger.getLogger(SessionKeysImpl.class
-			.getName());
-	private String keyDescription;
-
-	public SessionKeysImpl(int localKeyIndex, int remoteKeyIndex) {
-		if (localKeyIndex == 0)
-			keyDescription = "(Previous local, ";
-		else
-			keyDescription = "(Most recent local, ";
-
-		if (remoteKeyIndex == 0)
-			keyDescription += "Previous remote)";
-		else
-			keyDescription += "Most recent remote)";
-
-	}
-
-	public void setLocalPair(KeyPair keyPair, int localPairKeyID) {
-		this.localPair = keyPair;
-		this.setLocalKeyID(localPairKeyID);
-		logger.finest(keyDescription + " current local key ID: "
-				+ this.getLocalKeyID());
-		this.reset();
-	}
-
-	public void setRemoteDHPublicKey(DHPublicKey pubKey, int remoteKeyID) {
-		this.setRemoteKey(pubKey);
-		this.setRemoteKeyID(remoteKeyID);
-		logger.finest(keyDescription + " current remote key ID: "
-				+ this.getRemoteKeyID());
-		this.reset();
-	}
-
-	private byte[] sendingCtr = new byte[16];
-	private byte[] receivingCtr = new byte[16];
-
-	public void incrementSendingCtr() {
-		logger.finest("Incrementing counter for (localkeyID, remoteKeyID) = ("
-				+ getLocalKeyID() + "," + getRemoteKeyID() + ")");
-		// logger.debug("Counter prior increament: " +
-		// Utils.dump(sendingCtr,
-		// true, 16));
-		for (int i = 7; i >= 0; i--)
-			if (++sendingCtr[i] != 0)
-				break;
-		// logger.debug("Counter after increament: " +
-		// Utils.dump(sendingCtr,
-		// true, 16));
-	}
-
-	public byte[] getSendingCtr() {
-		return sendingCtr;
-	}
-
-	public byte[] getReceivingCtr() {
-		return receivingCtr;
-	}
-
-	public void setReceivingCtr(byte[] ctr) {
-		for (int i = 0; i < ctr.length; i++)
-			receivingCtr[i] = ctr[i];
-	}
-
-	private void reset() {
-		logger.finest("Resetting " + keyDescription + " session keys.");
-		Arrays.fill(this.sendingCtr, (byte) 0x00);
-		Arrays.fill(this.receivingCtr, (byte) 0x00);
-		this.sendingAESKey = null;
-		this.receivingAESKey = null;
-		this.sendingMACKey = null;
-		this.receivingMACKey = null;
-		this.setIsUsedReceivingMACKey(false);
-		this.s = null;
-		if (getLocalPair() != null && getRemoteKey() != null) {
-			this.isHigh = ((DHPublicKey) getLocalPair().getPublic()).getY()
-					.abs().compareTo(getRemoteKey().getY().abs()) == 1;
-		}
-
-	}
-
-	private byte[] h1(byte b) throws OtrException {
-
-		try {
-			byte[] secbytes = SerializationUtils.writeMpi(getS());
-
-			int len = secbytes.length + 1;
-			ByteBuffer buff = ByteBuffer.allocate(len);
-			buff.put(b);
-			buff.put(secbytes);
-			byte[] result = new OtrCryptoEngineImpl().sha1Hash(buff.array());
-			return result;
-		} catch (Exception e) {
-			throw new OtrException(e);
-		}
-	}
-
-	public byte[] getSendingAESKey() throws OtrException {
-		if (sendingAESKey != null)
-			return sendingAESKey;
-
-		byte sendbyte = LOW_SEND_BYTE;
-		if (this.isHigh)
-			sendbyte = HIGH_SEND_BYTE;
-
-		byte[] h1 = h1(sendbyte);
-
-		byte[] key = new byte[OtrCryptoEngine.AES_KEY_BYTE_LENGTH];
-		ByteBuffer buff = ByteBuffer.wrap(h1);
-		buff.get(key);
-		logger.finest("Calculated sending AES key.");
-		this.sendingAESKey = key;
-		return sendingAESKey;
-	}
-
-	public byte[] getReceivingAESKey() throws OtrException {
-		if (receivingAESKey != null)
-			return receivingAESKey;
-
-		byte receivebyte = LOW_RECEIVE_BYTE;
-		if (this.isHigh)
-			receivebyte = HIGH_RECEIVE_BYTE;
-
-		byte[] h1 = h1(receivebyte);
-
-		byte[] key = new byte[OtrCryptoEngine.AES_KEY_BYTE_LENGTH];
-		ByteBuffer buff = ByteBuffer.wrap(h1);
-		buff.get(key);
-		logger.finest("Calculated receiving AES key.");
-		this.receivingAESKey = key;
-
-		return receivingAESKey;
-	}
-
-	public byte[] getSendingMACKey() throws OtrException {
-		if (sendingMACKey != null)
-			return sendingMACKey;
-
-		sendingMACKey = new OtrCryptoEngineImpl().sha1Hash(getSendingAESKey());
-		logger.finest("Calculated sending MAC key.");
-		return sendingMACKey;
-	}
-
-	public byte[] getReceivingMACKey() throws OtrException {
-		if (receivingMACKey == null) {
-			receivingMACKey = new OtrCryptoEngineImpl()
-					.sha1Hash(getReceivingAESKey());
-			logger.finest("Calculated receiving AES key.");
-		}
-		return receivingMACKey;
-	}
-
-	private BigInteger getS() throws OtrException {
-		if (s == null) {
-			s = new OtrCryptoEngineImpl().generateSecret(getLocalPair()
-					.getPrivate(), getRemoteKey());
-			logger.finest("Calculating shared secret S.");
-		}
-		return s;
-	}
-
-	public void setS(BigInteger s) {
-		this.s = s;
-	}
-
-	public void setIsUsedReceivingMACKey(Boolean isUsedReceivingMACKey) {
-		this.isUsedReceivingMACKey = isUsedReceivingMACKey;
-	}
-
-	public Boolean getIsUsedReceivingMACKey() {
-		return isUsedReceivingMACKey;
-	}
-
-	private void setLocalKeyID(int localKeyID) {
-		this.localKeyID = localKeyID;
-	}
-
-	public int getLocalKeyID() {
-		return localKeyID;
-	}
-
-	private void setRemoteKeyID(int remoteKeyID) {
-		this.remoteKeyID = remoteKeyID;
-	}
-
-	public int getRemoteKeyID() {
-		return remoteKeyID;
-	}
-
-	private void setRemoteKey(DHPublicKey remoteKey) {
-		this.remoteKey = remoteKey;
-	}
-
-	public DHPublicKey getRemoteKey() {
-		return remoteKey;
-	}
-
-	public KeyPair getLocalPair() {
-		return localPair;
-	}
-
-	private int localKeyID;
-	private int remoteKeyID;
-	private DHPublicKey remoteKey;
-	private KeyPair localPair;
-
-	private byte[] sendingAESKey;
-	private byte[] receivingAESKey;
-	private byte[] sendingMACKey;
-	private byte[] receivingMACKey;
-	private Boolean isUsedReceivingMACKey;
-	private BigInteger s;
-	private Boolean isHigh;
-}
--- a/app/src/main/java/net/java/otr4j/session/SessionStatus.java	Sun Mar 15 18:57:24 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-/*
- * otr4j, the open source java otr library.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.otr4j.session;
-
-/**
- * 
- * @author George Politis
- */
-public enum SessionStatus {
-	PLAINTEXT,
-	ENCRYPTED,
-	FINISHED
-}