From 0dbfd7073f8edf6e3b9afde05da7ff16bedc8f2d Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Thu, 29 Jan 2015 11:05:46 +0000
Subject: [PATCH] Comments to indicate which locks guard which variables.

---
 .../AndroidNotificationManagerImpl.java       |  10 +-
 .../android/ReferenceManagerImpl.java         |   6 +-
 .../briarproject/crypto/FortunaGenerator.java |   5 +-
 .../src/org/briarproject/db/JdbcDatabase.java |   7 +-
 .../invitation/ConnectorGroup.java            |   5 +-
 .../lifecycle/ShutdownManagerImpl.java        |   6 +-
 .../plugins/ConnectionRegistryImpl.java       |   7 +-
 .../briarproject/reliability/Receiver.java    |  20 +-
 .../org/briarproject/reliability/Sender.java  |  24 +-
 .../transport/KeyManagerImpl.java             |  10 +-
 .../transport/KeyManagerImpl.java.orig        | 546 ------------------
 .../transport/TagRecogniserImpl.java          |   5 +-
 .../transport/TransportTagRecogniser.java     |   6 +-
 .../TransportTagRecogniser.java.orig          | 235 --------
 .../lifecycle/WindowsShutdownManagerImpl.java |   5 +-
 .../file/PollingRemovableDriveMonitor.java    |   5 +-
 .../PollingRemovableDriveMonitor.java.orig    |  83 ---
 .../file/UnixRemovableDriveMonitor.java       |  12 +-
 .../plugins/modem/CountryCodes.java           | 309 +++++-----
 .../briarproject/plugins/modem/ModemImpl.java |  11 +-
 .../crypto/StreamEncrypterImplTest.java       |   6 +-
 21 files changed, 233 insertions(+), 1090 deletions(-)
 delete mode 100644 briar-core/src/org/briarproject/transport/KeyManagerImpl.java.orig
 delete mode 100644 briar-core/src/org/briarproject/transport/TransportTagRecogniser.java.orig
 delete mode 100644 briar-desktop/src/org/briarproject/plugins/file/PollingRemovableDriveMonitor.java.orig

