// Path: src/main/java/net/java/otr4j/OtrEngineHost.java
// public interface OtrEngineHost {
// 	void injectMessage(SessionID sessionID, String msg)
// 			throws OtrException;
// 
// 	void unreadableMessageReceived(SessionID sessionID)
// 			throws OtrException;
// 
// 	void unencryptedMessageReceived(SessionID sessionID,
// 			String msg) throws OtrException;
// 
// 	void showError(SessionID sessionID, String error)
// 			throws OtrException;
// 
// 	void smpError(SessionID sessionID, int tlvType,
// 			boolean cheated) throws OtrException;
// 
// 	void smpAborted(SessionID sessionID) throws OtrException;
// 
// 	void finishedSessionMessage(SessionID sessionID,
// 			String msgText) throws OtrException;
// 
// 	void requireEncryptedMessage(SessionID sessionID,
// 			String msgText) throws OtrException;
// 
// 	OtrPolicy getSessionPolicy(SessionID sessionID);
// 
// 	/**
// 	 * Get instructions for the necessary fragmentation operations.
// 	 *
// 	 * If no fragmentation is necessary, return {@code null} to set the default
// 	 * fragmentation instructions which are to use an unlimited number of
// 	 * messages of unlimited size each. Hence fragmentation is not necessary or
// 	 * applied.
// 	 *
// 	 * @param sessionID
// 	 *            the session ID of the session
// 	 * @return return fragmentation instructions or null for defaults (i.e. no
// 	 *         fragmentation)
// 	 */
// 	FragmenterInstructions getFragmenterInstructions(SessionID sessionID);
// 
// 	KeyPair getLocalKeyPair(SessionID sessionID)
// 			throws OtrException;
// 
// 	byte[] getLocalFingerprintRaw(SessionID sessionID);
// 
// 	void askForSecret(SessionID sessionID, InstanceTag receiverTag, String question);
// 
// 	void verify(SessionID sessionID, String fingerprint, boolean approved);
// 
// 	void unverify(SessionID sessionID, String fingerprint);
// 
// 	String getReplyForUnreadableMessage(SessionID sessionID);
// 
// 	String getFallbackMessage(SessionID sessionID);
// 
// 	void messageFromAnotherInstanceReceived(SessionID sessionID);
// 
// 	void multipleInstancesDetected(SessionID sessionID);
// }
// 
// Path: src/main/java/net/java/otr4j/OtrException.java
// @SuppressWarnings("serial")
// public class OtrException extends Exception {
// 	public OtrException(Exception e) {
// 		super(e);
// 	}
// }
// 
// Path: src/main/java/net/java/otr4j/OtrPolicy.java
// public interface OtrPolicy {
// 
// 	int ALLOW_V1 = 0x01;
// 	int ALLOW_V2 = 0x02;
// 	int ALLOW_V3 = 0x40; // ALLOW_V3 is set to 0x40 for compatibility with older versions
// 	int REQUIRE_ENCRYPTION = 0x04;
// 	int SEND_WHITESPACE_TAG = 0x8;
// 	int WHITESPACE_START_AKE = 0x10;
// 	int ERROR_START_AKE = 0x20;
// 	int VERSION_MASK = (ALLOW_V1 | ALLOW_V2 | ALLOW_V3);
// 
// 	// The four old version 1 policies correspond to the following combinations
// 	// of flags (adding an allowance for version 2 of the protocol):
// 
// 	int NEVER = 0x00;
// 	int OPPORTUNISTIC = (ALLOW_V1 | ALLOW_V2 | ALLOW_V3
// 			| SEND_WHITESPACE_TAG | WHITESPACE_START_AKE | ERROR_START_AKE);
// 	int OTRL_POLICY_MANUAL = (ALLOW_V1 | ALLOW_V2 | ALLOW_V3);
// 	int OTRL_POLICY_ALWAYS = (ALLOW_V1 | ALLOW_V2 | ALLOW_V3
// 			| REQUIRE_ENCRYPTION | WHITESPACE_START_AKE | ERROR_START_AKE);
// 	int OTRL_POLICY_DEFAULT = OPPORTUNISTIC;
// 
// 	boolean getAllowV1();
// 
// 	boolean getAllowV2();
// 
// 	boolean getAllowV3();
// 
// 	boolean getRequireEncryption();
// 
// 	boolean getSendWhitespaceTag();
// 
// 	boolean getWhitespaceStartAKE();
// 
// 	boolean getErrorStartAKE();
// 
// 	int getPolicy();
// 
// 	void setAllowV1(boolean value);
// 
// 	void setAllowV2(boolean value);
// 
// 	void setAllowV3(boolean value);
// 
// 	void setRequireEncryption(boolean value);
// 
// 	void setSendWhitespaceTag(boolean value);
// 
// 	void setWhitespaceStartAKE(boolean value);
// 
// 	void setErrorStartAKE(boolean value);
// 
// 	void setEnableAlways(boolean value);
// 
// 	boolean getEnableAlways();
// 
// 	void setEnableManual(boolean value);
// 
// 	boolean getEnableManual();
// }


import java.security.KeyPair;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.logging.Logger;
import net.java.otr4j.OtrEngineHost;
import net.java.otr4j.OtrException;
import net.java.otr4j.OtrPolicy;
import net.java.otr4j.crypto.OtrCryptoEngineImpl;
import net.java.otr4j.crypto.OtrCryptoException;
							stop();
						}
					} else {
						try {
							process(m);
						} catch (OtrException e) {
							e.printStackTrace();
							stopped = true;
						}
					}
				}
			}
		}

		public void enqueue(String sender, String s) {
			synchronized (messageQueue) {
				messageQueue.add(new Message(sender, s));
				messageQueue.notify();
			}
		}

		public void stop() {
			stopped = true;

			synchronized (messageQueue) {
				messageQueue.notify();
			}
		}
	}

// Path: src/main/java/net/java/otr4j/OtrEngineHost.java
// public interface OtrEngineHost {
// 	void injectMessage(SessionID sessionID, String msg)
// 			throws OtrException;
// 
// 	void unreadableMessageReceived(SessionID sessionID)
// 			throws OtrException;
// 
// 	void unencryptedMessageReceived(SessionID sessionID,
// 			String msg) throws OtrException;
// 
// 	void showError(SessionID sessionID, String error)
// 			throws OtrException;
// 
// 	void smpError(SessionID sessionID, int tlvType,
// 			boolean cheated) throws OtrException;
// 
// 	void smpAborted(SessionID sessionID) throws OtrException;
// 
// 	void finishedSessionMessage(SessionID sessionID,
// 			String msgText) throws OtrException;
// 
// 	void requireEncryptedMessage(SessionID sessionID,
// 			String msgText) throws OtrException;
// 
// 	OtrPolicy getSessionPolicy(SessionID sessionID);
// 
// 	/**
// 	 * Get instructions for the necessary fragmentation operations.
// 	 *
// 	 * If no fragmentation is necessary, return {@code null} to set the default
// 	 * fragmentation instructions which are to use an unlimited number of
// 	 * messages of unlimited size each. Hence fragmentation is not necessary or
// 	 * applied.
// 	 *
// 	 * @param sessionID
// 	 *            the session ID of the session
// 	 * @return return fragmentation instructions or null for defaults (i.e. no
// 	 *         fragmentation)
// 	 */
// 	FragmenterInstructions getFragmenterInstructions(SessionID sessionID);
// 
// 	KeyPair getLocalKeyPair(SessionID sessionID)
// 			throws OtrException;
// 
// 	byte[] getLocalFingerprintRaw(SessionID sessionID);
// 
// 	void askForSecret(SessionID sessionID, InstanceTag receiverTag, String question);
// 
// 	void verify(SessionID sessionID, String fingerprint, boolean approved);
// 
// 	void unverify(SessionID sessionID, String fingerprint);
// 
// 	String getReplyForUnreadableMessage(SessionID sessionID);
// 
// 	String getFallbackMessage(SessionID sessionID);
// 
// 	void messageFromAnotherInstanceReceived(SessionID sessionID);
// 
// 	void multipleInstancesDetected(SessionID sessionID);
// }
// 
// Path: src/main/java/net/java/otr4j/OtrException.java
// @SuppressWarnings("serial")
// public class OtrException extends Exception {
// 	public OtrException(Exception e) {
// 		super(e);
// 	}
// }
// 
// Path: src/main/java/net/java/otr4j/OtrPolicy.java
// public interface OtrPolicy {
// 
// 	int ALLOW_V1 = 0x01;
// 	int ALLOW_V2 = 0x02;
// 	int ALLOW_V3 = 0x40; // ALLOW_V3 is set to 0x40 for compatibility with older versions
// 	int REQUIRE_ENCRYPTION = 0x04;
// 	int SEND_WHITESPACE_TAG = 0x8;
// 	int WHITESPACE_START_AKE = 0x10;
// 	int ERROR_START_AKE = 0x20;
// 	int VERSION_MASK = (ALLOW_V1 | ALLOW_V2 | ALLOW_V3);
// 
// 	// The four old version 1 policies correspond to the following combinations
// 	// of flags (adding an allowance for version 2 of the protocol):
// 
// 	int NEVER = 0x00;
// 	int OPPORTUNISTIC = (ALLOW_V1 | ALLOW_V2 | ALLOW_V3
// 			| SEND_WHITESPACE_TAG | WHITESPACE_START_AKE | ERROR_START_AKE);
// 	int OTRL_POLICY_MANUAL = (ALLOW_V1 | ALLOW_V2 | ALLOW_V3);
// 	int OTRL_POLICY_ALWAYS = (ALLOW_V1 | ALLOW_V2 | ALLOW_V3
// 			| REQUIRE_ENCRYPTION | WHITESPACE_START_AKE | ERROR_START_AKE);
// 	int OTRL_POLICY_DEFAULT = OPPORTUNISTIC;
// 
// 	boolean getAllowV1();
// 
// 	boolean getAllowV2();
// 
// 	boolean getAllowV3();
// 
// 	boolean getRequireEncryption();
// 
// 	boolean getSendWhitespaceTag();
// 
// 	boolean getWhitespaceStartAKE();
// 
// 	boolean getErrorStartAKE();
// 
// 	int getPolicy();
// 
// 	void setAllowV1(boolean value);
// 
// 	void setAllowV2(boolean value);
// 
// 	void setAllowV3(boolean value);
// 
// 	void setRequireEncryption(boolean value);
// 
// 	void setSendWhitespaceTag(boolean value);
// 
// 	void setWhitespaceStartAKE(boolean value);
// 
// 	void setErrorStartAKE(boolean value);
// 
// 	void setEnableAlways(boolean value);
// 
// 	boolean getEnableAlways();
// 
// 	void setEnableManual(boolean value);
// 
// 	boolean getEnableManual();
// }


// Path: src/test/java/net/java/otr4j/session/DummyClient.java
import java.security.KeyPair;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.logging.Logger;
import net.java.otr4j.OtrEngineHost;
import net.java.otr4j.OtrException;
import net.java.otr4j.OtrPolicy;
import net.java.otr4j.crypto.OtrCryptoEngineImpl;
import net.java.otr4j.crypto.OtrCryptoException;

							stop();
						}
					} else {
						try {
							process(m);
						} catch (OtrException e) {
							e.printStackTrace();
							stopped = true;
						}
					}
				}
			}
		}

		public void enqueue(String sender, String s) {
			synchronized (messageQueue) {
				messageQueue.add(new Message(sender, s));
				messageQueue.notify();
			}
		}

		public void stop() {
			stopped = true;

			synchronized (messageQueue) {
				messageQueue.notify();
			}
		}
	}

	class DummyOtrEngineHostImpl implements OtrEngineHost {