diff --git a/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java b/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java
index 90842481cf..0f6bccfe6f 100644
--- a/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java
+++ b/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java
@@ -61,18 +61,18 @@ Service, EventListener {
 	private final Executor dbExecutor;
 	private final EventBus eventBus;
 	private final Context appContext;
+	private final Lock synchLock = new ReentrantLock();
+
+	// The following are locking: synchLock
 	private final Map<ContactId, Integer> contactCounts =
 			new HashMap<ContactId, Integer>();
 	private final Map<GroupId, Integer> groupCounts =
 			new HashMap<GroupId, Integer>();
-
 	private int privateTotal = 0, groupTotal = 0;
 	private int nextRequestId = 0;
 
 	private volatile Settings settings = new Settings();
 
-	private final Lock synchLock = new ReentrantLock();
-
 	@Inject
 	public AndroidNotificationManagerImpl(DatabaseComponent db,
 			@DatabaseExecutor Executor dbExecutor, EventBus eventBus,
@@ -136,6 +136,7 @@ Service, EventListener {
 		}
 	}
 
+	// Locking: synchLock
 	private void updatePrivateMessageNotification() {
 		if(privateTotal == 0) {
 			clearPrivateMessageNotification();
@@ -180,6 +181,7 @@ Service, EventListener {
 		}
 	}
 
+	// Locking: synchLock
 	private void clearPrivateMessageNotification() {
 		Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
 		NotificationManager nm = (NotificationManager) o;
@@ -222,6 +224,7 @@ Service, EventListener {
 		}
 	}
 
+	// Locking: synchLock
 	private void updateGroupPostNotification() {
 		if(groupTotal == 0) {
 			clearGroupPostNotification();
@@ -266,6 +269,7 @@ Service, EventListener {
 		}
 	}
 
+	// Locking: synchLock
 	private void clearGroupPostNotification() {
 		Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
 		NotificationManager nm = (NotificationManager) o;
diff --git a/briar-android/src/org/briarproject/android/ReferenceManagerImpl.java b/briar-android/src/org/briarproject/android/ReferenceManagerImpl.java
index e345b02d06..b7b764f097 100644
--- a/briar-android/src/org/briarproject/android/ReferenceManagerImpl.java
+++ b/briar-android/src/org/briarproject/android/ReferenceManagerImpl.java
@@ -15,13 +15,13 @@ class ReferenceManagerImpl implements ReferenceManager {
 	private static final Logger LOG =
 			Logger.getLogger(ReferenceManagerImpl.class.getName());
 
+	private final Lock synchLock = new ReentrantLock();
+
+	// The following are locking: synchLock
 	private final Map<Class<?>, Map<Long, Object>> outerMap =
 			new HashMap<Class<?>, Map<Long, Object>>();
-
 	private long nextHandle = 0;
 
-	private final Lock synchLock = new ReentrantLock();
-
 	public <T> T getReference(long handle, Class<T> c) {
 		synchLock.lock();
 		try {
diff --git a/briar-core/src/org/briarproject/crypto/FortunaGenerator.java b/briar-core/src/org/briarproject/crypto/FortunaGenerator.java
index f804db971d..4045db3ce1 100644
--- a/briar-core/src/org/briarproject/crypto/FortunaGenerator.java
+++ b/briar-core/src/org/briarproject/crypto/FortunaGenerator.java
@@ -19,6 +19,9 @@ class FortunaGenerator {
 	private static final int KEY_BYTES = 32;
 	private static final int BLOCK_BYTES = 16;
 
+	private final Lock synchLock = new ReentrantLock();
+
+	// The following are locking: synchLock
 	private final MessageDigest digest = new DoubleDigest(new SHA256Digest());
 	private final BlockCipher cipher = new AESLightEngine();
 	private final byte[] key = new byte[KEY_BYTES];
@@ -26,8 +29,6 @@ class FortunaGenerator {
 	private final byte[] buffer = new byte[BLOCK_BYTES];
 	private final byte[] newKey = new byte[KEY_BYTES];
 
-	private final Lock synchLock = new ReentrantLock();
-
 	FortunaGenerator(byte[] seed) {
 		reseed(seed);
 	}
diff --git a/briar-core/src/org/briarproject/db/JdbcDatabase.java b/briar-core/src/org/briarproject/db/JdbcDatabase.java
index 19ea75e13c..256cda0dfc 100644
--- a/briar-core/src/org/briarproject/db/JdbcDatabase.java
+++ b/briar-core/src/org/briarproject/db/JdbcDatabase.java
@@ -316,12 +316,12 @@ abstract class JdbcDatabase implements Database<Connection> {
 	private final Clock clock;
 
 	private final LinkedList<Connection> connections =
-			new LinkedList<Connection>();
+			new LinkedList<Connection>(); // Locking: connectionsLock
 
 	private final AtomicInteger transactionCount = new AtomicInteger(0);
 
-	private int openConnections = 0;
-	private boolean closed = false;
+	private int openConnections = 0; // Locking: connectionsLock
+	private boolean closed = false; // Locking: connectionsLock
 
 	protected abstract Connection createConnection() throws SQLException;
 	protected abstract void flushBuffersToDisk(Statement s) throws SQLException;
@@ -444,7 +444,6 @@ abstract class JdbcDatabase implements Database<Connection> {
 		} finally {
 			connectionsLock.unlock();
 		}
-
 		try {
 			if(txn == null) {
 				// Open a new connection
diff --git a/briar-core/src/org/briarproject/invitation/ConnectorGroup.java b/briar-core/src/org/briarproject/invitation/ConnectorGroup.java
index b8f471229c..97bd39ddaa 100644
--- a/briar-core/src/org/briarproject/invitation/ConnectorGroup.java
+++ b/briar-core/src/org/briarproject/invitation/ConnectorGroup.java
@@ -62,12 +62,9 @@ class ConnectorGroup extends Thread implements InvitationTask {
 	private final Collection<InvitationListener> listeners;
 	private final AtomicBoolean connected;
 	private final CountDownLatch localConfirmationLatch;
-
 	private final Lock synchLock = new ReentrantLock();
 
-	/*The state that's accessed in addListener() after
-	 * calling listeners.add() must be guarded by a lock.
-	 */
+	// The following are locking: synchLock
 	private int localConfirmationCode = -1, remoteConfirmationCode = -1;
 	private boolean connectionFailed = false;
 	private boolean localCompared = false, remoteCompared = false;
diff --git a/briar-core/src/org/briarproject/lifecycle/ShutdownManagerImpl.java b/briar-core/src/org/briarproject/lifecycle/ShutdownManagerImpl.java
index 030d15483a..880db5b5eb 100644
--- a/briar-core/src/org/briarproject/lifecycle/ShutdownManagerImpl.java
+++ b/briar-core/src/org/briarproject/lifecycle/ShutdownManagerImpl.java
@@ -9,12 +9,12 @@ import org.briarproject.api.lifecycle.ShutdownManager;
 
 class ShutdownManagerImpl implements ShutdownManager {
 
-	protected final Map<Integer, Thread> hooks;
+	private final Lock synchLock = new ReentrantLock();
 
+	// The following are locking: synchLock
+	protected final Map<Integer, Thread> hooks;
 	private int nextHandle = 0;
 
-	private final Lock synchLock = new ReentrantLock();
-
 	ShutdownManagerImpl() {
 		hooks = new HashMap<Integer, Thread>();
 	}
diff --git a/briar-core/src/org/briarproject/plugins/ConnectionRegistryImpl.java b/briar-core/src/org/briarproject/plugins/ConnectionRegistryImpl.java
index c898036b13..358f6da43a 100644
--- a/briar-core/src/org/briarproject/plugins/ConnectionRegistryImpl.java
+++ b/briar-core/src/org/briarproject/plugins/ConnectionRegistryImpl.java
@@ -27,13 +27,12 @@ class ConnectionRegistryImpl implements ConnectionRegistry {
 			Logger.getLogger(ConnectionRegistryImpl.class.getName());
 
 	private final EventBus eventBus;
-	// Locking: this
+	private final Lock synchLock = new ReentrantLock();
+
+	// The following are locking: synchLock
 	private final Map<TransportId, Map<ContactId, Integer>> connections;
-	// Locking: this
 	private final Map<ContactId, Integer> contactCounts;
 
-	private final Lock synchLock = new ReentrantLock();
-
 	@Inject
 	ConnectionRegistryImpl(EventBus eventBus) {
 		this.eventBus = eventBus;
diff --git a/briar-core/src/org/briarproject/reliability/Receiver.java b/briar-core/src/org/briarproject/reliability/Receiver.java
index 5d27e3ec4c..b45bc27484 100644
--- a/briar-core/src/org/briarproject/reliability/Receiver.java
+++ b/briar-core/src/org/briarproject/reliability/Receiver.java
@@ -21,15 +21,17 @@ class Receiver implements ReadHandler {
 
 	private final Clock clock;
 	private final Sender sender;
-	private final SortedSet<Data> dataFrames;
+	private final Lock windowLock = new ReentrantLock();
+	private final Condition dataFrameAvailable = windowLock.newCondition();
 
+	// The following are locking: windowLock
+	private final SortedSet<Data> dataFrames;
 	private int windowSize = MAX_WINDOW_SIZE;
+
 	private long finalSequenceNumber = Long.MAX_VALUE;
 	private long nextSequenceNumber = 1;
 
 	private volatile boolean valid = true;
-	private Lock synchLock = new ReentrantLock();
-	private Condition dataFrameAvailable = synchLock.newCondition();
 
 	Receiver(Clock clock, Sender sender) {
 		this.sender = sender;
@@ -38,7 +40,7 @@ class Receiver implements ReadHandler {
 	}
 
 	Data read() throws IOException, InterruptedException {
-		synchLock.lock();
+		windowLock.lock();
 		try {
 			long now = clock.currentTimeMillis(), end = now + READ_TIMEOUT;
 			while(now < end && valid) {
@@ -64,17 +66,17 @@ class Receiver implements ReadHandler {
 			if(valid) throw new IOException("Read timed out");
 			throw new IOException("Connection closed");
 		} finally {
-			synchLock.unlock();
+			windowLock.unlock();
 		}
 	}
 
 	void invalidate() {
 		valid = false;
-		synchLock.lock();
+		windowLock.lock();
 		try {
 			dataFrameAvailable.signalAll();
 		} finally {
-			synchLock.unlock();
+			windowLock.unlock();
 		}
 	}
 
@@ -95,7 +97,7 @@ class Receiver implements ReadHandler {
 	}
 
 	private void handleData(byte[] b) throws IOException {
-		synchLock.lock();
+		windowLock.lock();
 		try {
 			if(b.length < Data.MIN_LENGTH || b.length > Data.MAX_LENGTH) {
 				// Ignore data frame with invalid length
@@ -134,7 +136,7 @@ class Receiver implements ReadHandler {
 			// Acknowledge the data frame even if it's a duplicate
 			sender.sendAck(sequenceNumber, windowSize);
 		} finally {
-			synchLock.unlock();
+			windowLock.unlock();
 		}
 	}
 
diff --git a/briar-core/src/org/briarproject/reliability/Sender.java b/briar-core/src/org/briarproject/reliability/Sender.java
index 77a30efaa2..6cb5d6d8f4 100644
--- a/briar-core/src/org/briarproject/reliability/Sender.java
+++ b/briar-core/src/org/briarproject/reliability/Sender.java
@@ -26,8 +26,11 @@ class Sender {
 
 	private final Clock clock;
 	private final WriteHandler writeHandler;
-	private final LinkedList<Outstanding> outstanding;
+	private final Lock windowLock = new ReentrantLock();
+	private final Condition sendWindowAvailable = windowLock.newCondition();
 
+	// The following are locking: windowLock
+	private final LinkedList<Outstanding> outstanding;
 	private int outstandingBytes = 0;
 	private int windowSize = Data.MAX_PAYLOAD_LENGTH;
 	private int rtt = INITIAL_RTT, rttVar = INITIAL_RTT_VAR;
@@ -35,9 +38,6 @@ class Sender {
 	private long lastWindowUpdateOrProbe = Long.MAX_VALUE;
 	private boolean dataWaiting = false;
 
-	private Lock synchLock = new ReentrantLock();
-	private Condition sendWindowAvailable = synchLock.newCondition();
-
 	Sender(Clock clock, WriteHandler writeHandler) {
 		this.clock = clock;
 		this.writeHandler = writeHandler;
@@ -65,7 +65,7 @@ class Sender {
 		long sequenceNumber = a.getSequenceNumber();
 		long now = clock.currentTimeMillis();
 		Outstanding fastRetransmit = null;
-		synchLock.lock();
+		windowLock.lock();
 		try {
 			// Remove the acked data frame if it's outstanding
 			int foundIndex = -1;
@@ -105,7 +105,7 @@ class Sender {
 			if(windowSize > oldWindowSize || foundIndex != -1)
 				sendWindowAvailable.signalAll();
 		} finally {
-			synchLock.unlock();
+			windowLock.unlock();
 		}
 		// Fast retransmission
 		if(fastRetransmit != null)
@@ -116,7 +116,7 @@ class Sender {
 		long now = clock.currentTimeMillis();
 		List<Outstanding> retransmit = null;
 		boolean sendProbe = false;
-		synchLock.lock();
+		windowLock.lock();
 		try {
 			if(outstanding.isEmpty()) {
 				if(dataWaiting && now - lastWindowUpdateOrProbe > rto) {
@@ -147,7 +147,7 @@ class Sender {
 				}
 			}
 		} finally {
-			synchLock.unlock();
+			windowLock.unlock();
 		}
 		// Send a window probe if necessary
 		if(sendProbe) {
@@ -165,7 +165,7 @@ class Sender {
 
 	void write(Data d) throws IOException, InterruptedException {
 		int payloadLength = d.getPayloadLength();
-		synchLock.lock();
+		windowLock.lock();
 		try {
 			// Wait for space in the window
 			long now = clock.currentTimeMillis(), end = now + WRITE_TIMEOUT;
@@ -180,18 +180,18 @@ class Sender {
 			outstandingBytes += payloadLength;
 			dataWaiting = false;
 		} finally {
-			synchLock.unlock();
+			windowLock.unlock();
 		}
 		writeHandler.handleWrite(d.getBuffer());
 	}
 
 	void flush() throws IOException, InterruptedException {
-		synchLock.lock();
+		windowLock.lock();
 		try {
 			while(dataWaiting || !outstanding.isEmpty())
 				sendWindowAvailable.await();
 		} finally {
-			synchLock.unlock();
+			windowLock.unlock();
 		}
 	}
 
diff --git a/briar-core/src/org/briarproject/transport/KeyManagerImpl.java b/briar-core/src/org/briarproject/transport/KeyManagerImpl.java
index 9f4f301f02..257b1ef619 100644
--- a/briar-core/src/org/briarproject/transport/KeyManagerImpl.java
+++ b/briar-core/src/org/briarproject/transport/KeyManagerImpl.java
@@ -50,14 +50,14 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
 	private final TagRecogniser tagRecogniser;
 	private final Clock clock;
 	private final Timer timer;
+	private final Lock synchLock = new ReentrantLock();
 
+	// The following are locking: synchLock
 	private final Map<TransportId, Integer> maxLatencies;
 	private final Map<EndpointKey, TemporarySecret> oldSecrets;
 	private final Map<EndpointKey, TemporarySecret> currentSecrets;
 	private final Map<EndpointKey, TemporarySecret> newSecrets;
 
-	private final Lock synchLock = new ReentrantLock();
-
 	@Inject
 	KeyManagerImpl(CryptoComponent crypto, DatabaseComponent db,
 			EventBus eventBus, TagRecogniser tagRecogniser, Clock clock,
@@ -121,6 +121,7 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
 	}
 
 	// Assigns secrets to the appropriate maps and returns any dead secrets
+	// Locking: synchLock
 	private Collection<TemporarySecret> assignSecretsToMaps(long now,
 			Collection<TemporarySecret> secrets) {
 		Collection<TemporarySecret> dead = new ArrayList<TemporarySecret>();
@@ -153,6 +154,7 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
 	}
 
 	// Replaces the given secrets and returns any secrets created
+	// Locking: synchLock
 	private Collection<TemporarySecret> replaceDeadSecrets(long now,
 			Collection<TemporarySecret> dead) {
 		// If there are several dead secrets for an endpoint, use the newest
@@ -253,7 +255,7 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
 		}
 	}
 
-	public synchronized void endpointAdded(Endpoint ep, int maxLatency,
+	public void endpointAdded(Endpoint ep, int maxLatency,
 			byte[] initialSecret) {
 		synchLock.lock();
 		try {
@@ -345,12 +347,14 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
 		}
 	}
 
+	// Locking: synchLock
 	private void removeSecrets(ContactId c, Map<?, TemporarySecret> m) {
 		Iterator<TemporarySecret> it = m.values().iterator();
 		while(it.hasNext())
 			if(it.next().getContactId().equals(c)) it.remove();
 	}
 
+	// Locking: synchLock
 	private void removeSecrets(TransportId t, Map<?, TemporarySecret> m) {
 		Iterator<TemporarySecret> it = m.values().iterator();
 		while(it.hasNext())
diff --git a/briar-core/src/org/briarproject/transport/KeyManagerImpl.java.orig b/briar-core/src/org/briarproject/transport/KeyManagerImpl.java.orig
deleted file mode 100644
index 88863dadaa..0000000000
--- a/briar-core/src/org/briarproject/transport/KeyManagerImpl.java.orig
+++ /dev/null
@@ -1,546 +0,0 @@
-package org.briarproject.transport;
-
-import static java.util.logging.Level.WARNING;
-import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TimerTask;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.logging.Logger;
-
-import javax.inject.Inject;
-
-import org.briarproject.api.ContactId;
-import org.briarproject.api.TransportId;
-import org.briarproject.api.crypto.CryptoComponent;
-import org.briarproject.api.crypto.KeyManager;
-import org.briarproject.api.db.DatabaseComponent;
-import org.briarproject.api.db.DbException;
-import org.briarproject.api.event.ContactRemovedEvent;
-import org.briarproject.api.event.Event;
-import org.briarproject.api.event.EventBus;
-import org.briarproject.api.event.EventListener;
-import org.briarproject.api.event.TransportAddedEvent;
-import org.briarproject.api.event.TransportRemovedEvent;
-import org.briarproject.api.system.Clock;
-import org.briarproject.api.system.Timer;
-import org.briarproject.api.transport.Endpoint;
-import org.briarproject.api.transport.StreamContext;
-import org.briarproject.api.transport.TagRecogniser;
-import org.briarproject.api.transport.TemporarySecret;
-
-// FIXME: Don't make alien calls with a lock held
-class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
-
-	private static final int MS_BETWEEN_CHECKS = 60 * 1000;
-
-	private static final Logger LOG =
-			Logger.getLogger(KeyManagerImpl.class.getName());
-
-	private final CryptoComponent crypto;
-	private final DatabaseComponent db;
-	private final EventBus eventBus;
-	private final TagRecogniser tagRecogniser;
-	private final Clock clock;
-	private final Timer timer;
-
-<<<<<<< HEAD
-	private final Map<TransportId, Long> maxLatencies;
-=======
-	// All of the following are locking: this
-	private final Map<TransportId, Integer> maxLatencies;
->>>>>>> theSource
-	private final Map<EndpointKey, TemporarySecret> oldSecrets;
-	private final Map<EndpointKey, TemporarySecret> currentSecrets;
-	private final Map<EndpointKey, TemporarySecret> newSecrets;
-
-	private final Lock synchLock = new ReentrantLock();
-
-	@Inject
-	KeyManagerImpl(CryptoComponent crypto, DatabaseComponent db,
-			EventBus eventBus, TagRecogniser tagRecogniser, Clock clock,
-			Timer timer) {
-		this.crypto = crypto;
-		this.db = db;
-		this.eventBus = eventBus;
-		this.tagRecogniser = tagRecogniser;
-		this.clock = clock;
-		this.timer = timer;
-		maxLatencies = new HashMap<TransportId, Integer>();
-		oldSecrets = new HashMap<EndpointKey, TemporarySecret>();
-		currentSecrets = new HashMap<EndpointKey, TemporarySecret>();
-		newSecrets = new HashMap<EndpointKey, TemporarySecret>();
-	}
-
-	public boolean start() {
-		synchLock.lock();
-		try {
-			eventBus.addListener(this);
-			// Load the temporary secrets and transport latencies from the database
-			Collection<TemporarySecret> secrets;
-			try {
-				secrets = db.getSecrets();
-				maxLatencies.putAll(db.getTransportLatencies());
-			} catch(DbException e) {
-				if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-				return false;
-			}
-			// Work out what phase of its lifecycle each secret is in
-			long now = clock.currentTimeMillis();
-			Collection<TemporarySecret> dead = assignSecretsToMaps(now, secrets);
-			// Replace any dead secrets
-			Collection<TemporarySecret> created = replaceDeadSecrets(now, dead);
-			if(!created.isEmpty()) {
-				// Store any secrets that have been created, removing any dead ones
-				try {
-					db.addSecrets(created);
-				} catch(DbException e) {
-					if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-					return false;
-				}
-			}
-			// Pass the old, current and new secrets to the recogniser
-			for(TemporarySecret s : oldSecrets.values())
-				tagRecogniser.addSecret(s);
-			for(TemporarySecret s : currentSecrets.values())
-				tagRecogniser.addSecret(s);
-			for(TemporarySecret s : newSecrets.values())
-				tagRecogniser.addSecret(s);
-			// Schedule periodic key rotation
-			timer.scheduleAtFixedRate(this, MS_BETWEEN_CHECKS, MS_BETWEEN_CHECKS);
-			return true;
-		}
-		finally{
-			synchLock.unlock();
-		}
-	}
-
-	// Assigns secrets to the appropriate maps and returns any dead secrets
-	private Collection<TemporarySecret> assignSecretsToMaps(long now,
-			Collection<TemporarySecret> secrets) {
-		Collection<TemporarySecret> dead = new ArrayList<TemporarySecret>();
-		for(TemporarySecret s : secrets) {
-			// Discard the secret if the transport has been removed
-			Integer maxLatency = maxLatencies.get(s.getTransportId());
-			if(maxLatency == null) {
-				LOG.info("Discarding obsolete secret");
-				continue;
-			}
-			long rotation = maxLatency + MAX_CLOCK_DIFFERENCE;
-			long creationTime = s.getEpoch() + rotation * (s.getPeriod() - 2);
-			long activationTime = creationTime + rotation;
-			long deactivationTime = activationTime + rotation;
-			long destructionTime = deactivationTime + rotation;
-			if(now >= destructionTime) {
-				dead.add(s);
-			} else if(now >= deactivationTime) {
-				oldSecrets.put(new EndpointKey(s), s);
-			} else if(now >= activationTime) {
-				currentSecrets.put(new EndpointKey(s), s);
-			} else if(now >= creationTime) {
-				newSecrets.put(new EndpointKey(s), s);
-			} else {
-				// FIXME: Work out what to do here
-				throw new Error("Clock has moved backwards");
-			}
-		}
-		return dead;
-	}
-
-<<<<<<< HEAD
-	// Replaces and erases the given secrets and returns any secrets created
-=======
-	// Replaces the given secrets and returns any secrets created
-	// Locking: this
->>>>>>> theSource
-	private Collection<TemporarySecret> replaceDeadSecrets(long now,
-			Collection<TemporarySecret> dead) {
-		// If there are several dead secrets for an endpoint, use the newest
-		Map<EndpointKey, TemporarySecret> newest =
-				new HashMap<EndpointKey, TemporarySecret>();
-		for(TemporarySecret s : dead) {
-			EndpointKey k = new EndpointKey(s);
-			TemporarySecret exists = newest.get(k);
-			if(exists == null) {
-				// There's no other secret for this endpoint
-				newest.put(k, s);
-			} else if(exists.getPeriod() < s.getPeriod()) {
-				// There's an older secret - use this one instead
-				newest.put(k, s);
-			} else {
-				// There's a newer secret - keep using it
-			}
-		}
-		Collection<TemporarySecret> created = new ArrayList<TemporarySecret>();
-		for(Entry<EndpointKey, TemporarySecret> e : newest.entrySet()) {
-			TemporarySecret s = e.getValue();
-			Integer maxLatency = maxLatencies.get(s.getTransportId());
-			if(maxLatency == null) throw new IllegalStateException();
-			// Work out which rotation period we're in
-			long elapsed = now - s.getEpoch();
-			long rotation = maxLatency + MAX_CLOCK_DIFFERENCE;
-			long period = (elapsed / rotation) + 1;
-			if(period < 1) throw new IllegalStateException();
-			if(period - s.getPeriod() < 2)
-				throw new IllegalStateException();
-			// Derive the old, current and new secrets
-			byte[] b1 = s.getSecret();
-			for(long p = s.getPeriod() + 1; p < period; p++)
-				b1 = crypto.deriveNextSecret(b1, p);
-			byte[] b2 = crypto.deriveNextSecret(b1, period);
-			byte[] b3 = crypto.deriveNextSecret(b2, period + 1);
-			// Add the secrets to their respective maps if not already present
-			EndpointKey k = e.getKey();
-			if(!oldSecrets.containsKey(k)) {
-				TemporarySecret s1 = new TemporarySecret(s, period - 1, b1);
-				oldSecrets.put(k, s1);
-				created.add(s1);
-			}
-			if(!currentSecrets.containsKey(k)) {
-				TemporarySecret s2 = new TemporarySecret(s, period, b2);
-				currentSecrets.put(k, s2);
-				created.add(s2);
-			}
-			if(!newSecrets.containsKey(k)) {
-				TemporarySecret s3 = new TemporarySecret(s, period + 1, b3);
-				newSecrets.put(k, s3);
-				created.add(s3);
-			}
-		}
-		return created;
-	}
-
-<<<<<<< HEAD
-	public boolean stop() {
-		synchLock.lock();
-		try{
-			eventBus.removeListener(this);
-			timer.cancel();
-			tagRecogniser.removeSecrets();
-			maxLatencies.clear();
-			removeAndEraseSecrets(oldSecrets);
-			removeAndEraseSecrets(currentSecrets);
-			removeAndEraseSecrets(newSecrets);
-			return true;
-		}
-		finally{
-			synchLock.unlock();
-		}
-	}
-
-	private void removeAndEraseSecrets(Map<?, TemporarySecret> m) {
-		for(TemporarySecret s : m.values()) ByteUtils.erase(s.getSecret());
-		m.clear();
-	}
-
-	public StreamContext getStreamContext(ContactId c,
-=======
-	public synchronized boolean stop() {
-		eventBus.removeListener(this);
-		timer.cancel();
-		tagRecogniser.removeSecrets();
-		maxLatencies.clear();
-		oldSecrets.clear();
-		currentSecrets.clear();
-		newSecrets.clear();
-		return true;
-	}
-
-	public synchronized StreamContext getStreamContext(ContactId c,
->>>>>>> theSource
-			TransportId t) {
-		synchLock.lock();
-		try{
-			TemporarySecret s = currentSecrets.get(new EndpointKey(c, t));
-			if(s == null) {
-				LOG.info("No secret for endpoint");
-				return null;
-			}
-			long streamNumber;
-			try {
-				streamNumber = db.incrementStreamCounter(c, t, s.getPeriod());
-				if(streamNumber == -1) {
-					LOG.info("No counter for period");
-					return null;
-				}
-			} catch(DbException e) {
-				if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-				return null;
-			}
-			// Clone the secret - the original will be erased
-			byte[] secret = s.getSecret().clone();
-			return new StreamContext(c, t, secret, streamNumber, s.getAlice());
-		}
-		finally{
-			synchLock.unlock();
-		}
-<<<<<<< HEAD
-	}
-
-	public void endpointAdded(Endpoint ep, long maxLatency,
-			byte[] initialSecret) {
-		synchLock.lock();
-		try{
-			maxLatencies.put(ep.getTransportId(), maxLatency);
-			// Work out which rotation period we're in
-			long elapsed = clock.currentTimeMillis() - ep.getEpoch();
-			long rotation = maxLatency + MAX_CLOCK_DIFFERENCE;
-			long period = (elapsed / rotation) + 1;
-			if(period < 1) throw new IllegalStateException();
-			// Derive the old, current and new secrets
-			byte[] b1 = initialSecret;
-			for(long p = 0; p < period; p++) {
-				byte[] temp = crypto.deriveNextSecret(b1, p);
-				ByteUtils.erase(b1);
-				b1 = temp;
-			}
-			byte[] b2 = crypto.deriveNextSecret(b1, period);
-			byte[] b3 = crypto.deriveNextSecret(b2, period + 1);
-			TemporarySecret s1 = new TemporarySecret(ep, period - 1, b1);
-			TemporarySecret s2 = new TemporarySecret(ep, period, b2);
-			TemporarySecret s3 = new TemporarySecret(ep, period + 1, b3);
-			// Add the incoming secrets to their respective maps
-			EndpointKey k = new EndpointKey(ep);
-			oldSecrets.put(k, s1);
-			currentSecrets.put(k, s2);
-			newSecrets.put(k, s3);
-			// Store the new secrets
-			try {
-				db.addSecrets(Arrays.asList(s1, s2, s3));
-			} catch(DbException e) {
-				if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-				return;
-			}
-			// Pass the new secrets to the recogniser
-			tagRecogniser.addSecret(s1);
-			tagRecogniser.addSecret(s2);
-			tagRecogniser.addSecret(s3);
-		}
-		finally{
-			synchLock.unlock();
-=======
-		byte[] secret = s.getSecret();
-		return new StreamContext(c, t, secret, streamNumber, s.getAlice());
-	}
-
-	public synchronized void endpointAdded(Endpoint ep, int maxLatency,
-			byte[] initialSecret) {
-		maxLatencies.put(ep.getTransportId(), maxLatency);
-		// Work out which rotation period we're in
-		long elapsed = clock.currentTimeMillis() - ep.getEpoch();
-		long rotation = maxLatency + MAX_CLOCK_DIFFERENCE;
-		long period = (elapsed / rotation) + 1;
-		if(period < 1) throw new IllegalStateException();
-		// Derive the old, current and new secrets
-		byte[] b1 = initialSecret;
-		for(long p = 0; p < period; p++)
-			b1 = crypto.deriveNextSecret(b1, p);
-		byte[] b2 = crypto.deriveNextSecret(b1, period);
-		byte[] b3 = crypto.deriveNextSecret(b2, period + 1);
-		TemporarySecret s1 = new TemporarySecret(ep, period - 1, b1);
-		TemporarySecret s2 = new TemporarySecret(ep, period, b2);
-		TemporarySecret s3 = new TemporarySecret(ep, period + 1, b3);
-		// Add the incoming secrets to their respective maps
-		EndpointKey k = new EndpointKey(ep);
-		oldSecrets.put(k, s1);
-		currentSecrets.put(k, s2);
-		newSecrets.put(k, s3);
-		// Store the new secrets
-		try {
-			db.addSecrets(Arrays.asList(s1, s2, s3));
-		} catch(DbException e) {
-			if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-			return;
->>>>>>> theSource
-		}
-	}
-
-	@Override
-	public void run() {
-		synchLock.lock();
-		try{
-		// Rebuild the maps because we may be running a whole period late
-			Collection<TemporarySecret> secrets = new ArrayList<TemporarySecret>();
-			secrets.addAll(oldSecrets.values());
-			secrets.addAll(currentSecrets.values());
-			secrets.addAll(newSecrets.values());
-			oldSecrets.clear();
-			currentSecrets.clear();
-			newSecrets.clear();
-			// Work out what phase of its lifecycle each secret is in
-			long now = clock.currentTimeMillis();
-			Collection<TemporarySecret> dead = assignSecretsToMaps(now, secrets);
-			// Remove any dead secrets from the recogniser
-			for(TemporarySecret s : dead) {
-				ContactId c = s.getContactId();
-				TransportId t = s.getTransportId();
-				long period = s.getPeriod();
-				tagRecogniser.removeSecret(c, t, period);
-			}
-			// Replace any dead secrets
-			Collection<TemporarySecret> created = replaceDeadSecrets(now, dead);
-			if(!created.isEmpty()) {
-				// Store any secrets that have been created
-				try {
-					db.addSecrets(created);
-				} catch(DbException e) {
-					if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-				}
-				// Pass any secrets that have been created to the recogniser
-				for(TemporarySecret s : created) tagRecogniser.addSecret(s);
-			}
-		}
-		finally{
-			synchLock.unlock();
-		}
-	}
-
-	public void eventOccurred(Event e) {
-		if(e instanceof ContactRemovedEvent) {
-			ContactRemovedEvent c = (ContactRemovedEvent) e;
-			timer.schedule(new ContactRemovedTask(c), 0);
-		} else if(e instanceof TransportAddedEvent) {
-			TransportAddedEvent t = (TransportAddedEvent) e;
-			timer.schedule(new TransportAddedTask(t), 0);
-		} else if(e instanceof TransportRemovedEvent) {
-			TransportRemovedEvent t = (TransportRemovedEvent) e;
-			timer.schedule(new TransportRemovedTask(t), 0);
-		}
-	}
-
-<<<<<<< HEAD
-	private void removeAndEraseSecrets(ContactId c, Map<?, TemporarySecret> m) {
-=======
-	// Locking: this
-	private void removeSecrets(ContactId c, Map<?, TemporarySecret> m) {
->>>>>>> theSource
-		Iterator<TemporarySecret> it = m.values().iterator();
-		while(it.hasNext())
-			if(it.next().getContactId().equals(c)) it.remove();
-	}
-
-<<<<<<< HEAD
-	private void removeAndEraseSecrets(TransportId t,
-			Map<?, TemporarySecret> m) {
-=======
-	// Locking: this
-	private void removeSecrets(TransportId t, Map<?, TemporarySecret> m) {
->>>>>>> theSource
-		Iterator<TemporarySecret> it = m.values().iterator();
-		while(it.hasNext())
-			if(it.next().getTransportId().equals(t)) it.remove();
-	}
-
-	private static class EndpointKey {
-
-		private final ContactId contactId;
-		private final TransportId transportId;
-
-		private EndpointKey(ContactId contactId, TransportId transportId) {
-			this.contactId = contactId;
-			this.transportId = transportId;
-		}
-
-		private EndpointKey(Endpoint ep) {
-			this(ep.getContactId(), ep.getTransportId());
-		}
-
-		@Override
-		public int hashCode() {
-			return contactId.hashCode() ^ transportId.hashCode();
-		}
-
-		@Override
-		public boolean equals(Object o) {
-			if(o instanceof EndpointKey) {
-				EndpointKey k = (EndpointKey) o;
-				return contactId.equals(k.contactId) &&
-						transportId.equals(k.transportId);
-			}
-			return false;
-		}
-	}
-
-	private class ContactRemovedTask extends TimerTask {
-
-		private final ContactRemovedEvent event;
-
-		private ContactRemovedTask(ContactRemovedEvent event) {
-			this.event = event;
-		}
-
-		@Override
-		public void run() {
-			ContactId c = event.getContactId();
-			tagRecogniser.removeSecrets(c);
-<<<<<<< HEAD
-			synchLock.lock();
-			try {
-				removeAndEraseSecrets(c, oldSecrets);
-				removeAndEraseSecrets(c, currentSecrets);
-				removeAndEraseSecrets(c, newSecrets);
-=======
-			synchronized(KeyManagerImpl.this) {
-				removeSecrets(c, oldSecrets);
-				removeSecrets(c, currentSecrets);
-				removeSecrets(c, newSecrets);
->>>>>>> theSource
-			}
-			finally{
-				synchLock.unlock();
-			}
-		}
-	}
-
-	private class TransportAddedTask extends TimerTask {
-
-		private final TransportAddedEvent event;
-
-		private TransportAddedTask(TransportAddedEvent event) {
-			this.event = event;
-		}
-
-		@Override
-		public void run() {
-			synchLock.lock();
-			try {
-				maxLatencies.put(event.getTransportId(), event.getMaxLatency());
-			}
-			finally{
-				synchLock.unlock();
-			}
-		}
-	}
-
-	private class TransportRemovedTask extends TimerTask {
-
-		private TransportRemovedEvent event;
-
-		private TransportRemovedTask(TransportRemovedEvent event) {
-			this.event = event;
-		}
-
-		@Override
-		public void run() {
-			TransportId t = event.getTransportId();
-			tagRecogniser.removeSecrets(t);
-			synchLock.lock();
-			try {
-				maxLatencies.remove(t);
-				removeSecrets(t, oldSecrets);
-				removeSecrets(t, currentSecrets);
-				removeSecrets(t, newSecrets);
-			}
-			finally{
-				synchLock.unlock();
-			}
-		}
-	}
-}
diff --git a/briar-core/src/org/briarproject/transport/TagRecogniserImpl.java b/briar-core/src/org/briarproject/transport/TagRecogniserImpl.java
index ba3aa9bf40..ea4e5567b5 100644
--- a/briar-core/src/org/briarproject/transport/TagRecogniserImpl.java
+++ b/briar-core/src/org/briarproject/transport/TagRecogniserImpl.java
@@ -20,11 +20,10 @@ class TagRecogniserImpl implements TagRecogniser {
 
 	private final CryptoComponent crypto;
 	private final DatabaseComponent db;
-
-	private final Map<TransportId, TransportTagRecogniser> recognisers;
-
 	private final Lock synchLock = new ReentrantLock();
 
+	// Locking: synchLock
+	private final Map<TransportId, TransportTagRecogniser> recognisers;
 
 	@Inject
 	TagRecogniserImpl(CryptoComponent crypto, DatabaseComponent db) {
diff --git a/briar-core/src/org/briarproject/transport/TransportTagRecogniser.java b/briar-core/src/org/briarproject/transport/TransportTagRecogniser.java
index 71cd559254..0898120440 100644
--- a/briar-core/src/org/briarproject/transport/TransportTagRecogniser.java
+++ b/briar-core/src/org/briarproject/transport/TransportTagRecogniser.java
@@ -29,11 +29,12 @@ class TransportTagRecogniser {
 	private final CryptoComponent crypto;
 	private final DatabaseComponent db;
 	private final TransportId transportId;
+	private final Lock synchLock = new ReentrantLock();
+
+	// The following are locking: synchLock
 	private final Map<Bytes, TagContext> tagMap;
 	private final Map<RemovalKey, RemovalContext> removalMap;
 
-	private final Lock synchLock = new ReentrantLock();
-
 	TransportTagRecogniser(CryptoComponent crypto, DatabaseComponent db,
 			TransportId transportId) {
 		this.crypto = crypto;
@@ -112,6 +113,7 @@ class TransportTagRecogniser {
 		}
 	}
 
+	// Locking: synchLock
 	private void removeSecret(RemovalContext r) {
 		// Remove the expected tags
 		SecretKey key = crypto.deriveTagKey(r.secret, !r.alice);
diff --git a/briar-core/src/org/briarproject/transport/TransportTagRecogniser.java.orig b/briar-core/src/org/briarproject/transport/TransportTagRecogniser.java.orig
deleted file mode 100644
index 0e46da82ef..0000000000
--- a/briar-core/src/org/briarproject/transport/TransportTagRecogniser.java.orig
+++ /dev/null
@@ -1,235 +0,0 @@
-package org.briarproject.transport;
-
-import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.briarproject.api.Bytes;
-import org.briarproject.api.ContactId;
-import org.briarproject.api.TransportId;
-import org.briarproject.api.crypto.CryptoComponent;
-import org.briarproject.api.crypto.SecretKey;
-import org.briarproject.api.db.DatabaseComponent;
-import org.briarproject.api.db.DbException;
-import org.briarproject.api.transport.StreamContext;
-import org.briarproject.api.transport.TemporarySecret;
-
-// FIXME: Don't make alien calls with a lock held
-/**
- * A {@link org.briarproject.api.transport.TagRecogniser TagRecogniser} for a
- * specific transport.
- */
-class TransportTagRecogniser {
-
-	private final CryptoComponent crypto;
-	private final DatabaseComponent db;
-	private final TransportId transportId;
-	private final Map<Bytes, TagContext> tagMap;
-	private final Map<RemovalKey, RemovalContext> removalMap;
-
-	private final Lock synchLock = new ReentrantLock();
-
-	TransportTagRecogniser(CryptoComponent crypto, DatabaseComponent db,
-			TransportId transportId) {
-		this.crypto = crypto;
-		this.db = db;
-		this.transportId = transportId;
-		tagMap = new HashMap<Bytes, TagContext>();
-		removalMap = new HashMap<RemovalKey, RemovalContext>();
-	}
-
-	StreamContext recogniseTag(byte[] tag) throws DbException {
-		synchLock.lock();
-		try{
-			TagContext t = tagMap.remove(new Bytes(tag));
-			if(t == null) return null; // The tag was not expected
-			// Update the reordering window and the expected tags
-			SecretKey key = crypto.deriveTagKey(t.secret, !t.alice);
-			for(long streamNumber : t.window.setSeen(t.streamNumber)) {
-				byte[] tag1 = new byte[TAG_LENGTH];
-				crypto.encodeTag(tag1, key, streamNumber);
-				if(streamNumber < t.streamNumber) {
-					TagContext removed = tagMap.remove(new Bytes(tag1));
-					assert removed != null;
-				} else {
-					TagContext added = new TagContext(t, streamNumber);
-					TagContext duplicate = tagMap.put(new Bytes(tag1), added);
-					assert duplicate == null;
-				}
-			}
-			key.erase();
-			// Store the updated reordering window in the DB
-			db.setReorderingWindow(t.contactId, transportId, t.period,
-					t.window.getCentre(), t.window.getBitmap());
-			// Clone the secret - the key manager will erase the original
-			byte[] secret = t.secret.clone();
-			return new StreamContext(t.contactId, transportId, secret,
-					t.streamNumber, t.alice);
-		}
-		finally{
-			synchLock.unlock();
-		}
-<<<<<<< HEAD
-=======
-		// Store the updated reordering window in the DB
-		db.setReorderingWindow(t.contactId, transportId, t.period,
-				t.window.getCentre(), t.window.getBitmap());
-		return new StreamContext(t.contactId, transportId, t.secret,
-				t.streamNumber, t.alice);
->>>>>>> theSource
-	}
-
-	void addSecret(TemporarySecret s) {
-		synchLock.lock();
-		try{
-			ContactId contactId = s.getContactId();
-			boolean alice = s.getAlice();
-			long period = s.getPeriod();
-			byte[] secret = s.getSecret();
-			long centre = s.getWindowCentre();
-			byte[] bitmap = s.getWindowBitmap();
-			// Create the reordering window and the expected tags
-			SecretKey key = crypto.deriveTagKey(secret, !alice);
-			ReorderingWindow window = new ReorderingWindow(centre, bitmap);
-			for(long streamNumber : window.getUnseen()) {
-				byte[] tag = new byte[TAG_LENGTH];
-				crypto.encodeTag(tag, key, streamNumber);
-				TagContext added = new TagContext(contactId, alice, period,
-						secret, window, streamNumber);
-				TagContext duplicate = tagMap.put(new Bytes(tag), added);
-				assert duplicate == null;
-			}
-			key.erase();
-			// Create a removal context to remove the window and the tags later
-			RemovalContext r = new RemovalContext(window, secret, alice);
-			removalMap.put(new RemovalKey(contactId, period), r);
-		}
-		finally{
-			synchLock.unlock();
-		}
-<<<<<<< HEAD
-=======
-		// Create a removal context to remove the window and the tags later
-		RemovalContext r = new RemovalContext(window, secret, alice);
-		removalMap.put(new RemovalKey(contactId, period), r);
->>>>>>> theSource
-	}
-
-	void removeSecret(ContactId contactId, long period) {
-		synchLock.lock();
-		try{
-			RemovalKey k = new RemovalKey(contactId, period);
-			RemovalContext removed = removalMap.remove(k);
-			if(removed == null) throw new IllegalArgumentException();
-			removeSecret(removed);
-		}
-		finally{
-			synchLock.unlock();
-		}
-	}
-
-	private void removeSecret(RemovalContext r) {
-		// Remove the expected tags
-		SecretKey key = crypto.deriveTagKey(r.secret, !r.alice);
-		byte[] tag = new byte[TAG_LENGTH];
-		for(long streamNumber : r.window.getUnseen()) {
-			crypto.encodeTag(tag, key, streamNumber);
-			TagContext removed = tagMap.remove(new Bytes(tag));
-			assert removed != null;
-		}
-	}
-
-	void removeSecrets(ContactId c) {
-		synchLock.lock();
-		try{
-			Collection<RemovalKey> keysToRemove = new ArrayList<RemovalKey>();
-			for(RemovalKey k : removalMap.keySet())
-				if(k.contactId.equals(c)) keysToRemove.add(k);
-			for(RemovalKey k : keysToRemove) removeSecret(k.contactId, k.period);
-		}
-		finally{
-			synchLock.unlock();
-		}
-	}
-
-	void removeSecrets() {
-		synchLock.lock();
-		try{
-			for(RemovalContext r : removalMap.values()) removeSecret(r);
-			assert tagMap.isEmpty();
-			removalMap.clear();
-		}
-		finally{
-			synchLock.unlock();
-		}
-	}
-
-	private static class TagContext {
-
-		private final ContactId contactId;
-		private final boolean alice;
-		private final long period;
-		private final byte[] secret;
-		private final ReorderingWindow window;
-		private final long streamNumber;
-
-		private TagContext(ContactId contactId, boolean alice, long period,
-				byte[] secret, ReorderingWindow window, long streamNumber) {
-			this.contactId = contactId;
-			this.alice = alice;
-			this.period = period;
-			this.secret = secret;
-			this.window = window;
-			this.streamNumber = streamNumber;
-		}
-
-		private TagContext(TagContext t, long streamNumber) {
-			this(t.contactId, t.alice, t.period, t.secret, t.window,
-					streamNumber);
-		}
-	}
-
-	private static class RemovalKey {
-
-		private final ContactId contactId;
-		private final long period;
-
-		private RemovalKey(ContactId contactId, long period) {
-			this.contactId = contactId;
-			this.period = period;
-		}
-
-		@Override
-		public int hashCode() {
-			return contactId.hashCode() ^ (int) (period ^ (period >>> 32));
-		}
-
-		@Override
-		public boolean equals(Object o) {
-			if(o instanceof RemovalKey) {
-				RemovalKey k = (RemovalKey) o;
-				return contactId.equals(k.contactId) && period == k.period;
-			}
-			return false;
-		}
-	}
-
-	private static class RemovalContext {
-
-		private final ReorderingWindow window;
-		private final byte[] secret;
-		private final boolean alice;
-
-		private RemovalContext(ReorderingWindow window, byte[] secret,
-				boolean alice) {
-			this.window = window;
-			this.secret = secret;
-			this.alice = alice;
-		}
-	}
-}
diff --git a/briar-desktop/src/org/briarproject/lifecycle/WindowsShutdownManagerImpl.java b/briar-desktop/src/org/briarproject/lifecycle/WindowsShutdownManagerImpl.java
index 7fd8e77cfd..3585e557f2 100644
--- a/briar-desktop/src/org/briarproject/lifecycle/WindowsShutdownManagerImpl.java
+++ b/briar-desktop/src/org/briarproject/lifecycle/WindowsShutdownManagerImpl.java
@@ -38,11 +38,9 @@ class WindowsShutdownManagerImpl extends ShutdownManagerImpl {
 	private static final int WS_MINIMIZE = 0x20000000;
 
 	private final Map<String, Object> options;
-
-	private boolean initialised = false;
-
 	private final Lock synchLock = new ReentrantLock();
 
+	private boolean initialised = false; // Locking: synchLock
 
 	WindowsShutdownManagerImpl() {
 		// Use the Unicode versions of Win32 API calls
@@ -68,6 +66,7 @@ class WindowsShutdownManagerImpl extends ShutdownManagerImpl {
 		return new StartOnce(r);
 	}
 
+	// Locking: synchLock
 	private void initialise() {
 		if(OsUtils.isWindows()) {
 			new EventLoop().start();
diff --git a/briar-desktop/src/org/briarproject/plugins/file/PollingRemovableDriveMonitor.java b/briar-desktop/src/org/briarproject/plugins/file/PollingRemovableDriveMonitor.java
index 33b485f5d8..c86b657d7e 100644
--- a/briar-desktop/src/org/briarproject/plugins/file/PollingRemovableDriveMonitor.java
+++ b/briar-desktop/src/org/briarproject/plugins/file/PollingRemovableDriveMonitor.java
@@ -20,12 +20,11 @@ class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
 	private final RemovableDriveFinder finder;
 	private final int pollingInterval;
 
-	private volatile boolean running = false;
-	private volatile Callback callback = null;
-
 	private final Lock pollingLock = new ReentrantLock();
 	private final Condition stopPolling = pollingLock.newCondition();
 
+	private volatile boolean running = false;
+	private volatile Callback callback = null;
 
 	public PollingRemovableDriveMonitor(Executor ioExecutor,
 			RemovableDriveFinder finder, int pollingInterval) {
diff --git a/briar-desktop/src/org/briarproject/plugins/file/PollingRemovableDriveMonitor.java.orig b/briar-desktop/src/org/briarproject/plugins/file/PollingRemovableDriveMonitor.java.orig
deleted file mode 100644
index d27f65a0a1..0000000000
--- a/briar-desktop/src/org/briarproject/plugins/file/PollingRemovableDriveMonitor.java.orig
+++ /dev/null
@@ -1,83 +0,0 @@
-package org.briarproject.plugins.file;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.logging.Logger;
-
-class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
-
-	private static final Logger LOG =
-			Logger.getLogger(PollingRemovableDriveMonitor.class.getName());
-
-	private final Executor ioExecutor;
-	private final RemovableDriveFinder finder;
-<<<<<<< HEAD
-	private final long pollingInterval;
-=======
-	private final int pollingInterval;
-	private final Object pollingLock = new Object();
->>>>>>> theSource
-
-	private volatile boolean running = false;
-	private volatile Callback callback = null;
-
-	private final Lock pollingLock = new ReentrantLock();
-	private final Condition stopPolling = pollingLock.newCondition();
-
-
-	public PollingRemovableDriveMonitor(Executor ioExecutor,
-			RemovableDriveFinder finder, int pollingInterval) {
-		this.ioExecutor = ioExecutor;
-		this.finder = finder;
-		this.pollingInterval = pollingInterval;
-	}
-
-	public void start(Callback callback) throws IOException {
-		this.callback = callback;
-		running = true;
-		ioExecutor.execute(this);
-	}
-
-	public void stop() throws IOException {
-		running = false;
-		pollingLock.lock();
-		try {
-			stopPolling.signalAll();
-		} 
-		finally {
-			pollingLock.unlock();
-		}
-	}
-
-	public void run() {
-		try {
-			Collection<File> drives = finder.findRemovableDrives();
-			while(running) {
-				pollingLock.lock();
-				try {
-					stopPolling.await(pollingInterval, TimeUnit.MILLISECONDS);
-				} 
-				finally{
-					pollingLock.unlock();
-				}
-				if(!running) return;
-				Collection<File> newDrives = finder.findRemovableDrives();
-				for(File f : newDrives) {
-					if(!drives.contains(f)) callback.driveInserted(f);
-				}
-				drives = newDrives;
-			}
-		} catch(InterruptedException e) {
-			LOG.warning("Interrupted while waiting to poll");
-			Thread.currentThread().interrupt();
-		} catch(IOException e) {
-			callback.exceptionThrown(e);
-		}
-	}
-}
diff --git a/briar-desktop/src/org/briarproject/plugins/file/UnixRemovableDriveMonitor.java b/briar-desktop/src/org/briarproject/plugins/file/UnixRemovableDriveMonitor.java
index 8a788ddc61..bc2ca3fd9f 100644
--- a/briar-desktop/src/org/briarproject/plugins/file/UnixRemovableDriveMonitor.java
+++ b/briar-desktop/src/org/briarproject/plugins/file/UnixRemovableDriveMonitor.java
@@ -13,20 +13,22 @@ import net.contentobjects.jnotify.JNotifyListener;
 abstract class UnixRemovableDriveMonitor implements RemovableDriveMonitor,
 JNotifyListener {
 
+	//TODO: rationalise this in a further refactor
+	private static final Lock staticSynchLock = new ReentrantLock();
+
+	// The following are locking: staticSynchLock
 	private static boolean triedLoad = false;
 	private static Throwable loadError = null;
 
-	private final List<Integer> watches = new ArrayList<Integer>();
+	private final Lock synchLock = new ReentrantLock();
 
+	// The following are locking: synchLock
+	private final List<Integer> watches = new ArrayList<Integer>();
 	private boolean started = false;
 	private Callback callback = null;
 
 	protected abstract String[] getPathsToWatch();
 
-	//TODO: rationalise this in a further refactor
-	private final Lock synchLock = new ReentrantLock();
-	private static final Lock staticSynchLock = new ReentrantLock();
-
 	private static Throwable tryLoad() {
 		try {
 			Class.forName("net.contentobjects.jnotify.JNotify");
diff --git a/briar-desktop/src/org/briarproject/plugins/modem/CountryCodes.java b/briar-desktop/src/org/briarproject/plugins/modem/CountryCodes.java
index 7975c78580..b4fb65a00c 100644
--- a/briar-desktop/src/org/briarproject/plugins/modem/CountryCodes.java
+++ b/briar-desktop/src/org/briarproject/plugins/modem/CountryCodes.java
@@ -91,161 +91,160 @@ class CountryCodes {
 		new Country("GP", "Guadeloupe", "590", "00", ""),
 		new Country("GQ", "Equatorial Guinea", "240", "00", ""),
 		new Country("GR", "Greece", "30", "00", ""),
-		new Country("GS", "South Georgia and the South Sandwich Islands",
-				"995", "8**10", "8"),
-				new Country("GT", "Guatemala", "502", "00", ""),
-				new Country("GU", "Guam", "1", "011", "1"),
-				new Country("GW", "Guinea-Bissau", "245", "00", ""),
-				new Country("GY", "Guyana", "592", "001", "0"),
-				new Country("HK", "Hong Kong", "852", "001", ""),
-				new Country("HM", "Heard Island and McDonald Islands", "692", "00", "0"),
-				new Country("HN", "Honduras", "504", "00", "0"),
-				new Country("HR", "Croatia", "385", "00", "0"),
-				new Country("HT", "Haiti", "509", "00", "0"),
-				new Country("HU", "Hungary", "36", "00", "06"),
-				new Country("ID", "Indonesia", "62", "001", "0"),
-				new Country("IE", "Ireland", "353", "00", "0"),
-				new Country("IL", "Israel", "972", "00", "0"),
-				new Country("IN", "India", "91", "00", "0"),
-				new Country("IO", "British Indian Ocean Territory", "246", "00", ""),
-				new Country("IQ", "Iraq", "964", "00", "0"),
-				new Country("IR", "Iran", "98", "00", "0"),
-				new Country("IS", "Iceland", "354", "00", "0"),
-				new Country("IT", "Italy", "39", "00", ""),
-				new Country("JM", "Jamaica", "1", "011", "1"),
-				new Country("JO", "Jordan", "962", "00", "0"),
-				new Country("JP", "Japan", "81", "001", "0"),
-				new Country("KE", "Kenya", "254", "000", "0"),
-				new Country("KG", "Kyrgyzstan", "996", "00", "0"),
-				new Country("KH", "Cambodia", "855", "001", "0"),
-				new Country("KI", "Kiribati", "686", "00", "0"),
-				new Country("KM", "Comoros", "269", "00", ""),
-				new Country("KN", "Saint Kitts and Nevis", "1", "011", "1"),
-				new Country("KP", "Korea (North)", "850", "00", "0"),
-				new Country("KR", "Korea (South)", "82", "001", "0"),
-				new Country("KW", "Kuwait", "965", "00", "0"),
-				new Country("KY", "Cayman Islands", "1", "011", "1"),
-				new Country("KZ", "Kazakhstan", "7", "8**10", "8"),
-				new Country("LA", "Laos", "856", "00", "0"),
-				new Country("LB", "Lebanon", "961", "00", "0"),
-				new Country("LC", "Saint Lucia", "1", "011", "1"),
-				new Country("LI", "Liechtenstein", "423", "00", ""),
-				new Country("LK", "Sri Lanka", "94", "00", "0"),
-				new Country("LR", "Liberia", "231", "00", "22"),
-				new Country("LS", "Lesotho", "266", "00", "0"),
-				new Country("LT", "Lithuania", "370", "00", "8"),
-				new Country("LU", "Luxembourg", "352", "00", ""),
-				new Country("LV", "Latvia", "371", "00", "8"),
-				new Country("LY", "Libya", "218", "00", "0"),
-				new Country("MA", "Morocco", "212", "00", ""),
-				new Country("MC", "Monaco", "377", "00", "0"),
-				new Country("MD", "Moldova", "373", "00", "0"),
-				new Country("ME", "Montenegro", "382", "99", "0"),
-				new Country("MG", "Madagascar", "261", "00", "0"),
-				new Country("MH", "Marshall Islands", "692", "011", "1"),
-				new Country("MK", "Macedonia", "389", "00", "0"),
-				new Country("ML", "Mali", "223", "00", "0"),
-				new Country("MM", "Myanmar", "95", "00", ""),
-				new Country("MN", "Mongolia", "976", "001", "0"),
-				new Country("MO", "Macao", "853", "00", "0"),
-				new Country("MP", "Northern Mariana Islands", "1", "011", "1"),
-				new Country("MQ", "Martinique", "596", "00", "0"),
-				new Country("MR", "Mauritania", "222", "00", "0"),
-				new Country("MS", "Montserrat", "1", "011", "1"),
-				new Country("MT", "Malta", "356", "00", "21"),
-				new Country("MU", "Mauritius", "230", "00", "0"),
-				new Country("MV", "Maldives", "960", "00", "0"),
-				new Country("MW", "Malawi", "265", "00", ""),
-				new Country("MX", "Mexico", "52", "00", "01"),
-				new Country("MY", "Malaysia", "60", "00", "0"),
-				new Country("MZ", "Mozambique", "258", "00", "0"),
-				new Country("NA", "Namibia", "264", "00", "0"),
-				new Country("NC", "New Caledonia", "687", "00", "0"),
-				new Country("NE", "Niger", "227", "00", "0"),
-				new Country("NF", "Norfolk Island", "672", "00", ""),
-				new Country("NG", "Nigeria", "234", "009", "0"),
-				new Country("NI", "Nicaragua", "505", "00", "0"),
-				new Country("NL", "Netherlands", "31", "00", "0"),
-				new Country("NO", "Norway", "47", "00", ""),
-				new Country("NP", "Nepal", "977", "00", "0"),
-				new Country("NR", "Nauru", "674", "00", "0"),
-				new Country("NU", "Niue", "683", "00", "0"),
-				new Country("NZ", "New Zealand", "64", "00", "0"),
-				new Country("OM", "Oman", "968", "00", "0"),
-				new Country("PA", "Panama", "507", "00", "0"),
-				new Country("PE", "Peru", "51", "00", "0"),
-				new Country("PF", "French Polynesia", "689", "00", ""),
-				new Country("PG", "Papua New Guinea", "675", "05", ""),
-				new Country("PH", "Philippines", "63", "00", "0"),
-				new Country("PK", "Pakistan", "92", "00", "0"),
-				new Country("PL", "Poland", "48", "00", "0"),
-				new Country("PM", "Saint Pierre and Miquelon", "508", "00", "0"),
-				new Country("PN", "Pitcairn", "872", "", ""),
-				new Country("PR", "Puerto Rico", "1", "011", "1"),
-				new Country("PS", "Palestine", "970", "00", "0"),
-				new Country("PT", "Portugal", "351", "00", ""),
-				new Country("PW", "Palau", "680", "011", ""),
-				new Country("PY", "Paraguay", "595", "002", "0"),
-				new Country("QA", "Qatar", "974", "00", "0"),
-				new Country("RE", "Reunion", "262", "00", "0"),
-				new Country("RO", "Romania", "40", "00", "0"),
-				new Country("RS", "Serbia", "381", "99", "0"),
-				new Country("RU", "Russia", "7", "8**10", "8"),
-				new Country("RW", "Rwanda", "250", "00", "0"),
-				new Country("SA", "Saudi Arabia", "966", "00", "0"),
-				new Country("SB", "Solomon Islands", "677", "00", ""),
-				new Country("SC", "Seychelles", "248", "00", "0"),
-				new Country("SD", "Sudan", "249", "00", "0"),
-				new Country("SE", "Sweden", "46", "00", "0"),
-				new Country("SG", "Singapore", "65", "001", ""),
-				new Country("SH", "Saint Helena", "290", "00", ""),
-				new Country("SI", "Slovenia", "386", "00", "0"),
-				new Country("SJ", "Svalbard and Jan Mayen", "378", "00", "0"),
-				new Country("SK", "Slovakia", "421", "00", "0"),
-				new Country("SL", "Sierra Leone", "232", "00", "0"),
-				new Country("SM", "San Marino", "378", "00", "0"),
-				new Country("SN", "Senegal", "221", "00", "0"),
-				new Country("SO", "Somalia", "252", "00", ""),
-				new Country("SR", "Suriname", "597", "00", ""),
-				new Country("ST", "Sao Tome and Principe", "239", "00", "0"),
-				new Country("SV", "El Salvador", "503", "00", ""),
-				new Country("SY", "Syria", "963", "00", "0"),
-				new Country("SZ", "Swaziland", "268", "00", ""),
-				new Country("TC", "Turks and Caicos Islands", "1", "011", "1"),
-				new Country("TD", "Chad", "235", "15", ""),
-				new Country("TF", "French Southern Territories", "596", "00", "0"),
-				new Country("TG", "Togo", "228", "00", ""),
-				new Country("TH", "Thailand", "66", "001", "0"),
-				new Country("TJ", "Tajikistan", "992", "8**10", "8"),
-				new Country("TK", "Tokelau", "690", "00", ""),
-				new Country("TL", "Timor-Leste", "670", "00", ""),
-				new Country("TM", "Turkmenistan", "993", "8**10", "8"),
-				new Country("TN", "Tunisia", "216", "00", "0"),
-				new Country("TO", "Tonga Islands", "676", "00", ""),
-				new Country("TR", "Turkey", "90", "00", "0"),
-				new Country("TT", "Trinidad and Tobago", "1", "011", "1"),
-				new Country("TV", "Tuvalu", "688", "00", ""),
-				new Country("TW", "Taiwan", "886", "002", ""),
-				new Country("TZ", "Tanzania", "255", "000", "0"),
-				new Country("UA", "Ukraine", "380", "8**10", "8"),
-				new Country("UG", "Uganda", "256", "000", "0"),
-				new Country("US", "United States", "1", "011", "1"),
-				new Country("UY", "Uruguay", "598", "00", "0"),
-				new Country("UZ", "Uzbekistan", "998", "8**10", "8"),
-				new Country("VA", "Holy See (Vatican City State)", "379", "00", ""),
-				new Country("VC", "Saint Vincent and the Grenadines", "1", "011", "1"),
-				new Country("VE", "Venezuela", "58", "00", "0"),
-				new Country("VG", "Virgin Islands (British)", "1", "011", "1"),
-				new Country("VI", "Virgin Islands (U.S.)", "1", "011", "1"),
-				new Country("VN", "Viet Nam", "84", "00", "0"),
-				new Country("VU", "Vanuatu", "678", "00", ""),
-				new Country("WF", "Wallis and Futuna Islands", "681", "19", ""),
-				new Country("WS", "Samoa (Western)", "685", "0", "0"),
-				new Country("YE", "Yemen", "967", "00", "0"),
-				new Country("YT", "Mayotte", "269", "00", ""),
-				new Country("ZA", "South Africa", "27", "09", "0"),
-				new Country("ZM", "Zambia", "260", "00", "0"),
-				new Country("ZW", "Zimbabwe", "263", "110", "0")
+		new Country("GS", "South Georgia and the South Sandwich Islands", "995", "8**10", "8"),
+		new Country("GT", "Guatemala", "502", "00", ""),
+		new Country("GU", "Guam", "1", "011", "1"),
+		new Country("GW", "Guinea-Bissau", "245", "00", ""),
+		new Country("GY", "Guyana", "592", "001", "0"),
+		new Country("HK", "Hong Kong", "852", "001", ""),
+		new Country("HM", "Heard Island and McDonald Islands", "692", "00", "0"),
+		new Country("HN", "Honduras", "504", "00", "0"),
+		new Country("HR", "Croatia", "385", "00", "0"),
+		new Country("HT", "Haiti", "509", "00", "0"),
+		new Country("HU", "Hungary", "36", "00", "06"),
+		new Country("ID", "Indonesia", "62", "001", "0"),
+		new Country("IE", "Ireland", "353", "00", "0"),
+		new Country("IL", "Israel", "972", "00", "0"),
+		new Country("IN", "India", "91", "00", "0"),
+		new Country("IO", "British Indian Ocean Territory", "246", "00", ""),
+		new Country("IQ", "Iraq", "964", "00", "0"),
+		new Country("IR", "Iran", "98", "00", "0"),
+		new Country("IS", "Iceland", "354", "00", "0"),
+		new Country("IT", "Italy", "39", "00", ""),
+		new Country("JM", "Jamaica", "1", "011", "1"),
+		new Country("JO", "Jordan", "962", "00", "0"),
+		new Country("JP", "Japan", "81", "001", "0"),
+		new Country("KE", "Kenya", "254", "000", "0"),
+		new Country("KG", "Kyrgyzstan", "996", "00", "0"),
+		new Country("KH", "Cambodia", "855", "001", "0"),
+		new Country("KI", "Kiribati", "686", "00", "0"),
+		new Country("KM", "Comoros", "269", "00", ""),
+		new Country("KN", "Saint Kitts and Nevis", "1", "011", "1"),
+		new Country("KP", "Korea (North)", "850", "00", "0"),
+		new Country("KR", "Korea (South)", "82", "001", "0"),
+		new Country("KW", "Kuwait", "965", "00", "0"),
+		new Country("KY", "Cayman Islands", "1", "011", "1"),
+		new Country("KZ", "Kazakhstan", "7", "8**10", "8"),
+		new Country("LA", "Laos", "856", "00", "0"),
+		new Country("LB", "Lebanon", "961", "00", "0"),
+		new Country("LC", "Saint Lucia", "1", "011", "1"),
+		new Country("LI", "Liechtenstein", "423", "00", ""),
+		new Country("LK", "Sri Lanka", "94", "00", "0"),
+		new Country("LR", "Liberia", "231", "00", "22"),
+		new Country("LS", "Lesotho", "266", "00", "0"),
+		new Country("LT", "Lithuania", "370", "00", "8"),
+		new Country("LU", "Luxembourg", "352", "00", ""),
+		new Country("LV", "Latvia", "371", "00", "8"),
+		new Country("LY", "Libya", "218", "00", "0"),
+		new Country("MA", "Morocco", "212", "00", ""),
+		new Country("MC", "Monaco", "377", "00", "0"),
+		new Country("MD", "Moldova", "373", "00", "0"),
+		new Country("ME", "Montenegro", "382", "99", "0"),
+		new Country("MG", "Madagascar", "261", "00", "0"),
+		new Country("MH", "Marshall Islands", "692", "011", "1"),
+		new Country("MK", "Macedonia", "389", "00", "0"),
+		new Country("ML", "Mali", "223", "00", "0"),
+		new Country("MM", "Myanmar", "95", "00", ""),
+		new Country("MN", "Mongolia", "976", "001", "0"),
+		new Country("MO", "Macao", "853", "00", "0"),
+		new Country("MP", "Northern Mariana Islands", "1", "011", "1"),
+		new Country("MQ", "Martinique", "596", "00", "0"),
+		new Country("MR", "Mauritania", "222", "00", "0"),
+		new Country("MS", "Montserrat", "1", "011", "1"),
+		new Country("MT", "Malta", "356", "00", "21"),
+		new Country("MU", "Mauritius", "230", "00", "0"),
+		new Country("MV", "Maldives", "960", "00", "0"),
+		new Country("MW", "Malawi", "265", "00", ""),
+		new Country("MX", "Mexico", "52", "00", "01"),
+		new Country("MY", "Malaysia", "60", "00", "0"),
+		new Country("MZ", "Mozambique", "258", "00", "0"),
+		new Country("NA", "Namibia", "264", "00", "0"),
+		new Country("NC", "New Caledonia", "687", "00", "0"),
+		new Country("NE", "Niger", "227", "00", "0"),
+		new Country("NF", "Norfolk Island", "672", "00", ""),
+		new Country("NG", "Nigeria", "234", "009", "0"),
+		new Country("NI", "Nicaragua", "505", "00", "0"),
+		new Country("NL", "Netherlands", "31", "00", "0"),
+		new Country("NO", "Norway", "47", "00", ""),
+		new Country("NP", "Nepal", "977", "00", "0"),
+		new Country("NR", "Nauru", "674", "00", "0"),
+		new Country("NU", "Niue", "683", "00", "0"),
+		new Country("NZ", "New Zealand", "64", "00", "0"),
+		new Country("OM", "Oman", "968", "00", "0"),
+		new Country("PA", "Panama", "507", "00", "0"),
+		new Country("PE", "Peru", "51", "00", "0"),
+		new Country("PF", "French Polynesia", "689", "00", ""),
+		new Country("PG", "Papua New Guinea", "675", "05", ""),
+		new Country("PH", "Philippines", "63", "00", "0"),
+		new Country("PK", "Pakistan", "92", "00", "0"),
+		new Country("PL", "Poland", "48", "00", "0"),
+		new Country("PM", "Saint Pierre and Miquelon", "508", "00", "0"),
+		new Country("PN", "Pitcairn", "872", "", ""),
+		new Country("PR", "Puerto Rico", "1", "011", "1"),
+		new Country("PS", "Palestine", "970", "00", "0"),
+		new Country("PT", "Portugal", "351", "00", ""),
+		new Country("PW", "Palau", "680", "011", ""),
+		new Country("PY", "Paraguay", "595", "002", "0"),
+		new Country("QA", "Qatar", "974", "00", "0"),
+		new Country("RE", "Reunion", "262", "00", "0"),
+		new Country("RO", "Romania", "40", "00", "0"),
+		new Country("RS", "Serbia", "381", "99", "0"),
+		new Country("RU", "Russia", "7", "8**10", "8"),
+		new Country("RW", "Rwanda", "250", "00", "0"),
+		new Country("SA", "Saudi Arabia", "966", "00", "0"),
+		new Country("SB", "Solomon Islands", "677", "00", ""),
+		new Country("SC", "Seychelles", "248", "00", "0"),
+		new Country("SD", "Sudan", "249", "00", "0"),
+		new Country("SE", "Sweden", "46", "00", "0"),
+		new Country("SG", "Singapore", "65", "001", ""),
+		new Country("SH", "Saint Helena", "290", "00", ""),
+		new Country("SI", "Slovenia", "386", "00", "0"),
+		new Country("SJ", "Svalbard and Jan Mayen", "378", "00", "0"),
+		new Country("SK", "Slovakia", "421", "00", "0"),
+		new Country("SL", "Sierra Leone", "232", "00", "0"),
+		new Country("SM", "San Marino", "378", "00", "0"),
+		new Country("SN", "Senegal", "221", "00", "0"),
+		new Country("SO", "Somalia", "252", "00", ""),
+		new Country("SR", "Suriname", "597", "00", ""),
+		new Country("ST", "Sao Tome and Principe", "239", "00", "0"),
+		new Country("SV", "El Salvador", "503", "00", ""),
+		new Country("SY", "Syria", "963", "00", "0"),
+		new Country("SZ", "Swaziland", "268", "00", ""),
+		new Country("TC", "Turks and Caicos Islands", "1", "011", "1"),
+		new Country("TD", "Chad", "235", "15", ""),
+		new Country("TF", "French Southern Territories", "596", "00", "0"),
+		new Country("TG", "Togo", "228", "00", ""),
+		new Country("TH", "Thailand", "66", "001", "0"),
+		new Country("TJ", "Tajikistan", "992", "8**10", "8"),
+		new Country("TK", "Tokelau", "690", "00", ""),
+		new Country("TL", "Timor-Leste", "670", "00", ""),
+		new Country("TM", "Turkmenistan", "993", "8**10", "8"),
+		new Country("TN", "Tunisia", "216", "00", "0"),
+		new Country("TO", "Tonga Islands", "676", "00", ""),
+		new Country("TR", "Turkey", "90", "00", "0"),
+		new Country("TT", "Trinidad and Tobago", "1", "011", "1"),
+		new Country("TV", "Tuvalu", "688", "00", ""),
+		new Country("TW", "Taiwan", "886", "002", ""),
+		new Country("TZ", "Tanzania", "255", "000", "0"),
+		new Country("UA", "Ukraine", "380", "8**10", "8"),
+		new Country("UG", "Uganda", "256", "000", "0"),
+		new Country("US", "United States", "1", "011", "1"),
+		new Country("UY", "Uruguay", "598", "00", "0"),
+		new Country("UZ", "Uzbekistan", "998", "8**10", "8"),
+		new Country("VA", "Holy See (Vatican City State)", "379", "00", ""),
+		new Country("VC", "Saint Vincent and the Grenadines", "1", "011", "1"),
+		new Country("VE", "Venezuela", "58", "00", "0"),
+		new Country("VG", "Virgin Islands (British)", "1", "011", "1"),
+		new Country("VI", "Virgin Islands (U.S.)", "1", "011", "1"),
+		new Country("VN", "Viet Nam", "84", "00", "0"),
+		new Country("VU", "Vanuatu", "678", "00", ""),
+		new Country("WF", "Wallis and Futuna Islands", "681", "19", ""),
+		new Country("WS", "Samoa (Western)", "685", "0", "0"),
+		new Country("YE", "Yemen", "967", "00", "0"),
+		new Country("YT", "Mayotte", "269", "00", ""),
+		new Country("ZA", "South Africa", "27", "09", "0"),
+		new Country("ZM", "Zambia", "260", "00", "0"),
+		new Country("ZW", "Zimbabwe", "263", "110", "0")
 	};
 
 	private static final Map<String, Country> COUNTRY_MAP =
diff --git a/briar-desktop/src/org/briarproject/plugins/modem/ModemImpl.java b/briar-desktop/src/org/briarproject/plugins/modem/ModemImpl.java
index f8be63c116..2896f48d02 100644
--- a/briar-desktop/src/org/briarproject/plugins/modem/ModemImpl.java
+++ b/briar-desktop/src/org/briarproject/plugins/modem/ModemImpl.java
@@ -44,15 +44,15 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
 	private final Semaphore stateChange;
 	private final byte[] line;
 
-	private int lineLen = 0;
-
-	private ReliabilityLayer reliability = null;
-	private boolean initialised = false, connected = false;
-
 	private final Lock synchLock = new ReentrantLock();
 	private final Condition connectedStateChanged = synchLock.newCondition();
 	private final Condition initialisedStateChanged = synchLock.newCondition();
 
+	// The following are locking: synchLock
+	private ReliabilityLayer reliability = null;
+	private boolean initialised = false, connected = false;
+
+	private int lineLen = 0;
 
 	ModemImpl(Executor ioExecutor, ReliabilityLayerFactory reliabilityFactory,
 			Clock clock, Callback callback, SerialPort port) {
@@ -161,6 +161,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
 		}
 	}
 
+	// Locking: stateChange
 	private void hangUpInner() throws IOException {
 		ReliabilityLayer reliability;
 		synchLock.lock();
diff --git a/briar-tests/src/org/briarproject/crypto/StreamEncrypterImplTest.java b/briar-tests/src/org/briarproject/crypto/StreamEncrypterImplTest.java
index a874314165..8d1e2aa088 100644
--- a/briar-tests/src/org/briarproject/crypto/StreamEncrypterImplTest.java
+++ b/briar-tests/src/org/briarproject/crypto/StreamEncrypterImplTest.java
@@ -213,9 +213,9 @@ public class StreamEncrypterImplTest extends BriarTestCase {
 		FrameEncoder.encodeHeader(header1, true, payloadLength1,
 				paddingLength1);
 		byte[] expected = new byte[HEADER_LENGTH + payloadLength
-		                           + paddingLength + MAC_LENGTH
-		                           + HEADER_LENGTH + payloadLength1
-		                           + paddingLength1 + MAC_LENGTH];
+		                           + paddingLength + MAC_LENGTH + HEADER_LENGTH
+		                           + payloadLength + paddingLength1
+		                           + MAC_LENGTH];
 		System.arraycopy(header, 0, expected, 0, HEADER_LENGTH);
 		System.arraycopy(payload, 0, expected, HEADER_LENGTH, payloadLength);
 		System.arraycopy(header1, 0, expected, HEADER_LENGTH + payloadLength
-- 
GitLab