diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/AndroidPluginModule.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/AndroidPluginModule.java
index d070c90ea852f2cced900ab0317f239007634824..0dbc81b3ec3ff890a0e2d3429c2f3a55d0774196 100644
--- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/AndroidPluginModule.java
+++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/AndroidPluginModule.java
@@ -45,7 +45,7 @@ public class AndroidPluginModule {
 				backoffFactory);
 		DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor,
 				backoffFactory, appContext);
-		final Collection<DuplexPluginFactory> duplex =
+		Collection<DuplexPluginFactory> duplex =
 				Arrays.asList(bluetooth, tor, lan);
 		@NotNullByDefault
 		PluginConfig pluginConfig = new PluginConfig() {
diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPlugin.java
index a2d0695ece65119fd26554e5ec7efaaca54d255d..580c5834508642e8f1d0892ee67ee607ca0b7e9c 100644
--- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPlugin.java
+++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPlugin.java
@@ -124,12 +124,7 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
 		// with a message queue, so submit it to the AndroidExecutor
 		try {
 			adapter = androidExecutor.runOnBackgroundThread(
-					new Callable<BluetoothAdapter>() {
-						@Override
-						public BluetoothAdapter call() throws Exception {
-							return BluetoothAdapter.getDefaultAdapter();
-						}
-					}).get();
+					BluetoothAdapter::getDefaultAdapter).get();
 		} catch (InterruptedException e) {
 			Thread.currentThread().interrupt();
 			LOG.warning("Interrupted while getting BluetoothAdapter");
@@ -162,40 +157,36 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
 	}
 
 	private void bind() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				if (!isRunning()) return;
-				String address = AndroidUtils.getBluetoothAddress(appContext,
-						adapter);
-				if (LOG.isLoggable(INFO))
-					LOG.info("Local address " + scrubMacAddress(address));
-				if (!StringUtils.isNullOrEmpty(address)) {
-					// Advertise the Bluetooth address to contacts
-					TransportProperties p = new TransportProperties();
-					p.put(PROP_ADDRESS, address);
-					callback.mergeLocalProperties(p);
-				}
-				// Bind a server socket to accept connections from contacts
-				BluetoothServerSocket ss;
-				try {
-					ss = adapter.listenUsingInsecureRfcommWithServiceRecord(
-							"RFCOMM", getUuid());
-				} catch (IOException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					return;
-				}
-				if (!isRunning()) {
-					tryToClose(ss);
-					return;
-				}
-				LOG.info("Socket bound");
-				socket = ss;
-				backoff.reset();
-				callback.transportEnabled();
-				acceptContactConnections();
+		ioExecutor.execute(() -> {
+			if (!isRunning()) return;
+			String address = AndroidUtils.getBluetoothAddress(appContext,
+					adapter);
+			if (LOG.isLoggable(INFO))
+				LOG.info("Local address " + scrubMacAddress(address));
+			if (!StringUtils.isNullOrEmpty(address)) {
+				// Advertise the Bluetooth address to contacts
+				TransportProperties p = new TransportProperties();
+				p.put(PROP_ADDRESS, address);
+				callback.mergeLocalProperties(p);
+			}
+			// Bind a server socket to accept connections from contacts
+			BluetoothServerSocket ss;
+			try {
+				ss = adapter.listenUsingInsecureRfcommWithServiceRecord(
+						"RFCOMM", getUuid());
+			} catch (IOException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				return;
 			}
+			if (!isRunning()) {
+				tryToClose(ss);
+				return;
+			}
+			LOG.info("Socket bound");
+			socket = ss;
+			backoff.reset();
+			callback.transportEnabled();
+			acceptContactConnections();
 		});
 	}
 
@@ -294,21 +285,18 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
 		Map<ContactId, TransportProperties> remote =
 				callback.getRemoteProperties();
 		for (Entry<ContactId, TransportProperties> e : remote.entrySet()) {
-			final ContactId c = e.getKey();
+			ContactId c = e.getKey();
 			if (connected.contains(c)) continue;
-			final String address = e.getValue().get(PROP_ADDRESS);
+			String address = e.getValue().get(PROP_ADDRESS);
 			if (StringUtils.isNullOrEmpty(address)) continue;
-			final String uuid = e.getValue().get(PROP_UUID);
+			String uuid = e.getValue().get(PROP_UUID);
 			if (StringUtils.isNullOrEmpty(uuid)) continue;
-			ioExecutor.execute(new Runnable() {
-				@Override
-				public void run() {
-					if (!running) return;
-					BluetoothSocket s = connect(address, uuid);
-					if (s != null) {
-						backoff.reset();
-						callback.outgoingConnectionCreated(c, wrapSocket(s));
-					}
+			ioExecutor.execute(() -> {
+				if (!running) return;
+				BluetoothSocket s = connect(address, uuid);
+				if (s != null) {
+					backoff.reset();
+					callback.outgoingConnectionCreated(c, wrapSocket(s));
 				}
 			});
 		}
@@ -438,21 +426,11 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
 	}
 
 	private void enableAdapterAsync() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				enableAdapter();
-			}
-		});
+		ioExecutor.execute(this::enableAdapter);
 	}
 
 	private void disableAdapterAsync() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				disableAdapter();
-			}
-		});
+		ioExecutor.execute(this::disableAdapter);
 	}
 
 	private class BluetoothStateReceiver extends BroadcastReceiver {
@@ -490,16 +468,13 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
 
 		@Override
 		public Callable<KeyAgreementConnection> listen() {
-			return new Callable<KeyAgreementConnection>() {
-				@Override
-				public KeyAgreementConnection call() throws IOException {
-					BluetoothSocket s = ss.accept();
-					if (LOG.isLoggable(INFO))
-						LOG.info(ID.getString() + ": Incoming connection");
-					return new KeyAgreementConnection(
-							new DroidtoothTransportConnection(
-									DroidtoothPlugin.this, s), ID);
-				}
+			return () -> {
+				BluetoothSocket s = ss.accept();
+				if (LOG.isLoggable(INFO))
+					LOG.info(ID.getString() + ": Incoming connection");
+				return new KeyAgreementConnection(
+						new DroidtoothTransportConnection(
+								DroidtoothPlugin.this, s), ID);
 			};
 		}
 
diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java
index 5322532a2c91457b7b9f3c3d82d31c4ac50fbe98..1045f372ce34a604054cf8036ea81611f9288642 100644
--- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java
+++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java
@@ -370,57 +370,45 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
 	}
 
 	private void sendDevReports() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				// TODO: Trigger this with a TransportEnabledEvent
-				File reportDir = AndroidUtils.getReportDir(appContext);
-				reporter.sendReports(reportDir);
-			}
+		ioExecutor.execute(() -> {
+			// TODO: Trigger this with a TransportEnabledEvent
+			File reportDir = AndroidUtils.getReportDir(appContext);
+			reporter.sendReports(reportDir);
 		});
 	}
 
 	private void bind() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				// If there's already a port number stored in config, reuse it
-				String portString = callback.getSettings().get(PREF_TOR_PORT);
-				int port;
-				if (StringUtils.isNullOrEmpty(portString)) port = 0;
-				else port = Integer.parseInt(portString);
-				// Bind a server socket to receive connections from Tor
-				ServerSocket ss = null;
-				try {
-					ss = new ServerSocket();
-					ss.bind(new InetSocketAddress("127.0.0.1", port));
-				} catch (IOException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					tryToClose(ss);
-					return;
-				}
-				if (!running) {
-					tryToClose(ss);
-					return;
-				}
-				socket = ss;
-				// Store the port number
-				final String localPort = String.valueOf(ss.getLocalPort());
-				Settings s = new Settings();
-				s.put(PREF_TOR_PORT, localPort);
-				callback.mergeSettings(s);
-				// Create a hidden service if necessary
-				ioExecutor.execute(new Runnable() {
-					@Override
-					public void run() {
-						publishHiddenService(localPort);
-					}
-				});
-				backoff.reset();
-				// Accept incoming hidden service connections from Tor
-				acceptContactConnections(ss);
+		ioExecutor.execute(() -> {
+			// If there's already a port number stored in config, reuse it
+			String portString = callback.getSettings().get(PREF_TOR_PORT);
+			int port;
+			if (StringUtils.isNullOrEmpty(portString)) port = 0;
+			else port = Integer.parseInt(portString);
+			// Bind a server socket to receive connections from Tor
+			ServerSocket ss = null;
+			try {
+				ss = new ServerSocket();
+				ss.bind(new InetSocketAddress("127.0.0.1", port));
+			} catch (IOException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				tryToClose(ss);
+				return;
+			}
+			if (!running) {
+				tryToClose(ss);
+				return;
 			}
+			socket = ss;
+			// Store the port number
+			String localPort = String.valueOf(ss.getLocalPort());
+			Settings s = new Settings();
+			s.put(PREF_TOR_PORT, localPort);
+			callback.mergeSettings(s);
+			// Create a hidden service if necessary
+			ioExecutor.execute(() -> publishHiddenService(localPort));
+			backoff.reset();
+			// Accept incoming hidden service connections from Tor
+			acceptContactConnections(ss);
 		});
 	}
 
@@ -548,17 +536,13 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
 		}
 	}
 
-	private void connectAndCallBack(final ContactId c,
-			final TransportProperties p) {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				if (!isRunning()) return;
-				DuplexTransportConnection d = createConnection(p);
-				if (d != null) {
-					backoff.reset();
-					callback.outgoingConnectionCreated(c, d);
-				}
+	private void connectAndCallBack(ContactId c, TransportProperties p) {
+		ioExecutor.execute(() -> {
+			if (!isRunning()) return;
+			DuplexTransportConnection d = createConnection(p);
+			if (d != null) {
+				backoff.reset();
+				callback.outgoingConnectionCreated(c, d);
 			}
 		});
 	}
@@ -691,48 +675,43 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
 	}
 
 	private void updateConnectionStatus() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				if (!running) return;
-
-				Object o = appContext.getSystemService(CONNECTIVITY_SERVICE);
-				ConnectivityManager cm = (ConnectivityManager) o;
-				NetworkInfo net = cm.getActiveNetworkInfo();
-				boolean online = net != null && net.isConnected();
-				boolean wifi = online && net.getType() == TYPE_WIFI;
-				String country = locationUtils.getCurrentCountry();
-				boolean blocked = TorNetworkMetadata.isTorProbablyBlocked(
-						country);
-				Settings s = callback.getSettings();
-				int network = s.getInt(PREF_TOR_NETWORK,
-						PREF_TOR_NETWORK_ALWAYS);
-
-				if (LOG.isLoggable(INFO)) {
-					LOG.info("Online: " + online + ", wifi: " + wifi);
-					if ("".equals(country)) LOG.info("Country code unknown");
-					else LOG.info("Country code: " + country);
-				}
+		ioExecutor.execute(() -> {
+			if (!running) return;
+
+			Object o = appContext.getSystemService(CONNECTIVITY_SERVICE);
+			ConnectivityManager cm = (ConnectivityManager) o;
+			NetworkInfo net = cm.getActiveNetworkInfo();
+			boolean online = net != null && net.isConnected();
+			boolean wifi = online && net.getType() == TYPE_WIFI;
+			String country = locationUtils.getCurrentCountry();
+			boolean blocked = TorNetworkMetadata.isTorProbablyBlocked(
+					country);
+			Settings s = callback.getSettings();
+			int network = s.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_ALWAYS);
 
-				try {
-					if (!online) {
-						LOG.info("Disabling network, device is offline");
-						enableNetwork(false);
-					} else if (blocked) {
-						LOG.info("Disabling network, country is blocked");
-						enableNetwork(false);
-					} else if (network == PREF_TOR_NETWORK_NEVER
-							|| (network == PREF_TOR_NETWORK_WIFI && !wifi)) {
-						LOG.info("Disabling network due to data setting");
-						enableNetwork(false);
-					} else {
-						LOG.info("Enabling network");
-						enableNetwork(true);
-					}
-				} catch (IOException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
+			if (LOG.isLoggable(INFO)) {
+				LOG.info("Online: " + online + ", wifi: " + wifi);
+				if ("".equals(country)) LOG.info("Country code unknown");
+				else LOG.info("Country code: " + country);
+			}
+
+			try {
+				if (!online) {
+					LOG.info("Disabling network, device is offline");
+					enableNetwork(false);
+				} else if (blocked) {
+					LOG.info("Disabling network, country is blocked");
+					enableNetwork(false);
+				} else if (network == PREF_TOR_NETWORK_NEVER
+						|| (network == PREF_TOR_NETWORK_WIFI && !wifi)) {
+					LOG.info("Disabling network due to data setting");
+					enableNetwork(false);
+				} else {
+					LOG.info("Enabling network");
+					enableNetwork(true);
 				}
+			} catch (IOException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
diff --git a/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidExecutorImpl.java b/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidExecutorImpl.java
index f07b2d721fc7a5cc5c66a53bd37a701242d11317..fb7fb701bcd64905f4d0fe7654a04215b64b0d5f 100644
--- a/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidExecutorImpl.java
+++ b/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidExecutorImpl.java
@@ -27,14 +27,11 @@ class AndroidExecutorImpl implements AndroidExecutor {
 	@Inject
 	AndroidExecutorImpl(Application app) {
 		uiHandler = new Handler(app.getApplicationContext().getMainLooper());
-		loop = new Runnable() {
-			@Override
-			public void run() {
-				Looper.prepare();
-				backgroundHandler = new Handler();
-				startLatch.countDown();
-				Looper.loop();
-			}
+		loop = () -> {
+			Looper.prepare();
+			backgroundHandler = new Handler();
+			startLatch.countDown();
+			Looper.loop();
 		};
 	}
 
diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/client/BdfMessageContext.java b/bramble-api/src/main/java/org/briarproject/bramble/api/client/BdfMessageContext.java
index 4cc02f3a247fbcf1b32f09e3266b8a1cb4cecba7..fe238b9e0229b7616c4bf0bd61ad477637c5ac81 100644
--- a/bramble-api/src/main/java/org/briarproject/bramble/api/client/BdfMessageContext.java
+++ b/bramble-api/src/main/java/org/briarproject/bramble/api/client/BdfMessageContext.java
@@ -23,7 +23,7 @@ public class BdfMessageContext {
 	}
 
 	public BdfMessageContext(BdfDictionary dictionary) {
-		this(dictionary, Collections.<MessageId>emptyList());
+		this(dictionary, Collections.emptyList());
 	}
 
 	public BdfDictionary getDictionary() {
diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/db/Transaction.java b/bramble-api/src/main/java/org/briarproject/bramble/api/db/Transaction.java
index e228c84ec49b5ce986764b92c23ba4497465c7c5..0e55fd6508bd9ed088401c5044a9ef9ec4170056 100644
--- a/bramble-api/src/main/java/org/briarproject/bramble/api/db/Transaction.java
+++ b/bramble-api/src/main/java/org/briarproject/bramble/api/db/Transaction.java
@@ -45,7 +45,7 @@ public class Transaction {
 	 * committed.
 	 */
 	public void attach(Event e) {
-		if (events == null) events = new ArrayList<Event>();
+		if (events == null) events = new ArrayList<>();
 		events.add(e);
 	}
 
diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/sync/MessageContext.java b/bramble-api/src/main/java/org/briarproject/bramble/api/sync/MessageContext.java
index c11f630e4b9b87e07b58f2783b2e4bfe7b64115a..c47718c16fcd16702a43ce109b32fbf20993949d 100644
--- a/bramble-api/src/main/java/org/briarproject/bramble/api/sync/MessageContext.java
+++ b/bramble-api/src/main/java/org/briarproject/bramble/api/sync/MessageContext.java
@@ -22,7 +22,7 @@ public class MessageContext {
 	}
 
 	public MessageContext(Metadata metadata) {
-		this(metadata, Collections.<MessageId>emptyList());
+		this(metadata, Collections.emptyList());
 	}
 
 	public Metadata getMetadata() {
diff --git a/bramble-api/src/test/java/org/briarproject/bramble/test/BrambleTestCase.java b/bramble-api/src/test/java/org/briarproject/bramble/test/BrambleTestCase.java
index aa0eb55e506d66599827cf09bc8605c22679f212..9fae780434640f1dbf9132a64135b48881108324 100644
--- a/bramble-api/src/test/java/org/briarproject/bramble/test/BrambleTestCase.java
+++ b/bramble-api/src/test/java/org/briarproject/bramble/test/BrambleTestCase.java
@@ -8,12 +8,9 @@ public abstract class BrambleTestCase {
 
 	public BrambleTestCase() {
 		// Ensure exceptions thrown on worker threads cause tests to fail
-		UncaughtExceptionHandler fail = new UncaughtExceptionHandler() {
-			@Override
-			public void uncaughtException(Thread thread, Throwable throwable) {
-				throwable.printStackTrace();
-				fail();
-			}
+		UncaughtExceptionHandler fail = (thread, throwable) -> {
+			throwable.printStackTrace();
+			fail();
 		};
 		Thread.setDefaultUncaughtExceptionHandler(fail);
 	}
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/PoliteExecutor.java b/bramble-core/src/main/java/org/briarproject/bramble/PoliteExecutor.java
index 02f88c7c1d0ea5e63368323cf57afc0648bb4945..32a3a7b32b8ad3255e70f9fd2926398c4403e793 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/PoliteExecutor.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/PoliteExecutor.java
@@ -24,7 +24,7 @@ public class PoliteExecutor implements Executor {
 
 	private final Object lock = new Object();
 	@GuardedBy("lock")
-	private final Queue<Runnable> queue = new LinkedList<Runnable>();
+	private final Queue<Runnable> queue = new LinkedList<>();
 	private final Executor delegate;
 	private final int maxConcurrentTasks;
 	private final Logger log;
@@ -48,20 +48,17 @@ public class PoliteExecutor implements Executor {
 	}
 
 	@Override
-	public void execute(final Runnable r) {
-		final long submitted = System.currentTimeMillis();
-		Runnable wrapped = new Runnable() {
-			@Override
-			public void run() {
-				if (log.isLoggable(LOG_LEVEL)) {
-					long queued = System.currentTimeMillis() - submitted;
-					log.log(LOG_LEVEL, "Queue time " + queued + " ms");
-				}
-				try {
-					r.run();
-				} finally {
-					scheduleNext();
-				}
+	public void execute(Runnable r) {
+		long submitted = System.currentTimeMillis();
+		Runnable wrapped = () -> {
+			if (log.isLoggable(LOG_LEVEL)) {
+				long queued = System.currentTimeMillis() - submitted;
+				log.log(LOG_LEVEL, "Queue time " + queued + " ms");
+			}
+			try {
+				r.run();
+			} finally {
+				scheduleNext();
 			}
 		};
 		synchronized (lock) {
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/TimeLoggingExecutor.java b/bramble-core/src/main/java/org/briarproject/bramble/TimeLoggingExecutor.java
index e7385f59b086c664e1c49f2ca15952f2eb2c6a9f..c81bf43a7aeb6e6569c624b2831f17ae0bee7f8e 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/TimeLoggingExecutor.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/TimeLoggingExecutor.java
@@ -28,19 +28,16 @@ public class TimeLoggingExecutor extends ThreadPoolExecutor {
 	}
 
 	@Override
-	public void execute(final Runnable r) {
+	public void execute(Runnable r) {
 		if (log.isLoggable(LOG_LEVEL)) {
-			final long submitted = System.currentTimeMillis();
-			super.execute(new Runnable() {
-				@Override
-				public void run() {
-					long started = System.currentTimeMillis();
-					long queued = started - submitted;
-					log.log(LOG_LEVEL, "Queue time " + queued + " ms");
-					r.run();
-					long executing = System.currentTimeMillis() - started;
-					log.log(LOG_LEVEL, "Execution time " + executing + " ms");
-				}
+			long submitted = System.currentTimeMillis();
+			super.execute(() -> {
+				long started = System.currentTimeMillis();
+				long queued = started - submitted;
+				log.log(LOG_LEVEL, "Queue time " + queued + " ms");
+				r.run();
+				long executing = System.currentTimeMillis() - started;
+				log.log(LOG_LEVEL, "Execution time " + executing + " ms");
 			});
 		} else {
 			super.execute(r);
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/client/ClientHelperImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/client/ClientHelperImpl.java
index 55847365f435f44aed5debcca054aad098aa5ff7..2de54e0ce4eab098b28e2a6ceff31eeb27f7bd4f 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/client/ClientHelperImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/client/ClientHelperImpl.java
@@ -201,8 +201,7 @@ class ClientHelperImpl implements ClientHelper {
 	public Map<MessageId, BdfDictionary> getMessageMetadataAsDictionary(
 			Transaction txn, GroupId g) throws DbException, FormatException {
 		Map<MessageId, Metadata> raw = db.getMessageMetadata(txn, g);
-		Map<MessageId, BdfDictionary> parsed =
-				new HashMap<MessageId, BdfDictionary>(raw.size());
+		Map<MessageId, BdfDictionary> parsed = new HashMap<>(raw.size());
 		for (Entry<MessageId, Metadata> e : raw.entrySet())
 			parsed.put(e.getKey(), metadataParser.parse(e.getValue()));
 		return parsed;
@@ -229,8 +228,7 @@ class ClientHelperImpl implements ClientHelper {
 			FormatException {
 		Metadata metadata = metadataEncoder.encode(query);
 		Map<MessageId, Metadata> raw = db.getMessageMetadata(txn, g, metadata);
-		Map<MessageId, BdfDictionary> parsed =
-				new HashMap<MessageId, BdfDictionary>(raw.size());
+		Map<MessageId, BdfDictionary> parsed = new HashMap<>(raw.size());
 		for (Entry<MessageId, Metadata> e : raw.entrySet())
 			parsed.put(e.getKey(), metadataParser.parse(e.getValue()));
 		return parsed;
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactExchangeTaskImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactExchangeTaskImpl.java
index d97c8c9eef8443c203547e1db1f7b0925b40bc73..c49360e5bca20a9b99de30a3e710053c7ce8aea1 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactExchangeTaskImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactExchangeTaskImpl.java
@@ -184,12 +184,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
 			// Close the outgoing stream and expect EOF on the incoming stream
 			w.close();
 			if (!r.eof()) LOG.warning("Unexpected data at end of connection");
-		} catch (GeneralSecurityException e) {
-			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-			listener.contactExchangeFailed();
-			tryToClose(conn, true);
-			return;
-		} catch (IOException e) {
+		} catch (GeneralSecurityException | IOException e) {
 			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			listener.contactExchangeFailed();
 			tryToClose(conn, true);
@@ -276,8 +271,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
 
 	private Map<TransportId, TransportProperties> receiveTransportProperties(
 			BdfReader r) throws IOException {
-		Map<TransportId, TransportProperties> remote =
-				new HashMap<TransportId, TransportProperties>();
+		Map<TransportId, TransportProperties> remote = new HashMap<>();
 		r.readListStart();
 		while (!r.hasListEnd()) {
 			r.readListStart();
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactManagerImpl.java
index c840321365c62b5617479e9e8e9c547d06a486f0..25e0681c963778bf649bef07e801a2a06474314a 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactManagerImpl.java
@@ -34,8 +34,8 @@ class ContactManagerImpl implements ContactManager {
 	ContactManagerImpl(DatabaseComponent db, KeyManager keyManager) {
 		this.db = db;
 		this.keyManager = keyManager;
-		addHooks = new CopyOnWriteArrayList<AddContactHook>();
-		removeHooks = new CopyOnWriteArrayList<RemoveContactHook>();
+		addHooks = new CopyOnWriteArrayList<>();
+		removeHooks = new CopyOnWriteArrayList<>();
 	}
 
 	@Override
@@ -125,7 +125,7 @@ class ContactManagerImpl implements ContactManager {
 		} finally {
 			db.endTransaction(txn);
 		}
-		List<Contact> active = new ArrayList<Contact>(contacts.size());
+		List<Contact> active = new ArrayList<>(contacts.size());
 		for (Contact c : contacts) if (c.isActive()) active.add(c);
 		return active;
 	}
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java
index 6c97f1c2cd8bfb704ee942a8e66358c23ddd63e1..d2e319c263231cd73fa8bc7c0a3e13262545070d 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java
@@ -602,8 +602,8 @@ class CryptoComponentImpl implements CryptoComponent {
 
 	// Package access for testing
 	int chooseIterationCount(int targetMillis) {
-		List<Long> quickSamples = new ArrayList<Long>(PBKDF_SAMPLES);
-		List<Long> slowSamples = new ArrayList<Long>(PBKDF_SAMPLES);
+		List<Long> quickSamples = new ArrayList<>(PBKDF_SAMPLES);
+		List<Long> slowSamples = new ArrayList<>(PBKDF_SAMPLES);
 		long iterationNanos = 0, initNanos = 0;
 		while (iterationNanos <= 0 || initNanos <= 0) {
 			// Sample the running time with one iteration and two iterations
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoModule.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoModule.java
index 5ab4becce5b58fba195864c63654b2d5d2043b8d..37c37abf3ee2ad5d7fa3b22edbb323f91b6f2629 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoModule.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoModule.java
@@ -48,7 +48,7 @@ public class CryptoModule {
 
 	public CryptoModule() {
 		// Use an unbounded queue
-		BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
+		BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
 		// Discard tasks that are submitted during shutdown
 		RejectedExecutionHandler policy =
 				new ThreadPoolExecutor.DiscardPolicy();
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/PasswordStrengthEstimatorImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/PasswordStrengthEstimatorImpl.java
index 67f745239b61fee6566f9b2aeeff6a6882ad9571..04c52ac9fbddaea68ced5313c185933d35fe78f6 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/crypto/PasswordStrengthEstimatorImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/PasswordStrengthEstimatorImpl.java
@@ -16,7 +16,7 @@ class PasswordStrengthEstimatorImpl implements PasswordStrengthEstimator {
 
 	@Override
 	public float estimateStrength(String password) {
-		HashSet<Character> unique = new HashSet<Character>();
+		HashSet<Character> unique = new HashSet<>();
 		int length = password.length();
 		for (int i = 0; i < length; i++) unique.add(password.charAt(i));
 		return Math.min(1, (float) unique.size() / STRONG_UNIQUE_CHARS);
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java
index 8665c8675a2ef053427ea4491fe4cf8c250a538c..e02e9a7ab9bc8c106fb18c3db1b336ab10abb3c4 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java
@@ -103,15 +103,11 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
 
 	@Override
 	public boolean open() throws DbException {
-		Runnable shutdownHook = new Runnable() {
-			@Override
-			public void run() {
-				try {
-					close();
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		Runnable shutdownHook = () -> {
+			try {
+				close();
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		};
 		boolean reopened = db.open();
@@ -141,11 +137,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
 		}
 		try {
 			return new Transaction(db.startTransaction(), readOnly);
-		} catch (DbException e) {
-			if (readOnly) lock.readLock().unlock();
-			else lock.writeLock().unlock();
-			throw e;
-		} catch (RuntimeException e) {
+		} catch (DbException | RuntimeException e) {
 			if (readOnly) lock.readLock().unlock();
 			else lock.writeLock().unlock();
 			throw e;
@@ -331,7 +323,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
 		if (!db.containsContact(txn, c))
 			throw new NoSuchContactException();
 		Collection<MessageId> ids = db.getMessagesToSend(txn, c, maxLength);
-		List<byte[]> messages = new ArrayList<byte[]>(ids.size());
+		List<byte[]> messages = new ArrayList<>(ids.size());
 		for (MessageId m : ids) {
 			messages.add(db.getRawMessage(txn, m));
 			db.updateExpiryTime(txn, c, m, maxLatency);
@@ -381,7 +373,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
 			throw new NoSuchContactException();
 		Collection<MessageId> ids = db.getRequestedMessagesToSend(txn, c,
 				maxLength);
-		List<byte[]> messages = new ArrayList<byte[]>(ids.size());
+		List<byte[]> messages = new ArrayList<>(ids.size());
 		for (MessageId m : ids) {
 			messages.add(db.getRawMessage(txn, m));
 			db.updateExpiryTime(txn, c, m, maxLatency);
@@ -661,7 +653,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
 		T txn = unbox(transaction);
 		if (!db.containsContact(txn, c))
 			throw new NoSuchContactException();
-		Collection<MessageId> acked = new ArrayList<MessageId>();
+		Collection<MessageId> acked = new ArrayList<>();
 		for (MessageId m : a.getMessageIds()) {
 			if (db.containsVisibleMessage(txn, c, m)) {
 				db.raiseSeenFlag(txn, c, m);
@@ -896,8 +888,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
 			Map<ContactId, TransportKeys> keys) throws DbException {
 		if (transaction.isReadOnly()) throw new IllegalArgumentException();
 		T txn = unbox(transaction);
-		Map<ContactId, TransportKeys> filtered =
-				new HashMap<ContactId, TransportKeys>();
+		Map<ContactId, TransportKeys> filtered = new HashMap<>();
 		for (Entry<ContactId, TransportKeys> e : keys.entrySet()) {
 			ContactId c = e.getKey();
 			TransportKeys k = e.getValue();
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseExecutorModule.java b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseExecutorModule.java
index 4c11098ffb5e5c3391fafb314a060cfbdc162a56..a65feef89da60c3f967fb891906ee1a13c14a3d8 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseExecutorModule.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseExecutorModule.java
@@ -32,7 +32,7 @@ public class DatabaseExecutorModule {
 
 	public DatabaseExecutorModule() {
 		// Use an unbounded queue
-		BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
+		BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
 		// Discard tasks that are submitted during shutdown
 		RejectedExecutionHandler policy =
 				new ThreadPoolExecutor.DiscardPolicy();
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseModule.java b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseModule.java
index a6f3a117487b9ea42c43913b27e8861c46664015..24922528d9328e96a2011d52a68d65e366ffc326 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseModule.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseModule.java
@@ -26,7 +26,7 @@ public class DatabaseModule {
 	@Singleton
 	DatabaseComponent provideDatabaseComponent(Database<Connection> db,
 			EventBus eventBus, ShutdownManager shutdown) {
-		return new DatabaseComponentImpl<Connection>(db, Connection.class,
-				eventBus, shutdown);
+		return new DatabaseComponentImpl<>(db, Connection.class, eventBus,
+				shutdown);
 	}
 }
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java b/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java
index 48afdb38a5731ca36e1770d9c045d4b15267968f..8b8c3562af85c0b92dce12b71056bc93198f0c82 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java
@@ -263,8 +263,8 @@ abstract class JdbcDatabase implements Database<Connection> {
 	private final String hashType, binaryType, counterType, secretType;
 	private final Clock clock;
 
-	private final LinkedList<Connection> connections =
-			new LinkedList<Connection>(); // Locking: connectionsLock
+	// Locking: connectionsLock
+	private final LinkedList<Connection> connections = new LinkedList<>();
 
 	private int openConnections = 0; // Locking: connectionsLock
 	private boolean closed = false; // Locking: connectionsLock
@@ -1035,7 +1035,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 					+ " FROM contacts";
 			ps = txn.prepareStatement(sql);
 			rs = ps.executeQuery();
-			List<Contact> contacts = new ArrayList<Contact>();
+			List<Contact> contacts = new ArrayList<>();
 			while (rs.next()) {
 				ContactId contactId = new ContactId(rs.getInt(1));
 				AuthorId authorId = new AuthorId(rs.getBytes(2));
@@ -1069,7 +1069,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps = txn.prepareStatement(sql);
 			ps.setBytes(1, local.getBytes());
 			rs = ps.executeQuery();
-			List<ContactId> ids = new ArrayList<ContactId>();
+			List<ContactId> ids = new ArrayList<>();
 			while (rs.next()) ids.add(new ContactId(rs.getInt(1)));
 			rs.close();
 			ps.close();
@@ -1094,7 +1094,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps = txn.prepareStatement(sql);
 			ps.setBytes(1, remote.getBytes());
 			rs = ps.executeQuery();
-			List<Contact> contacts = new ArrayList<Contact>();
+			List<Contact> contacts = new ArrayList<>();
 			while (rs.next()) {
 				ContactId c = new ContactId(rs.getInt(1));
 				String name = rs.getString(2);
@@ -1150,7 +1150,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps = txn.prepareStatement(sql);
 			ps.setString(1, c.getString());
 			rs = ps.executeQuery();
-			List<Group> groups = new ArrayList<Group>();
+			List<Group> groups = new ArrayList<>();
 			while (rs.next()) {
 				GroupId id = new GroupId(rs.getBytes(1));
 				byte[] descriptor = rs.getBytes(2);
@@ -1203,7 +1203,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps = txn.prepareStatement(sql);
 			ps.setBytes(1, g.getBytes());
 			rs = ps.executeQuery();
-			List<ContactId> visible = new ArrayList<ContactId>();
+			List<ContactId> visible = new ArrayList<>();
 			while (rs.next()) visible.add(new ContactId(rs.getInt(1)));
 			rs.close();
 			ps.close();
@@ -1255,7 +1255,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 					+ " FROM localAuthors";
 			ps = txn.prepareStatement(sql);
 			rs = ps.executeQuery();
-			List<LocalAuthor> authors = new ArrayList<LocalAuthor>();
+			List<LocalAuthor> authors = new ArrayList<>();
 			while (rs.next()) {
 				AuthorId authorId = new AuthorId(rs.getBytes(1));
 				String name = rs.getString(2);
@@ -1285,7 +1285,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps = txn.prepareStatement(sql);
 			ps.setBytes(1, g.getBytes());
 			rs = ps.executeQuery();
-			List<MessageId> ids = new ArrayList<MessageId>();
+			List<MessageId> ids = new ArrayList<>();
 			while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
 			rs.close();
 			ps.close();
@@ -1308,7 +1308,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps.setInt(1, state.getValue());
 			ps.setBytes(2, g.getBytes());
 			rs = ps.executeQuery();
-			List<MessageId> ids = new ArrayList<MessageId>();
+			List<MessageId> ids = new ArrayList<>();
 			while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
 			rs.close();
 			ps.close();
@@ -1343,7 +1343,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 				ps.setString(3, e.getKey());
 				ps.setBytes(4, e.getValue());
 				rs = ps.executeQuery();
-				Set<MessageId> ids = new HashSet<MessageId>();
+				Set<MessageId> ids = new HashSet<>();
 				while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
 				rs.close();
 				ps.close();
@@ -1377,7 +1377,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps.setInt(1, DELIVERED.getValue());
 			ps.setBytes(2, g.getBytes());
 			rs = ps.executeQuery();
-			Map<MessageId, Metadata> all = new HashMap<MessageId, Metadata>();
+			Map<MessageId, Metadata> all = new HashMap<>();
 			Metadata metadata = null;
 			MessageId lastMessageId = null;
 			while (rs.next()) {
@@ -1406,8 +1406,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 		Collection<MessageId> matches = getMessageIds(txn, g, query);
 		if (matches.isEmpty()) return Collections.emptyMap();
 		// Retrieve the metadata for each match
-		Map<MessageId, Metadata> all = new HashMap<MessageId, Metadata>(
-				matches.size());
+		Map<MessageId, Metadata> all = new HashMap<>(matches.size());
 		for (MessageId m : matches) all.put(m, getMessageMetadata(txn, m));
 		return all;
 	}
@@ -1505,7 +1504,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps.setBytes(1, g.getBytes());
 			ps.setInt(2, c.getInt());
 			rs = ps.executeQuery();
-			List<MessageStatus> statuses = new ArrayList<MessageStatus>();
+			List<MessageStatus> statuses = new ArrayList<>();
 			while (rs.next()) {
 				MessageId messageId = new MessageId(rs.getBytes(1));
 				boolean sent = rs.getBoolean(2);
@@ -1564,7 +1563,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps = txn.prepareStatement(sql);
 			ps.setBytes(1, m.getBytes());
 			rs = ps.executeQuery();
-			Map<MessageId, State> dependencies = new HashMap<MessageId, State>();
+			Map<MessageId, State> dependencies = new HashMap<>();
 			while (rs.next()) {
 				MessageId dependency = new MessageId(rs.getBytes(1));
 				State state = State.fromValue(rs.getInt(2));
@@ -1602,7 +1601,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps = txn.prepareStatement(sql);
 			ps.setBytes(1, m.getBytes());
 			rs = ps.executeQuery();
-			Map<MessageId, State> dependents = new HashMap<MessageId, State>();
+			Map<MessageId, State> dependents = new HashMap<>();
 			while (rs.next()) {
 				MessageId dependent = new MessageId(rs.getBytes(1));
 				State state = State.fromValue(rs.getInt(2));
@@ -1654,7 +1653,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps.setInt(1, c.getInt());
 			ps.setInt(2, maxMessages);
 			rs = ps.executeQuery();
-			List<MessageId> ids = new ArrayList<MessageId>();
+			List<MessageId> ids = new ArrayList<>();
 			while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
 			rs.close();
 			ps.close();
@@ -1690,7 +1689,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps.setLong(3, now);
 			ps.setInt(4, maxMessages);
 			rs = ps.executeQuery();
-			List<MessageId> ids = new ArrayList<MessageId>();
+			List<MessageId> ids = new ArrayList<>();
 			while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
 			rs.close();
 			ps.close();
@@ -1715,7 +1714,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps.setInt(1, c.getInt());
 			ps.setInt(2, maxMessages);
 			rs = ps.executeQuery();
-			List<MessageId> ids = new ArrayList<MessageId>();
+			List<MessageId> ids = new ArrayList<>();
 			while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
 			rs.close();
 			ps.close();
@@ -1750,7 +1749,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps.setInt(2, DELIVERED.getValue());
 			ps.setLong(3, now);
 			rs = ps.executeQuery();
-			List<MessageId> ids = new ArrayList<MessageId>();
+			List<MessageId> ids = new ArrayList<>();
 			int total = 0;
 			while (rs.next()) {
 				int length = rs.getInt(1);
@@ -1792,7 +1791,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps.setInt(1, state.getValue());
 			ps.setString(2, c.getString());
 			rs = ps.executeQuery();
-			List<MessageId> ids = new ArrayList<MessageId>();
+			List<MessageId> ids = new ArrayList<>();
 			while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
 			rs.close();
 			ps.close();
@@ -1822,7 +1821,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps = txn.prepareStatement(sql);
 			ps.setString(1, c.getString());
 			rs = ps.executeQuery();
-			List<MessageId> ids = new ArrayList<MessageId>();
+			List<MessageId> ids = new ArrayList<>();
 			while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
 			rs.close();
 			ps.close();
@@ -1881,7 +1880,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps.setInt(2, DELIVERED.getValue());
 			ps.setLong(3, now);
 			rs = ps.executeQuery();
-			List<MessageId> ids = new ArrayList<MessageId>();
+			List<MessageId> ids = new ArrayList<>();
 			int total = 0;
 			while (rs.next()) {
 				int length = rs.getInt(1);
@@ -1935,7 +1934,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps = txn.prepareStatement(sql);
 			ps.setString(1, t.getString());
 			rs = ps.executeQuery();
-			List<IncomingKeys> inKeys = new ArrayList<IncomingKeys>();
+			List<IncomingKeys> inKeys = new ArrayList<>();
 			while (rs.next()) {
 				long rotationPeriod = rs.getLong(1);
 				SecretKey tagKey = new SecretKey(rs.getBytes(2));
@@ -1955,8 +1954,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			ps = txn.prepareStatement(sql);
 			ps.setString(1, t.getString());
 			rs = ps.executeQuery();
-			Map<ContactId, TransportKeys> keys =
-					new HashMap<ContactId, TransportKeys>();
+			Map<ContactId, TransportKeys> keys = new HashMap<>();
 			for (int i = 0; rs.next(); i++) {
 				// There should be three times as many incoming keys
 				if (inKeys.size() < (i + 1) * 3) throw new DbStateException();
@@ -2074,8 +2072,8 @@ abstract class JdbcDatabase implements Database<Connection> {
 		PreparedStatement ps = null;
 		try {
 			// Determine which keys are being removed
-			List<String> removed = new ArrayList<String>();
-			Map<String, byte[]> retained = new HashMap<String, byte[]>();
+			List<String> removed = new ArrayList<>();
+			Map<String, byte[]> retained = new HashMap<>();
 			for (Entry<String, byte[]> e : meta.entrySet()) {
 				if (e.getValue() == REMOVE) removed.add(e.getKey());
 				else retained.put(e.getKey(), e.getValue());
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/event/EventBusImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/event/EventBusImpl.java
index f2b346847510c62b510397068319c33a8947364b..b08493cd09647c0a44fdb85e423eb0b921ff9c91 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/event/EventBusImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/event/EventBusImpl.java
@@ -15,7 +15,7 @@ import javax.annotation.concurrent.ThreadSafe;
 class EventBusImpl implements EventBus {
 
 	private final Collection<EventListener> listeners =
-			new CopyOnWriteArrayList<EventListener>();
+			new CopyOnWriteArrayList<>();
 
 	@Override
 	public void addListener(EventListener l) {
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementConnector.java b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementConnector.java
index df6d28fa491d1c3d58613477e318b4e8f70ab1e2..992cb006b1daa923e021326066208b87fab7b966 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementConnector.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementConnector.java
@@ -50,10 +50,9 @@ class KeyAgreementConnector {
 	private final PluginManager pluginManager;
 	private final CompletionService<KeyAgreementConnection> connect;
 
-	private final List<KeyAgreementListener> listeners =
-			new ArrayList<KeyAgreementListener>();
+	private final List<KeyAgreementListener> listeners = new ArrayList<>();
 	private final List<Future<KeyAgreementConnection>> pending =
-			new ArrayList<Future<KeyAgreementConnection>>();
+			new ArrayList<>();
 
 	private volatile boolean connecting = false;
 	private volatile boolean alice = false;
@@ -65,8 +64,7 @@ class KeyAgreementConnector {
 		this.clock = clock;
 		this.crypto = crypto;
 		this.pluginManager = pluginManager;
-		connect = new ExecutorCompletionService<KeyAgreementConnection>(
-				ioExecutor);
+		connect = new ExecutorCompletionService<>(ioExecutor);
 	}
 
 	public Payload listen(KeyPair localKeyPair) {
@@ -75,8 +73,7 @@ class KeyAgreementConnector {
 		byte[] commitment = crypto.deriveKeyCommitment(
 				localKeyPair.getPublic().getEncoded());
 		// Start all listeners and collect their descriptors
-		List<TransportDescriptor> descriptors =
-				new ArrayList<TransportDescriptor>();
+		List<TransportDescriptor> descriptors = new ArrayList<>();
 		for (DuplexPlugin plugin : pluginManager.getKeyAgreementPlugins()) {
 			KeyAgreementListener l =
 					plugin.createKeyAgreementListener(commitment);
@@ -132,10 +129,7 @@ class KeyAgreementConnector {
 			LOG.info("Interrupted while waiting for connection");
 			Thread.currentThread().interrupt();
 			return null;
-		} catch (ExecutionException e) {
-			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-			return null;
-		} catch (IOException e) {
+		} catch (ExecutionException | IOException e) {
 			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			return null;
 		} finally {
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/PayloadParserImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/PayloadParserImpl.java
index 5b4df07c4846592d3effe6a831a5b0cd955cc137..ecf519e09e5c9827a9dcc8a4c5be24ad895c68b2 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/PayloadParserImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/PayloadParserImpl.java
@@ -51,8 +51,7 @@ class PayloadParserImpl implements PayloadParser {
 		byte[] commitment = payload.getRaw(1);
 		if (commitment.length != COMMIT_LENGTH) throw new FormatException();
 		// Remaining elements: transport descriptors
-		List<TransportDescriptor> recognised =
-				new ArrayList<TransportDescriptor>();
+		List<TransportDescriptor> recognised = new ArrayList<>();
 		for (int i = 2; i < payload.size(); i++) {
 			BdfList descriptor = payload.getList(i);
 			long transportId = descriptor.getLong(0);
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleManagerImpl.java
index da3536bebd9f47a09567098c2ab371dcb0f77372..7be465d990661b827f86b2b40723ebe45e2972c2 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleManagerImpl.java
@@ -63,9 +63,9 @@ class LifecycleManagerImpl implements LifecycleManager {
 		this.crypto = crypto;
 		this.authorFactory = authorFactory;
 		this.identityManager = identityManager;
-		services = new CopyOnWriteArrayList<Service>();
-		clients = new CopyOnWriteArrayList<Client>();
-		executors = new CopyOnWriteArrayList<ExecutorService>();
+		services = new CopyOnWriteArrayList<>();
+		clients = new CopyOnWriteArrayList<>();
+		executors = new CopyOnWriteArrayList<>();
 	}
 
 	@Override
@@ -88,7 +88,7 @@ class LifecycleManagerImpl implements LifecycleManager {
 		executors.add(e);
 	}
 
-	private LocalAuthor createLocalAuthor(final String nickname) {
+	private LocalAuthor createLocalAuthor(String nickname) {
 		long now = System.currentTimeMillis();
 		KeyPair keyPair = crypto.generateSignatureKeyPair();
 		byte[] publicKey = keyPair.getPublic().getEncoded();
@@ -203,9 +203,7 @@ class LifecycleManagerImpl implements LifecycleManager {
 			if (LOG.isLoggable(INFO))
 				LOG.info("Closing database took " + duration + " ms");
 			shutdownLatch.countDown();
-		} catch (DbException e) {
-			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-		} catch (ServiceException e) {
+		} catch (DbException | ServiceException e) {
 			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 		} finally {
 			startStopSemaphore.release();
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleModule.java b/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleModule.java
index 2db43072355f8c4f7d367b2162d7069dada031c8..8fcf789ed91d725b1dbb14ae2493324f785ca7d6 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleModule.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleModule.java
@@ -37,7 +37,7 @@ public class LifecycleModule {
 
 	public LifecycleModule() {
 		// The thread pool is unbounded, so use direct handoff
-		BlockingQueue<Runnable> queue = new SynchronousQueue<Runnable>();
+		BlockingQueue<Runnable> queue = new SynchronousQueue<>();
 		// Discard tasks that are submitted during shutdown
 		RejectedExecutionHandler policy =
 				new ThreadPoolExecutor.DiscardPolicy();
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/ShutdownManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/ShutdownManagerImpl.java
index 1b5e4ad6aa24e90da2bde02f5bf95ada8da6604e..f5f422c4a651e1963938d44ff45e17a4f6abb133 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/ShutdownManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/ShutdownManagerImpl.java
@@ -21,7 +21,7 @@ class ShutdownManagerImpl implements ShutdownManager {
 	private int nextHandle = 0;
 
 	ShutdownManagerImpl() {
-		hooks = new HashMap<Integer, Thread>();
+		hooks = new HashMap<>();
 	}
 
 	@Override
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionManagerImpl.java
index 3714e420ff54b984772a1d69a14f651a573c4cab..071068ab5cff4e99cb6df455ce202c5c9a3e2fef 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionManagerImpl.java
@@ -134,11 +134,7 @@ class ConnectionManagerImpl implements ConnectionManager {
 			try {
 				byte[] tag = readTag(reader);
 				ctx = keyManager.getStreamContext(transportId, tag);
-			} catch (IOException e) {
-				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-				disposeReader(true, false);
-				return;
-			} catch (DbException e) {
+			} catch (IOException | DbException e) {
 				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 				disposeReader(true, false);
 				return;
@@ -249,11 +245,7 @@ class ConnectionManagerImpl implements ConnectionManager {
 			try {
 				byte[] tag = readTag(reader);
 				ctx = keyManager.getStreamContext(transportId, tag);
-			} catch (IOException e) {
-				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-				disposeReader(true, false);
-				return;
-			} catch (DbException e) {
+			} catch (IOException | DbException e) {
 				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 				disposeReader(true, false);
 				return;
@@ -266,12 +258,7 @@ class ConnectionManagerImpl implements ConnectionManager {
 			contactId = ctx.getContactId();
 			connectionRegistry.registerConnection(contactId, transportId, true);
 			// Start the outgoing session on another thread
-			ioExecutor.execute(new Runnable() {
-				@Override
-				public void run() {
-					runOutgoingSession();
-				}
-			});
+			ioExecutor.execute(this::runOutgoingSession);
 			try {
 				// Create and run the incoming session
 				incomingSession = createIncomingSession(ctx, reader);
@@ -368,12 +355,7 @@ class ConnectionManagerImpl implements ConnectionManager {
 				return;
 			}
 			// Start the incoming session on another thread
-			ioExecutor.execute(new Runnable() {
-				@Override
-				public void run() {
-					runIncomingSession();
-				}
-			});
+			ioExecutor.execute(this::runIncomingSession);
 			try {
 				// Create and run the outgoing session
 				outgoingSession = createDuplexOutgoingSession(ctx, writer);
@@ -391,11 +373,7 @@ class ConnectionManagerImpl implements ConnectionManager {
 			try {
 				byte[] tag = readTag(reader);
 				ctx = keyManager.getStreamContext(transportId, tag);
-			} catch (IOException e) {
-				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-				disposeReader(true, false);
-				return;
-			} catch (DbException e) {
+			} catch (IOException | DbException e) {
 				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 				disposeReader(true, false);
 				return;
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionRegistryImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionRegistryImpl.java
index 5c4b5d4221fd6c2b0bad082f753a09620f64709a..780e46a6e3185646db974c6ee3982458d959188d 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionRegistryImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionRegistryImpl.java
@@ -42,8 +42,8 @@ class ConnectionRegistryImpl implements ConnectionRegistry {
 	@Inject
 	ConnectionRegistryImpl(EventBus eventBus) {
 		this.eventBus = eventBus;
-		connections = new HashMap<TransportId, Map<ContactId, Integer>>();
-		contactCounts = new HashMap<ContactId, Integer>();
+		connections = new HashMap<>();
+		contactCounts = new HashMap<>();
 	}
 
 	@Override
@@ -58,7 +58,7 @@ class ConnectionRegistryImpl implements ConnectionRegistry {
 		try {
 			Map<ContactId, Integer> m = connections.get(t);
 			if (m == null) {
-				m = new HashMap<ContactId, Integer>();
+				m = new HashMap<>();
 				connections.put(t, m);
 			}
 			Integer count = m.get(c);
@@ -124,7 +124,7 @@ class ConnectionRegistryImpl implements ConnectionRegistry {
 		try {
 			Map<ContactId, Integer> m = connections.get(t);
 			if (m == null) return Collections.emptyList();
-			List<ContactId> ids = new ArrayList<ContactId>(m.keySet());
+			List<ContactId> ids = new ArrayList<>(m.keySet());
 			if (LOG.isLoggable(INFO))
 				LOG.info(ids.size() + " contacts connected");
 			return ids;
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java
index 60c6d61cd8913f4c00433c312d126c8afb2dc7cb..7e05f5b347506d568a2d78cdc5527ac2e52b2f7a 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java
@@ -82,10 +82,10 @@ class PluginManagerImpl implements PluginManager, Service {
 		this.settingsManager = settingsManager;
 		this.transportPropertyManager = transportPropertyManager;
 		this.uiCallback = uiCallback;
-		plugins = new ConcurrentHashMap<TransportId, Plugin>();
-		simplexPlugins = new CopyOnWriteArrayList<SimplexPlugin>();
-		duplexPlugins = new CopyOnWriteArrayList<DuplexPlugin>();
-		startLatches = new ConcurrentHashMap<TransportId, CountDownLatch>();
+		plugins = new ConcurrentHashMap<>();
+		simplexPlugins = new CopyOnWriteArrayList<>();
+		duplexPlugins = new CopyOnWriteArrayList<>();
+		startLatches = new ConcurrentHashMap<>();
 	}
 
 	@Override
@@ -156,17 +156,17 @@ class PluginManagerImpl implements PluginManager, Service {
 
 	@Override
 	public Collection<SimplexPlugin> getSimplexPlugins() {
-		return new ArrayList<SimplexPlugin>(simplexPlugins);
+		return new ArrayList<>(simplexPlugins);
 	}
 
 	@Override
 	public Collection<DuplexPlugin> getDuplexPlugins() {
-		return new ArrayList<DuplexPlugin>(duplexPlugins);
+		return new ArrayList<>(duplexPlugins);
 	}
 
 	@Override
 	public Collection<DuplexPlugin> getKeyAgreementPlugins() {
-		List<DuplexPlugin> supported = new ArrayList<DuplexPlugin>();
+		List<DuplexPlugin> supported = new ArrayList<>();
 		for (DuplexPlugin d : duplexPlugins)
 			if (d.supportsKeyAgreement()) supported.add(d);
 		return supported;
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/Poller.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/Poller.java
index f315bda9e8631bfd112d0a45ce54261b956bdcbc..2405c0be83375ca5e815c853893033f08e4e4ca0 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/Poller.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/Poller.java
@@ -66,7 +66,7 @@ class Poller implements EventListener {
 		this.random = random;
 		this.clock = clock;
 		lock = new ReentrantLock();
-		tasks = new HashMap<TransportId, PollTask>();
+		tasks = new HashMap<>();
 	}
 
 	@Override
@@ -111,30 +111,24 @@ class Poller implements EventListener {
 			connectToContact(c, (DuplexPlugin) p);
 	}
 
-	private void connectToContact(final ContactId c, final SimplexPlugin p) {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				TransportId t = p.getId();
-				if (!connectionRegistry.isConnected(c, t)) {
-					TransportConnectionWriter w = p.createWriter(c);
-					if (w != null)
-						connectionManager.manageOutgoingConnection(c, t, w);
-				}
+	private void connectToContact(ContactId c, SimplexPlugin p) {
+		ioExecutor.execute(() -> {
+			TransportId t = p.getId();
+			if (!connectionRegistry.isConnected(c, t)) {
+				TransportConnectionWriter w = p.createWriter(c);
+				if (w != null)
+					connectionManager.manageOutgoingConnection(c, t, w);
 			}
 		});
 	}
 
-	private void connectToContact(final ContactId c, final DuplexPlugin p) {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				TransportId t = p.getId();
-				if (!connectionRegistry.isConnected(c, t)) {
-					DuplexTransportConnection d = p.createConnection(c);
-					if (d != null)
-						connectionManager.manageOutgoingConnection(c, t, d);
-				}
+	private void connectToContact(ContactId c, DuplexPlugin p) {
+		ioExecutor.execute(() -> {
+			TransportId t = p.getId();
+			if (!connectionRegistry.isConnected(c, t)) {
+				DuplexTransportConnection d = p.createConnection(c);
+				if (d != null)
+					connectionManager.manageOutgoingConnection(c, t, d);
 			}
 		});
 	}
@@ -159,14 +153,10 @@ class Poller implements EventListener {
 		try {
 			PollTask scheduled = tasks.get(t);
 			if (scheduled == null || due < scheduled.due) {
-				final PollTask task = new PollTask(p, due, randomiseNext);
+				PollTask task = new PollTask(p, due, randomiseNext);
 				tasks.put(t, task);
-				scheduler.schedule(new Runnable() {
-					@Override
-					public void run() {
-						ioExecutor.execute(task);
-					}
-				}, delay, MILLISECONDS);
+				scheduler.schedule(
+						() -> ioExecutor.execute(task), delay, MILLISECONDS);
 			}
 		} finally {
 			lock.unlock();
@@ -174,7 +164,7 @@ class Poller implements EventListener {
 	}
 
 	@IoExecutor
-	private void poll(final Plugin p) {
+	private void poll(Plugin p) {
 		TransportId t = p.getId();
 		if (LOG.isLoggable(INFO)) LOG.info("Polling plugin " + t);
 		p.poll(connectionRegistry.getConnectedContacts(t));
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/FilePlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/FilePlugin.java
index 17b61358d20bd4b0d1cdbb9bf39244e882923ced..6355342e6545d5ca43a1b5e4625b53151fe79d17 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/FilePlugin.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/FilePlugin.java
@@ -108,7 +108,7 @@ abstract class FilePlugin implements SimplexPlugin {
 		}
 	}
 
-	protected void createReaderFromFile(final File f) {
+	protected void createReaderFromFile(File f) {
 		if (!running) return;
 		ioExecutor.execute(new ReaderCreator(f));
 	}
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java
index dc07b5686bcab87988c40162eac8db2f9155f57a..7d26b8e5e06999e1b7b48561e1f039dd9e4a3991 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java
@@ -63,7 +63,7 @@ class LanTcpPlugin extends TcpPlugin {
 		TransportProperties p = callback.getLocalProperties();
 		String oldIpPorts = p.get(PROP_IP_PORTS);
 		List<InetSocketAddress> olds = parseSocketAddresses(oldIpPorts);
-		List<InetSocketAddress> locals = new LinkedList<InetSocketAddress>();
+		List<InetSocketAddress> locals = new LinkedList<>();
 		for (InetAddress local : getLocalIpAddresses()) {
 			if (isAcceptableAddress(local)) {
 				// If this is the old address, try to use the same port
@@ -82,7 +82,7 @@ class LanTcpPlugin extends TcpPlugin {
 	private List<InetSocketAddress> parseSocketAddresses(String ipPorts) {
 		if (StringUtils.isNullOrEmpty(ipPorts)) return Collections.emptyList();
 		String[] split = ipPorts.split(SEPARATOR);
-		List<InetSocketAddress> addresses = new ArrayList<InetSocketAddress>();
+		List<InetSocketAddress> addresses = new ArrayList<>();
 		for (String ipPort : split) {
 			InetSocketAddress a = parseSocketAddress(ipPort);
 			if (a != null) addresses.add(a);
@@ -95,7 +95,7 @@ class LanTcpPlugin extends TcpPlugin {
 		String ipPort = getIpPortString(a);
 		// Get the list of recently used addresses
 		String setting = callback.getSettings().get(PREF_LAN_IP_PORTS);
-		List<String> recent = new ArrayList<String>();
+		List<String> recent = new ArrayList<>();
 		if (!StringUtils.isNullOrEmpty(setting))
 			Collections.addAll(recent, setting.split(SEPARATOR));
 		// Is the address already in the list?
@@ -111,7 +111,7 @@ class LanTcpPlugin extends TcpPlugin {
 				recent = recent.subList(0, MAX_ADDRESSES);
 			setting = StringUtils.join(recent, SEPARATOR);
 			// Update the list of addresses shared with contacts
-			List<String> shared = new ArrayList<String>(recent);
+			List<String> shared = new ArrayList<>(recent);
 			Collections.sort(shared);
 			String property = StringUtils.join(shared, SEPARATOR);
 			TransportProperties properties = new TransportProperties();
@@ -260,16 +260,12 @@ class LanTcpPlugin extends TcpPlugin {
 
 		@Override
 		public Callable<KeyAgreementConnection> listen() {
-			return new Callable<KeyAgreementConnection>() {
-				@Override
-				public KeyAgreementConnection call() throws IOException {
-					Socket s = ss.accept();
-					if (LOG.isLoggable(INFO))
-						LOG.info(ID.getString() + ": Incoming connection");
-					return new KeyAgreementConnection(
-							new TcpTransportConnection(LanTcpPlugin.this, s),
-							ID);
-				}
+			return () -> {
+				Socket s = ss.accept();
+				if (LOG.isLoggable(INFO))
+					LOG.info(ID.getString() + ": Incoming connection");
+				return new KeyAgreementConnection(
+						new TcpTransportConnection(LanTcpPlugin.this, s), ID);
 			};
 		}
 
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/PortMapperImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/PortMapperImpl.java
index 2156bd10d12ee90445e96f0e220b2b9a1f05fce8..e40d531bdbe7107ec6a02cae767da510ee4af990 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/PortMapperImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/PortMapperImpl.java
@@ -37,7 +37,7 @@ class PortMapperImpl implements PortMapper {
 	}
 
 	@Override
-	public MappingResult map(final int port) {
+	public MappingResult map(int port) {
 		if (!started.getAndSet(true)) start();
 		if (gateway == null) return null;
 		InetAddress internal = gateway.getLocalAddress();
@@ -50,12 +50,7 @@ class PortMapperImpl implements PortMapper {
 			succeeded = gateway.addPortMapping(port, port,
 					getHostAddress(internal), "TCP", "TCP");
 			if (succeeded) {
-				shutdownManager.addShutdownHook(new Runnable() {
-					@Override
-					public void run() {
-						deleteMapping(port);
-					}
-				});
+				shutdownManager.addShutdownHook(() -> deleteMapping(port));
 			}
 			String externalString = gateway.getExternalIPAddress();
 			if (LOG.isLoggable(INFO))
@@ -63,9 +58,7 @@ class PortMapperImpl implements PortMapper {
 						"External address " + scrubInetAddress(externalString));
 			if (externalString != null)
 				external = InetAddress.getByName(externalString);
-		} catch (IOException e) {
-			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-		} catch (SAXException e) {
+		} catch (IOException | SAXException e) {
 			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 		}
 		return new MappingResult(internal, external, port, succeeded);
@@ -82,11 +75,7 @@ class PortMapperImpl implements PortMapper {
 		GatewayDiscover d = new GatewayDiscover();
 		try {
 			d.discover();
-		} catch (IOException e) {
-			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-		} catch (SAXException e) {
-			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-		} catch (ParserConfigurationException e) {
+		} catch (IOException | SAXException | ParserConfigurationException e) {
 			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 		}
 		gateway = d.getValidGateway();
@@ -97,9 +86,7 @@ class PortMapperImpl implements PortMapper {
 			gateway.deletePortMapping(port, "TCP");
 			if (LOG.isLoggable(INFO))
 				LOG.info("Deleted mapping for port " + port);
-		} catch (IOException e) {
-			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-		} catch (SAXException e) {
+		} catch (IOException | SAXException e) {
 			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 		}
 	}
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java
index baa523d4ba4cba20b8bda5c31eadc4e31e9ae92b..af6922793ce3103f1fb0dd0359f986aeebec02bb 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java
@@ -110,41 +110,37 @@ abstract class TcpPlugin implements DuplexPlugin {
 	}
 
 	protected void bind() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				if (!running) return;
-				ServerSocket ss = null;
-				for (InetSocketAddress addr : getLocalSocketAddresses()) {
-					try {
-						ss = new ServerSocket();
-						ss.bind(addr);
-						break;
-					} catch (IOException e) {
-						if (LOG.isLoggable(INFO))
-							LOG.info("Failed to bind " +
-									scrubSocketAddress(addr));
-						tryToClose(ss);
-					}
-				}
-				if (ss == null || !ss.isBound()) {
-					LOG.info("Could not bind server socket");
-					return;
-				}
-				if (!running) {
+		ioExecutor.execute(() -> {
+			if (!running) return;
+			ServerSocket ss = null;
+			for (InetSocketAddress addr : getLocalSocketAddresses()) {
+				try {
+					ss = new ServerSocket();
+					ss.bind(addr);
+					break;
+				} catch (IOException e) {
+					if (LOG.isLoggable(INFO))
+						LOG.info("Failed to bind " + scrubSocketAddress(addr));
 					tryToClose(ss);
-					return;
 				}
-				socket = ss;
-				backoff.reset();
-				InetSocketAddress local =
-						(InetSocketAddress) ss.getLocalSocketAddress();
-				setLocalSocketAddress(local);
-				if (LOG.isLoggable(INFO))
-					LOG.info("Listening on " + scrubSocketAddress(local));
-				callback.transportEnabled();
-				acceptContactConnections();
 			}
+			if (ss == null || !ss.isBound()) {
+				LOG.info("Could not bind server socket");
+				return;
+			}
+			if (!running) {
+				tryToClose(ss);
+				return;
+			}
+			socket = ss;
+			backoff.reset();
+			InetSocketAddress local =
+					(InetSocketAddress) ss.getLocalSocketAddress();
+			setLocalSocketAddress(local);
+			if (LOG.isLoggable(INFO))
+				LOG.info("Listening on " + scrubSocketAddress(local));
+			callback.transportEnabled();
+			acceptContactConnections();
 		});
 	}
 
@@ -218,17 +214,13 @@ abstract class TcpPlugin implements DuplexPlugin {
 		}
 	}
 
-	private void connectAndCallBack(final ContactId c,
-			final TransportProperties p) {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				if (!isRunning()) return;
-				DuplexTransportConnection d = createConnection(p);
-				if (d != null) {
-					backoff.reset();
-					callback.outgoingConnectionCreated(c, d);
-				}
+	private void connectAndCallBack(ContactId c, TransportProperties p) {
+		ioExecutor.execute(() -> {
+			if (!isRunning()) return;
+			DuplexTransportConnection d = createConnection(p);
+			if (d != null) {
+				backoff.reset();
+				callback.outgoingConnectionCreated(c, d);
 			}
 		});
 	}
@@ -317,7 +309,7 @@ abstract class TcpPlugin implements DuplexPlugin {
 			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			return Collections.emptyList();
 		}
-		List<InetAddress> addrs = new ArrayList<InetAddress>();
+		List<InetAddress> addrs = new ArrayList<>();
 		for (NetworkInterface iface : ifaces)
 			addrs.addAll(Collections.list(iface.getInetAddresses()));
 		return addrs;
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/WanTcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/WanTcpPlugin.java
index 7efe41159fc1cf6d753b939282754f3bbfabc79f..8144f921ed4c74717cee3844228ec57e4e57f4ed 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/WanTcpPlugin.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/WanTcpPlugin.java
@@ -43,7 +43,7 @@ class WanTcpPlugin extends TcpPlugin {
 		// Use the same address and port as last time if available
 		TransportProperties p = callback.getLocalProperties();
 		InetSocketAddress old = parseSocketAddress(p.get(PROP_IP_PORT));
-		List<InetSocketAddress> addrs = new LinkedList<InetSocketAddress>();
+		List<InetSocketAddress> addrs = new LinkedList<>();
 		for (InetAddress a : getLocalIpAddresses()) {
 			if (isAcceptableAddress(a)) {
 				// If this is the old address, try to use the same port
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyManagerImpl.java
index d002a6b02b225fea138238654aef1c3ac1546a61..8e65b494da65a8111e130f4093732a9b04531dee 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyManagerImpl.java
@@ -144,8 +144,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
 	public Map<TransportId, TransportProperties> getLocalProperties(
 			Transaction txn) throws DbException {
 		try {
-			Map<TransportId, TransportProperties> local =
-					new HashMap<TransportId, TransportProperties>();
+			Map<TransportId, TransportProperties> local = new HashMap<>();
 			// Find the latest local update for each transport
 			Map<TransportId, LatestUpdate> latest = findLatestLocal(txn);
 			// Retrieve and parse the latest local properties
@@ -192,8 +191,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
 	@Override
 	public Map<ContactId, TransportProperties> getRemoteProperties(
 			TransportId t) throws DbException {
-		Map<ContactId, TransportProperties> remote =
-				new HashMap<ContactId, TransportProperties>();
+		Map<ContactId, TransportProperties> remote = new HashMap<>();
 		// TODO: Transaction can be read-only when code is simplified
 		Transaction txn = db.startTransaction(false);
 		try {
@@ -321,8 +319,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
 	private Map<TransportId, LatestUpdate> findLatestLocal(Transaction txn)
 			throws DbException, FormatException {
 		// TODO: This can be simplified before 1.0
-		Map<TransportId, LatestUpdate> latestUpdates =
-				new HashMap<TransportId, LatestUpdate>();
+		Map<TransportId, LatestUpdate> latestUpdates = new HashMap<>();
 		Map<MessageId, BdfDictionary> metadata = clientHelper
 				.getMessageMetadataAsDictionary(txn, localGroup.getId());
 		for (Entry<MessageId, BdfDictionary> e : metadata.entrySet()) {
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/reliability/Receiver.java b/bramble-core/src/main/java/org/briarproject/bramble/reliability/Receiver.java
index c5c5de2e28de374e68f1d1205d68ffefc4822bba..9e0b37b507f0ce313541a2fa4e6b3162a005fcea 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/reliability/Receiver.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/reliability/Receiver.java
@@ -41,7 +41,7 @@ class Receiver implements ReadHandler {
 	Receiver(Clock clock, Sender sender) {
 		this.sender = sender;
 		this.clock = clock;
-		dataFrames = new TreeSet<Data>(new SequenceNumberComparator());
+		dataFrames = new TreeSet<>(new SequenceNumberComparator());
 	}
 
 	Data read() throws IOException, InterruptedException {
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/reliability/ReliabilityLayerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/reliability/ReliabilityLayerImpl.java
index b6b60ef9d659c757cbd7cd8d6de8a85b38037012..7a26db774683ffec836afd53d3403660e80cc740 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/reliability/ReliabilityLayerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/reliability/ReliabilityLayerImpl.java
@@ -42,48 +42,44 @@ class ReliabilityLayerImpl implements ReliabilityLayer, WriteHandler {
 		this.executor = executor;
 		this.clock = clock;
 		this.writeHandler = writeHandler;
-		writes = new LinkedBlockingQueue<byte[]>();
+		writes = new LinkedBlockingQueue<>();
 	}
 
 	@Override
 	public void start() {
 		SlipEncoder encoder = new SlipEncoder(this);
-		final Sender sender = new Sender(clock, encoder);
+		Sender sender = new Sender(clock, encoder);
 		receiver = new Receiver(clock, sender);
 		decoder = new SlipDecoder(receiver, Data.MAX_LENGTH);
 		inputStream = new ReceiverInputStream(receiver);
 		outputStream = new SenderOutputStream(sender);
 		running = true;
-		executor.execute(new Runnable() {
-			@Override
-			public void run() {
-				long now = clock.currentTimeMillis();
-				long next = now + TICK_INTERVAL;
-				try {
-					while (running) {
-						byte[] b = null;
-						while (now < next && b == null) {
-							b = writes.poll(next - now, MILLISECONDS);
-							if (!running) return;
-							now = clock.currentTimeMillis();
-						}
-						if (b == null) {
-							sender.tick();
-							while (next <= now) next += TICK_INTERVAL;
-						} else {
-							if (b.length == 0) return; // Poison pill
-							writeHandler.handleWrite(b);
-						}
+		executor.execute(() -> {
+			long now = clock.currentTimeMillis();
+			long next = now + TICK_INTERVAL;
+			try {
+				while (running) {
+					byte[] b = null;
+					while (now < next && b == null) {
+						b = writes.poll(next - now, MILLISECONDS);
+						if (!running) return;
+						now = clock.currentTimeMillis();
+					}
+					if (b == null) {
+						sender.tick();
+						while (next <= now) next += TICK_INTERVAL;
+					} else {
+						if (b.length == 0) return; // Poison pill
+						writeHandler.handleWrite(b);
 					}
-				} catch (InterruptedException e) {
-					LOG.warning("Interrupted while waiting to write");
-					Thread.currentThread().interrupt();
-					running = false;
-				} catch (IOException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					running = false;
 				}
+			} catch (InterruptedException e) {
+				LOG.warning("Interrupted while waiting to write");
+				Thread.currentThread().interrupt();
+				running = false;
+			} catch (IOException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				running = false;
 			}
 		});
 	}
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/reliability/Sender.java b/bramble-core/src/main/java/org/briarproject/bramble/reliability/Sender.java
index 3062780994376cfcb633856f6820fe174ecae5a5..982055eeadb1706e047b470d3edacd9ea8043838 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/reliability/Sender.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/reliability/Sender.java
@@ -46,7 +46,7 @@ class Sender {
 	Sender(Clock clock, WriteHandler writeHandler) {
 		this.clock = clock;
 		this.writeHandler = writeHandler;
-		outstanding = new LinkedList<Outstanding>();
+		outstanding = new LinkedList<>();
 	}
 
 	void sendAck(long sequenceNumber, int windowSize) throws IOException {
@@ -136,7 +136,7 @@ class Sender {
 					if (now - o.lastTransmitted > rto) {
 						it.remove();
 						if (retransmit == null)
-							retransmit = new ArrayList<Outstanding>();
+							retransmit = new ArrayList<>();
 						retransmit.add(o);
 						// Update the retransmission timeout
 						rto <<= 1;
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/sync/DuplexOutgoingSession.java b/bramble-core/src/main/java/org/briarproject/bramble/sync/DuplexOutgoingSession.java
index 7be248c5d6d85b8d5fb3730c80f78aee7876d328..04f864d13a0ee4b369c8cf318467f8c69bafaf7c 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/sync/DuplexOutgoingSession.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/sync/DuplexOutgoingSession.java
@@ -54,12 +54,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
 	private static final Logger LOG =
 			Logger.getLogger(DuplexOutgoingSession.class.getName());
 
-	private static final ThrowingRunnable<IOException> CLOSE =
-			new ThrowingRunnable<IOException>() {
-				@Override
-				public void run() {
-				}
-			};
+	private static final ThrowingRunnable<IOException> CLOSE = () -> {};
 
 	private final DatabaseComponent db;
 	private final Executor dbExecutor;
@@ -83,7 +78,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
 		this.maxLatency = maxLatency;
 		this.maxIdleTime = maxIdleTime;
 		this.recordWriter = recordWriter;
-		writerTasks = new LinkedBlockingQueue<ThrowingRunnable<IOException>>();
+		writerTasks = new LinkedBlockingQueue<>();
 	}
 
 	@IoExecutor
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/sync/RecordReaderImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/sync/RecordReaderImpl.java
index e6a80735ab450242e16b754bea3da49681c3d6b2..a9663dc0c232b7f9459f0ceefa0ed8f7b8795f0a 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/sync/RecordReaderImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/sync/RecordReaderImpl.java
@@ -116,7 +116,7 @@ class RecordReaderImpl implements RecordReader {
 	private List<MessageId> readMessageIds() throws IOException {
 		if (payloadLength == 0) throw new FormatException();
 		if (payloadLength % UniqueId.LENGTH != 0) throw new FormatException();
-		List<MessageId> ids = new ArrayList<MessageId>();
+		List<MessageId> ids = new ArrayList<>();
 		for (int off = 0; off < payloadLength; off += UniqueId.LENGTH) {
 			byte[] id = new byte[UniqueId.LENGTH];
 			System.arraycopy(payload, off, id, 0, UniqueId.LENGTH);
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/sync/SimplexOutgoingSession.java b/bramble-core/src/main/java/org/briarproject/bramble/sync/SimplexOutgoingSession.java
index a9246b974836754788d6e49b232d9b33f6fde828..3d0ecae22b739912b498e380156a9970eedb2028 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/sync/SimplexOutgoingSession.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/sync/SimplexOutgoingSession.java
@@ -43,12 +43,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
 	private static final Logger LOG =
 			Logger.getLogger(SimplexOutgoingSession.class.getName());
 
-	private static final ThrowingRunnable<IOException> CLOSE =
-			new ThrowingRunnable<IOException>() {
-				@Override
-				public void run() {
-				}
-			};
+	private static final ThrowingRunnable<IOException> CLOSE = () -> {};
 
 	private final DatabaseComponent db;
 	private final Executor dbExecutor;
@@ -71,7 +66,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
 		this.maxLatency = maxLatency;
 		this.recordWriter = recordWriter;
 		outstandingQueries = new AtomicInteger(2); // One per type of record
-		writerTasks = new LinkedBlockingQueue<ThrowingRunnable<IOException>>();
+		writerTasks = new LinkedBlockingQueue<>();
 	}
 
 	@IoExecutor
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/sync/ValidationManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/sync/ValidationManagerImpl.java
index 88889086409fad0e749bbbcf49f1606600c19894..3184a11082f97dacd3266fa2c599a6e96ee2f8e8 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/sync/ValidationManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/sync/ValidationManagerImpl.java
@@ -64,8 +64,8 @@ class ValidationManagerImpl implements ValidationManager, Service,
 		this.dbExecutor = dbExecutor;
 		this.validationExecutor = validationExecutor;
 		this.messageFactory = messageFactory;
-		validators = new ConcurrentHashMap<ClientId, MessageValidator>();
-		hooks = new ConcurrentHashMap<ClientId, IncomingMessageHook>();
+		validators = new ConcurrentHashMap<>();
+		hooks = new ConcurrentHashMap<>();
 	}
 
 	@Override
@@ -93,19 +93,14 @@ class ValidationManagerImpl implements ValidationManager, Service,
 		hooks.put(c, hook);
 	}
 
-	private void validateOutstandingMessagesAsync(final ClientId c) {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				validateOutstandingMessages(c);
-			}
-		});
+	private void validateOutstandingMessagesAsync(ClientId c) {
+		dbExecutor.execute(() -> validateOutstandingMessages(c));
 	}
 
 	@DatabaseExecutor
 	private void validateOutstandingMessages(ClientId c) {
 		try {
-			Queue<MessageId> unvalidated = new LinkedList<MessageId>();
+			Queue<MessageId> unvalidated = new LinkedList<>();
 			Transaction txn = db.startTransaction(true);
 			try {
 				unvalidated.addAll(db.getMessagesToValidate(txn, c));
@@ -119,14 +114,9 @@ class ValidationManagerImpl implements ValidationManager, Service,
 		}
 	}
 
-	private void validateNextMessageAsync(final Queue<MessageId> unvalidated) {
+	private void validateNextMessageAsync(Queue<MessageId> unvalidated) {
 		if (unvalidated.isEmpty()) return;
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				validateNextMessage(unvalidated);
-			}
-		});
+		dbExecutor.execute(() -> validateNextMessage(unvalidated));
 	}
 
 	@DatabaseExecutor
@@ -158,19 +148,14 @@ class ValidationManagerImpl implements ValidationManager, Service,
 		}
 	}
 
-	private void deliverOutstandingMessagesAsync(final ClientId c) {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				deliverOutstandingMessages(c);
-			}
-		});
+	private void deliverOutstandingMessagesAsync(ClientId c) {
+		dbExecutor.execute(() -> deliverOutstandingMessages(c));
 	}
 
 	@DatabaseExecutor
 	private void deliverOutstandingMessages(ClientId c) {
 		try {
-			Queue<MessageId> pending = new LinkedList<MessageId>();
+			Queue<MessageId> pending = new LinkedList<>();
 			Transaction txn = db.startTransaction(true);
 			try {
 				pending.addAll(db.getPendingMessages(txn, c));
@@ -184,15 +169,9 @@ class ValidationManagerImpl implements ValidationManager, Service,
 		}
 	}
 
-	private void deliverNextPendingMessageAsync(
-			final Queue<MessageId> pending) {
+	private void deliverNextPendingMessageAsync(Queue<MessageId> pending) {
 		if (pending.isEmpty()) return;
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				deliverNextPendingMessage(pending);
-			}
-		});
+		dbExecutor.execute(() -> deliverNextPendingMessage(pending));
 	}
 
 	@DatabaseExecutor
@@ -229,8 +208,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 							pending.addAll(getPendingDependents(txn, id));
 							if (result.share) {
 								db.setMessageShared(txn, id);
-								toShare = new LinkedList<MessageId>(
-										states.keySet());
+								toShare = new LinkedList<>(states.keySet());
 							}
 						} else {
 							invalidate = getDependentsToInvalidate(txn, id);
@@ -255,13 +233,8 @@ class ValidationManagerImpl implements ValidationManager, Service,
 		}
 	}
 
-	private void validateMessageAsync(final Message m, final Group g) {
-		validationExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				validateMessage(m, g);
-			}
-		});
+	private void validateMessageAsync(Message m, Group g) {
+		validationExecutor.execute(() -> validateMessage(m, g));
 	}
 
 	@ValidationExecutor
@@ -277,21 +250,16 @@ class ValidationManagerImpl implements ValidationManager, Service,
 			} catch (InvalidMessageException e) {
 				if (LOG.isLoggable(INFO))
 					LOG.log(INFO, e.toString(), e);
-				Queue<MessageId> invalidate = new LinkedList<MessageId>();
+				Queue<MessageId> invalidate = new LinkedList<>();
 				invalidate.add(m.getId());
 				invalidateNextMessageAsync(invalidate);
 			}
 		}
 	}
 
-	private void storeMessageContextAsync(final Message m, final ClientId c,
-			final MessageContext result) {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				storeMessageContext(m, c, result);
-			}
-		});
+	private void storeMessageContextAsync(Message m, ClientId c,
+			MessageContext result) {
+		dbExecutor.execute(() -> storeMessageContext(m, c, result));
 	}
 
 	@DatabaseExecutor
@@ -331,8 +299,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 							pending = getPendingDependents(txn, id);
 							if (result.share) {
 								db.setMessageShared(txn, id);
-								toShare =
-										new LinkedList<MessageId>(dependencies);
+								toShare = new LinkedList<>(dependencies);
 							}
 						} else {
 							invalidate = getDependentsToInvalidate(txn, id);
@@ -378,7 +345,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 	@DatabaseExecutor
 	private Queue<MessageId> getPendingDependents(Transaction txn, MessageId m)
 			throws DbException {
-		Queue<MessageId> pending = new LinkedList<MessageId>();
+		Queue<MessageId> pending = new LinkedList<>();
 		Map<MessageId, State> states = db.getMessageDependents(txn, m);
 		for (Entry<MessageId, State> e : states.entrySet()) {
 			if (e.getValue() == PENDING) pending.add(e.getKey());
@@ -386,19 +353,14 @@ class ValidationManagerImpl implements ValidationManager, Service,
 		return pending;
 	}
 
-	private void shareOutstandingMessagesAsync(final ClientId c) {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				shareOutstandingMessages(c);
-			}
-		});
+	private void shareOutstandingMessagesAsync(ClientId c) {
+		dbExecutor.execute(() -> shareOutstandingMessages(c));
 	}
 
 	@DatabaseExecutor
 	private void shareOutstandingMessages(ClientId c) {
 		try {
-			Queue<MessageId> toShare = new LinkedList<MessageId>();
+			Queue<MessageId> toShare = new LinkedList<>();
 			Transaction txn = db.startTransaction(true);
 			try {
 				toShare.addAll(db.getMessagesToShare(txn, c));
@@ -418,14 +380,9 @@ class ValidationManagerImpl implements ValidationManager, Service,
 	 * This method should only be called for messages that have all their
 	 * dependencies delivered and have been delivered themselves.
 	 */
-	private void shareNextMessageAsync(final Queue<MessageId> toShare) {
+	private void shareNextMessageAsync(Queue<MessageId> toShare) {
 		if (toShare.isEmpty()) return;
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				shareNextMessage(toShare);
-			}
-		});
+		dbExecutor.execute(() -> shareNextMessage(toShare));
 	}
 
 	@DatabaseExecutor
@@ -452,14 +409,9 @@ class ValidationManagerImpl implements ValidationManager, Service,
 		}
 	}
 
-	private void invalidateNextMessageAsync(final Queue<MessageId> invalidate) {
+	private void invalidateNextMessageAsync(Queue<MessageId> invalidate) {
 		if (invalidate.isEmpty()) return;
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				invalidateNextMessage(invalidate);
-			}
-		});
+		dbExecutor.execute(() -> invalidateNextMessage(invalidate));
 	}
 
 	@DatabaseExecutor
@@ -496,7 +448,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 	@DatabaseExecutor
 	private Queue<MessageId> getDependentsToInvalidate(Transaction txn,
 			MessageId m) throws DbException {
-		Queue<MessageId> invalidate = new LinkedList<MessageId>();
+		Queue<MessageId> invalidate = new LinkedList<>();
 		Map<MessageId, State> states = db.getMessageDependents(txn, m);
 		for (Entry<MessageId, State> e : states.entrySet()) {
 			if (e.getValue() != INVALID) invalidate.add(e.getKey());
@@ -514,17 +466,12 @@ class ValidationManagerImpl implements ValidationManager, Service,
 		}
 	}
 
-	private void loadGroupAndValidateAsync(final Message m) {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				loadGroupAndValidate(m);
-			}
-		});
+	private void loadGroupAndValidateAsync(Message m) {
+		dbExecutor.execute(() -> loadGroupAndValidate(m));
 	}
 
 	@DatabaseExecutor
-	private void loadGroupAndValidate(final Message m) {
+	private void loadGroupAndValidate(Message m) {
 		try {
 			Group g;
 			Transaction txn = db.startTransaction(true);
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/transport/KeyManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/transport/KeyManagerImpl.java
index 11e459eaf93861ffc2b8a1a55f9bafc6fccfe25a..d0c6fd709d619911f6cc9862b99947df3eb82bfe 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/transport/KeyManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/transport/KeyManagerImpl.java
@@ -58,15 +58,14 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
 		this.pluginConfig = pluginConfig;
 		this.transportKeyManagerFactory = transportKeyManagerFactory;
 		// Use a ConcurrentHashMap as a thread-safe set
-		activeContacts = new ConcurrentHashMap<ContactId, Boolean>();
-		managers = new ConcurrentHashMap<TransportId, TransportKeyManager>();
+		activeContacts = new ConcurrentHashMap<>();
+		managers = new ConcurrentHashMap<>();
 	}
 
 	@Override
 	public void startService() throws ServiceException {
 		if (used.getAndSet(true)) throw new IllegalStateException();
-		Map<TransportId, Integer> transports =
-				new HashMap<TransportId, Integer>();
+		Map<TransportId, Integer> transports = new HashMap<>();
 		for (SimplexPluginFactory f : pluginConfig.getSimplexFactories())
 			transports.put(f.getId(), f.getMaxLatency());
 		for (DuplexPluginFactory f : pluginConfig.getDuplexFactories())
@@ -156,14 +155,10 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
 		}
 	}
 
-	private void removeContact(final ContactId c) {
+	private void removeContact(ContactId c) {
 		activeContacts.remove(c);
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				for (TransportKeyManager m : managers.values())
-					m.removeContact(c);
-			}
+		dbExecutor.execute(() -> {
+			for (TransportKeyManager m : managers.values()) m.removeContact(c);
 		});
 	}
 }
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/transport/ReorderingWindow.java b/bramble-core/src/main/java/org/briarproject/bramble/transport/ReorderingWindow.java
index f81d57fa6dc7be6e69baab6e2efbf0c6328f2030..4b0ea2bc694b36eab166152cba3c54e6d1a1f16c 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/transport/ReorderingWindow.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/transport/ReorderingWindow.java
@@ -45,7 +45,7 @@ class ReorderingWindow {
 	}
 
 	List<Long> getUnseen() {
-		List<Long> unseen = new ArrayList<Long>(seen.length);
+		List<Long> unseen = new ArrayList<>(seen.length);
 		for (int i = 0; i < seen.length; i++)
 			if (!seen[i]) unseen.add(base + i);
 		return unseen;
@@ -69,8 +69,8 @@ class ReorderingWindow {
 			return new Change(added, removed);
 		}
 		// Record the elements that will be added and removed
-		List<Long> added = new ArrayList<Long>(slide);
-		List<Long> removed = new ArrayList<Long>(slide);
+		List<Long> added = new ArrayList<>(slide);
+		List<Long> removed = new ArrayList<>(slide);
 		for (int i = 0; i < slide; i++) {
 			if (!seen[i]) removed.add(base + i);
 			added.add(base + seen.length + i);
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/transport/TransportKeyManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/transport/TransportKeyManagerImpl.java
index a9779c184b396718582a2adb0a400c0ac5215c81..95e49f55346b6fc13ce6cf04b668bc5d12a41818 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/transport/TransportKeyManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/transport/TransportKeyManagerImpl.java
@@ -65,9 +65,9 @@ class TransportKeyManagerImpl implements TransportKeyManager {
 		this.transportId = transportId;
 		rotationPeriodLength = maxLatency + MAX_CLOCK_DIFFERENCE;
 		lock = new ReentrantLock();
-		inContexts = new HashMap<Bytes, TagContext>();
-		outContexts = new HashMap<ContactId, MutableOutgoingKeys>();
-		keys = new HashMap<ContactId, MutableTransportKeys>();
+		inContexts = new HashMap<>();
+		outContexts = new HashMap<>();
+		keys = new HashMap<>();
 	}
 
 	@Override
@@ -134,32 +134,22 @@ class TransportKeyManagerImpl implements TransportKeyManager {
 	}
 
 	private void scheduleKeyRotation(long now) {
-		Runnable task = new Runnable() {
-			@Override
-			public void run() {
-				rotateKeys();
-			}
-		};
 		long delay = rotationPeriodLength - now % rotationPeriodLength;
-		scheduler.schedule(task, delay, MILLISECONDS);
+		scheduler.schedule((Runnable) this::rotateKeys, delay, MILLISECONDS);
 	}
 
 	private void rotateKeys() {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
+		dbExecutor.execute(() -> {
+			try {
+				Transaction txn = db.startTransaction(false);
 				try {
-					Transaction txn = db.startTransaction(false);
-					try {
-						rotateKeys(txn);
-						db.commitTransaction(txn);
-					} finally {
-						db.endTransaction(txn);
-					}
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
+					rotateKeys(txn);
+					db.commitTransaction(txn);
+				} finally {
+					db.endTransaction(txn);
 				}
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
@@ -272,8 +262,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
 		lock.lock();
 		try {
 			// Rotate the keys to the current rotation period
-			Map<ContactId, TransportKeys> snapshot =
-					new HashMap<ContactId, TransportKeys>();
+			Map<ContactId, TransportKeys> snapshot = new HashMap<>();
 			for (Entry<ContactId, MutableTransportKeys> e : keys.entrySet())
 				snapshot.put(e.getKey(), e.getValue().snapshot());
 			RotationResult rotationResult = rotateKeys(snapshot, now);
@@ -311,8 +300,8 @@ class TransportKeyManagerImpl implements TransportKeyManager {
 		private final Map<ContactId, TransportKeys> current, rotated;
 
 		private RotationResult() {
-			current = new HashMap<ContactId, TransportKeys>();
-			rotated = new HashMap<ContactId, TransportKeys>();
+			current = new HashMap<>();
+			rotated = new HashMap<>();
 		}
 	}
 }
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/PoliteExecutorTest.java b/bramble-core/src/test/java/org/briarproject/bramble/PoliteExecutorTest.java
index 426c4cc1d329b37a37d6093cd1331318adf8ed59..2c53a8de44ae7a2b5b23ca3241620703b7e5c8df 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/PoliteExecutorTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/PoliteExecutorTest.java
@@ -24,16 +24,13 @@ public class PoliteExecutorTest extends BrambleTestCase {
 		Executor delegate = Executors.newSingleThreadExecutor();
 		// Allow all the tasks to be delegated straight away
 		PoliteExecutor polite = new PoliteExecutor(TAG, delegate, TASKS * 2);
-		final List<Integer> list = new Vector<Integer>();
-		final CountDownLatch latch = new CountDownLatch(TASKS);
+		List<Integer> list = new Vector<>();
+		CountDownLatch latch = new CountDownLatch(TASKS);
 		for (int i = 0; i < TASKS; i++) {
-			final int result = i;
-			polite.execute(new Runnable() {
-				@Override
-				public void run() {
-					list.add(result);
-					latch.countDown();
-				}
+			int result = i;
+			polite.execute(() -> {
+				list.add(result);
+				latch.countDown();
 			});
 		}
 		// Wait for all the tasks to finish
@@ -49,16 +46,13 @@ public class PoliteExecutorTest extends BrambleTestCase {
 		Executor delegate = Executors.newSingleThreadExecutor();
 		// Allow two tasks to be delegated at a time
 		PoliteExecutor polite = new PoliteExecutor(TAG, delegate, 2);
-		final List<Integer> list = new Vector<Integer>();
-		final CountDownLatch latch = new CountDownLatch(TASKS);
+		List<Integer> list = new Vector<>();
+		CountDownLatch latch = new CountDownLatch(TASKS);
 		for (int i = 0; i < TASKS; i++) {
-			final int result = i;
-			polite.execute(new Runnable() {
-				@Override
-				public void run() {
-					list.add(result);
-					latch.countDown();
-				}
+			int result = i;
+			polite.execute(() -> {
+				list.add(result);
+				latch.countDown();
 			});
 		}
 		// Wait for all the tasks to finish
@@ -73,23 +67,20 @@ public class PoliteExecutorTest extends BrambleTestCase {
 		Executor delegate = Executors.newCachedThreadPool();
 		// Allow all the tasks to be delegated straight away
 		PoliteExecutor polite = new PoliteExecutor(TAG, delegate, TASKS * 2);
-		final List<Integer> list = new Vector<Integer>();
-		final CountDownLatch[] latches = new CountDownLatch[TASKS];
+		List<Integer> list = new Vector<>();
+		CountDownLatch[] latches = new CountDownLatch[TASKS];
 		for (int i = 0; i < TASKS; i++) latches[i] = new CountDownLatch(1);
 		for (int i = 0; i < TASKS; i++) {
-			final int result = i;
-			polite.execute(new Runnable() {
-				@Override
-				public void run() {
-					try {
-						// Each task waits for the next task, if any, to finish
-						if (result < TASKS - 1) latches[result + 1].await();
-						list.add(result);
-					} catch (InterruptedException e) {
-						fail();
-					}
-					latches[result].countDown();
+			int result = i;
+			polite.execute(() -> {
+				try {
+					// Each task waits for the next task, if any, to finish
+					if (result < TASKS - 1) latches[result + 1].await();
+					list.add(result);
+				} catch (InterruptedException e) {
+					fail();
 				}
+				latches[result].countDown();
 			});
 		}
 		// Wait for all the tasks to finish
@@ -104,22 +95,19 @@ public class PoliteExecutorTest extends BrambleTestCase {
 		Executor delegate = Executors.newCachedThreadPool();
 		// Allow one task to be delegated at a time
 		PoliteExecutor polite = new PoliteExecutor(TAG, delegate, 1);
-		final List<Integer> list = new Vector<Integer>();
-		final CountDownLatch latch = new CountDownLatch(TASKS);
+		List<Integer> list = new Vector<>();
+		CountDownLatch latch = new CountDownLatch(TASKS);
 		for (int i = 0; i < TASKS; i++) {
-			final int result = i;
-			polite.execute(new Runnable() {
-				@Override
-				public void run() {
-					try {
-						// Each task runs faster than the previous task
-						Thread.sleep(TASKS - result);
-						list.add(result);
-					} catch (InterruptedException e) {
-						fail();
-					}
-					latch.countDown();
+			int result = i;
+			polite.execute(() -> {
+				try {
+					// Each task runs faster than the previous task
+					Thread.sleep(TASKS - result);
+					list.add(result);
+				} catch (InterruptedException e) {
+					fail();
 				}
+				latch.countDown();
 			});
 		}
 		// Wait for all the tasks to finish
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/client/BdfMessageValidatorTest.java b/bramble-core/src/test/java/org/briarproject/bramble/client/BdfMessageValidatorTest.java
index 58afef572e2eb56eac2c160c5e53b6d2d09dad94..07735626425d175aa0983d4b3446cc75b2f80dc6 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/client/BdfMessageValidatorTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/client/BdfMessageValidatorTest.java
@@ -83,9 +83,9 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
 
 	@Test(expected = InvalidMessageException.class)
 	public void testRejectsTooShortMessage() throws Exception {
-		final byte[] invalidRaw = new byte[MESSAGE_HEADER_LENGTH];
+		byte[] invalidRaw = new byte[MESSAGE_HEADER_LENGTH];
 		// Use a mock message so the length of the raw message can be invalid
-		final Message invalidMessage = context.mock(Message.class);
+		Message invalidMessage = context.mock(Message.class);
 
 		context.checking(new Expectations() {{
 			oneOf(invalidMessage).getTimestamp();
@@ -101,8 +101,8 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
 
 	@Test
 	public void testAcceptsMinLengthMessage() throws Exception {
-		final byte[] shortRaw = new byte[MESSAGE_HEADER_LENGTH + 1];
-		final Message shortMessage =
+		byte[] shortRaw = new byte[MESSAGE_HEADER_LENGTH + 1];
+		Message shortMessage =
 				new Message(messageId, groupId, timestamp, shortRaw);
 
 		context.checking(new Expectations() {{
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/client/ClientHelperImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/client/ClientHelperImplTest.java
index f41f6a225e6d344f896232d80df06a2b5a8b5ffe..fddf10b363724c96cccb12759ea8948aa4c504c3 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/client/ClientHelperImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/client/ClientHelperImplTest.java
@@ -76,8 +76,8 @@ public class ClientHelperImplTest extends BrambleTestCase {
 
 	@Test
 	public void testAddLocalMessage() throws Exception {
-		final boolean shared = true;
-		final Transaction txn = new Transaction(null, false);
+		boolean shared = true;
+		Transaction txn = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(false);
@@ -95,7 +95,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
 
 	@Test
 	public void testCreateMessage() throws Exception {
-		final byte[] bytes = expectToByteArray(list);
+		byte[] bytes = expectToByteArray(list);
 
 		context.checking(new Expectations() {{
 			oneOf(messageFactory).createMessage(groupId, timestamp, bytes);
@@ -107,7 +107,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
 
 	@Test
 	public void testGetMessageAsList() throws Exception {
-		final Transaction txn = new Transaction(null, true);
+		Transaction txn = new Transaction(null, true);
 
 		expectToList(true);
 		context.checking(new Expectations() {{
@@ -125,7 +125,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
 
 	@Test
 	public void testGetGroupMetadataAsDictionary() throws Exception {
-		final Transaction txn = new Transaction(null, true);
+		Transaction txn = new Transaction(null, true);
 
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(true);
@@ -145,7 +145,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
 
 	@Test
 	public void testGetMessageMetadataAsDictionary() throws Exception {
-		final Transaction txn = new Transaction(null, true);
+		Transaction txn = new Transaction(null, true);
 
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(true);
@@ -165,10 +165,9 @@ public class ClientHelperImplTest extends BrambleTestCase {
 
 	@Test
 	public void testGetMessageMetadataAsDictionaryMap() throws Exception {
-		final Map<MessageId, BdfDictionary> map =
-				new HashMap<MessageId, BdfDictionary>();
+		Map<MessageId, BdfDictionary> map = new HashMap<>();
 		map.put(messageId, dictionary);
-		final Transaction txn = new Transaction(null, true);
+		Transaction txn = new Transaction(null, true);
 
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(true);
@@ -188,14 +187,13 @@ public class ClientHelperImplTest extends BrambleTestCase {
 
 	@Test
 	public void testGetMessageMetadataAsDictionaryQuery() throws Exception {
-		final Map<MessageId, BdfDictionary> map =
-				new HashMap<MessageId, BdfDictionary>();
+		Map<MessageId, BdfDictionary> map = new HashMap<>();
 		map.put(messageId, dictionary);
-		final BdfDictionary query =
+		BdfDictionary query =
 				BdfDictionary.of(new BdfEntry("query", "me"));
-		final Metadata queryMetadata = new Metadata();
+		Metadata queryMetadata = new Metadata();
 		queryMetadata.put("query", getRandomBytes(42));
-		final Transaction txn = new Transaction(null, true);
+		Transaction txn = new Transaction(null, true);
 
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(true);
@@ -217,7 +215,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
 
 	@Test
 	public void testMergeGroupMetadata() throws Exception {
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(false);
@@ -235,7 +233,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
 
 	@Test
 	public void testMergeMessageMetadata() throws Exception {
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(false);
@@ -282,10 +280,10 @@ public class ClientHelperImplTest extends BrambleTestCase {
 
 	@Test
 	public void testSign() throws Exception {
-		final byte[] privateKey = getRandomBytes(42);
-		final byte[] signed = getRandomBytes(42);
+		byte[] privateKey = getRandomBytes(42);
+		byte[] signed = getRandomBytes(42);
 
-		final byte[] bytes = expectToByteArray(list);
+		byte[] bytes = expectToByteArray(list);
 		context.checking(new Expectations() {{
 			oneOf(cryptoComponent).sign(label, bytes, privateKey);
 			will(returnValue(signed));
@@ -297,8 +295,8 @@ public class ClientHelperImplTest extends BrambleTestCase {
 
 	@Test
 	public void testVerifySignature() throws Exception {
-		final byte[] publicKey = getRandomBytes(42);
-		final byte[] bytes = expectToByteArray(list);
+		byte[] publicKey = getRandomBytes(42);
+		byte[] bytes = expectToByteArray(list);
 
 		context.checking(new Expectations() {{
 			oneOf(cryptoComponent).verify(label, bytes, publicKey, rawMessage);
@@ -311,8 +309,8 @@ public class ClientHelperImplTest extends BrambleTestCase {
 
 	@Test
 	public void testVerifyWrongSignature() throws Exception {
-		final byte[] publicKey = getRandomBytes(42);
-		final byte[] bytes = expectToByteArray(list);
+		byte[] publicKey = getRandomBytes(42);
+		byte[] bytes = expectToByteArray(list);
 
 		context.checking(new Expectations() {{
 			oneOf(cryptoComponent).verify(label, bytes, publicKey, rawMessage);
@@ -329,8 +327,8 @@ public class ClientHelperImplTest extends BrambleTestCase {
 		}
 	}
 
-	private byte[] expectToByteArray(final BdfList list) throws Exception {
-		final BdfWriter bdfWriter = context.mock(BdfWriter.class);
+	private byte[] expectToByteArray(BdfList list) throws Exception {
+		BdfWriter bdfWriter = context.mock(BdfWriter.class);
 
 		context.checking(new Expectations() {{
 			oneOf(bdfWriterFactory)
@@ -341,8 +339,8 @@ public class ClientHelperImplTest extends BrambleTestCase {
 		return new byte[0];
 	}
 
-	private void expectToList(final boolean eof) throws Exception {
-		final BdfReader bdfReader = context.mock(BdfReader.class);
+	private void expectToList(boolean eof) throws Exception {
+		BdfReader bdfReader = context.mock(BdfReader.class);
 
 		context.checking(new Expectations() {{
 			oneOf(bdfReaderFactory)
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactManagerImplTest.java
index 1c4f2907374a9a90942eb6f60e060d6b561625f2..9ded370dd80328249a21427c99f509bc179fe896 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactManagerImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactManagerImplTest.java
@@ -46,10 +46,10 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testAddContact() throws Exception {
-		final SecretKey master = getSecretKey();
-		final long timestamp = 42;
-		final boolean alice = true;
-		final Transaction txn = new Transaction(null, false);
+		SecretKey master = getSecretKey();
+		long timestamp = 42;
+		boolean alice = true;
+		Transaction txn = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(false);
@@ -64,14 +64,13 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
 			oneOf(db).endTransaction(txn);
 		}});
 
-		assertEquals(contactId, contactManager
-				.addContact(remote, local, master, timestamp, alice, verified,
-						active));
+		assertEquals(contactId, contactManager.addContact(remote, local,
+				master, timestamp, alice, verified, active));
 	}
 
 	@Test
 	public void testGetContact() throws Exception {
-		final Transaction txn = new Transaction(null, true);
+		Transaction txn = new Transaction(null, true);
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn));
@@ -86,8 +85,8 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testGetContactByAuthor() throws Exception {
-		final Transaction txn = new Transaction(null, true);
-		final Collection<Contact> contacts = Collections.singleton(contact);
+		Transaction txn = new Transaction(null, true);
+		Collection<Contact> contacts = Collections.singleton(contact);
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn));
@@ -102,7 +101,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
 
 	@Test(expected = NoSuchContactException.class)
 	public void testGetContactByUnknownAuthor() throws Exception {
-		final Transaction txn = new Transaction(null, true);
+		Transaction txn = new Transaction(null, true);
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn));
@@ -116,8 +115,8 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
 
 	@Test(expected = NoSuchContactException.class)
 	public void testGetContactByUnknownLocalAuthor() throws Exception {
-		final Transaction txn = new Transaction(null, true);
-		final Collection<Contact> contacts = Collections.singleton(contact);
+		Transaction txn = new Transaction(null, true);
+		Collection<Contact> contacts = Collections.singleton(contact);
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn));
@@ -132,10 +131,9 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
 	@Test
 	public void testActiveContacts() throws Exception {
 		Collection<Contact> activeContacts = Collections.singletonList(contact);
-		final Collection<Contact> contacts =
-				new ArrayList<Contact>(activeContacts);
+		Collection<Contact> contacts = new ArrayList<>(activeContacts);
 		contacts.add(new Contact(new ContactId(3), remote, local, true, false));
-		final Transaction txn = new Transaction(null, true);
+		Transaction txn = new Transaction(null, true);
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn));
@@ -150,7 +148,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testRemoveContact() throws Exception {
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(false);
 			will(returnValue(txn));
@@ -166,7 +164,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testSetContactActive() throws Exception {
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 		context.checking(new Expectations() {{
 			oneOf(db).setContactActive(txn, contactId, active);
 		}});
@@ -176,7 +174,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testContactExists() throws Exception {
-		final Transaction txn = new Transaction(null, true);
+		Transaction txn = new Transaction(null, true);
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn));
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/crypto/EllipticCurvePerformanceTest.java b/bramble-core/src/test/java/org/briarproject/bramble/crypto/EllipticCurvePerformanceTest.java
index ec166c34498190b2193c98bac1ba35162ea04f32..b9e695eda67af04b34f8272232497e4bf05ec3f9 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/crypto/EllipticCurvePerformanceTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/crypto/EllipticCurvePerformanceTest.java
@@ -69,7 +69,7 @@ public class EllipticCurvePerformanceTest {
 		ECPublicKeyParameters public2 =
 				(ECPublicKeyParameters) keyPair2.getPublic();
 		// Time some ECDH key agreements
-		List<Long> samples = new ArrayList<Long>();
+		List<Long> samples = new ArrayList<>();
 		for (int i = 0; i < SAMPLES; i++) {
 			ECDHCBasicAgreement agreement = new ECDHCBasicAgreement();
 			long start = System.nanoTime();
@@ -79,7 +79,7 @@ public class EllipticCurvePerformanceTest {
 		}
 		long agreementMedian = median(samples);
 		// Time some signatures
-		List<byte[]> signatures = new ArrayList<byte[]>();
+		List<byte[]> signatures = new ArrayList<>();
 		samples.clear();
 		for (int i = 0; i < SAMPLES; i++) {
 			Digest digest = new Blake2sDigest();
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/crypto/KeyDerivationTest.java b/bramble-core/src/test/java/org/briarproject/bramble/crypto/KeyDerivationTest.java
index 0e0e7a69f7debff57300f5ae1af0d495c249b739..7a3e67c4c2f5d09a5773585a2122d740e5c24f1d 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/crypto/KeyDerivationTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/crypto/KeyDerivationTest.java
@@ -145,7 +145,7 @@ public class KeyDerivationTest extends BrambleTestCase {
 	}
 
 	private void assertAllDifferent(TransportKeys... transportKeys) {
-		List<SecretKey> secretKeys = new ArrayList<SecretKey>();
+		List<SecretKey> secretKeys = new ArrayList<>();
 		for (TransportKeys k : transportKeys) {
 			secretKeys.add(k.getPreviousIncomingKeys().getTagKey());
 			secretKeys.add(k.getPreviousIncomingKeys().getHeaderKey());
@@ -160,7 +160,7 @@ public class KeyDerivationTest extends BrambleTestCase {
 	}
 
 	private void assertAllDifferent(List<SecretKey> keys) {
-		Set<Bytes> set = new HashSet<Bytes>();
+		Set<Bytes> set = new HashSet<>();
 		for (SecretKey k : keys) assertTrue(set.add(new Bytes(k.getBytes())));
 	}
 }
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/crypto/TagEncodingTest.java b/bramble-core/src/test/java/org/briarproject/bramble/crypto/TagEncodingTest.java
index b10654e9f3d2c7b9d571b71d6634f9c0060dffe3..cfbc6d37529510c2ce37260eaa53c8a05ee4493d 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/crypto/TagEncodingTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/crypto/TagEncodingTest.java
@@ -28,7 +28,7 @@ public class TagEncodingTest extends BrambleTestCase {
 
 	@Test
 	public void testKeyAffectsTag() throws Exception {
-		Set<Bytes> set = new HashSet<Bytes>();
+		Set<Bytes> set = new HashSet<>();
 		for (int i = 0; i < 100; i++) {
 			byte[] tag = new byte[TAG_LENGTH];
 			SecretKey tagKey = TestUtils.getSecretKey();
@@ -39,7 +39,7 @@ public class TagEncodingTest extends BrambleTestCase {
 
 	@Test
 	public void testProtocolVersionAffectsTag() throws Exception {
-		Set<Bytes> set = new HashSet<Bytes>();
+		Set<Bytes> set = new HashSet<>();
 		for (int i = 0; i < 100; i++) {
 			byte[] tag = new byte[TAG_LENGTH];
 			crypto.encodeTag(tag, tagKey, PROTOCOL_VERSION + i, streamNumber);
@@ -49,7 +49,7 @@ public class TagEncodingTest extends BrambleTestCase {
 
 	@Test
 	public void testStreamNumberAffectsTag() throws Exception {
-		Set<Bytes> set = new HashSet<Bytes>();
+		Set<Bytes> set = new HashSet<>();
 		for (int i = 0; i < 100; i++) {
 			byte[] tag = new byte[TAG_LENGTH];
 			crypto.encodeTag(tag, tagKey, PROTOCOL_VERSION, streamNumber + i);
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/data/BdfWriterImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/data/BdfWriterImplTest.java
index 1737f746f33628a303ffa92da81d0c2a4e017dce..22d32816644647773b7bb3415c3782f9d874a9bc 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/data/BdfWriterImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/data/BdfWriterImplTest.java
@@ -1,7 +1,6 @@
 package org.briarproject.bramble.data;
 
 import org.briarproject.bramble.test.BrambleTestCase;
-import org.briarproject.bramble.test.TestUtils;
 import org.briarproject.bramble.util.StringUtils;
 import org.junit.Before;
 import org.junit.Test;
@@ -155,7 +154,7 @@ public class BdfWriterImplTest extends BrambleTestCase {
 
 	@Test
 	public void testWriteList() throws IOException {
-		List<Object> l = new ArrayList<Object>();
+		List<Object> l = new ArrayList<>();
 		for (int i = 0; i < 3; i++) l.add(i);
 		w.writeList(l);
 		// LIST tag, elements as integers, END tag
@@ -164,7 +163,7 @@ public class BdfWriterImplTest extends BrambleTestCase {
 
 	@Test
 	public void testListCanContainNull() throws IOException {
-		List<Object> l = new ArrayList<Object>();
+		List<Object> l = new ArrayList<>();
 		l.add(1);
 		l.add(null);
 		l.add(NULL_VALUE);
@@ -177,7 +176,7 @@ public class BdfWriterImplTest extends BrambleTestCase {
 	@Test
 	public void testWriteDictionary() throws IOException {
 		// Use LinkedHashMap to get predictable iteration order
-		Map<String, Object> m = new LinkedHashMap<String, Object>();
+		Map<String, Object> m = new LinkedHashMap<>();
 		for (int i = 0; i < 4; i++) m.put(String.valueOf(i), i);
 		w.writeDictionary(m);
 		// DICTIONARY tag, keys as strings and values as integers, END tag
@@ -216,12 +215,12 @@ public class BdfWriterImplTest extends BrambleTestCase {
 
 	@Test
 	public void testWriteNestedDictionariesAndLists() throws IOException {
-		Map<String, Object> inner = new LinkedHashMap<String, Object>();
+		Map<String, Object> inner = new LinkedHashMap<>();
 		inner.put("bar", new byte[0]);
-		List<Object> list = new ArrayList<Object>();
+		List<Object> list = new ArrayList<>();
 		list.add(1);
 		list.add(inner);
-		Map<String, Object> outer = new LinkedHashMap<String, Object>();
+		Map<String, Object> outer = new LinkedHashMap<>();
 		outer.put("foo", list);
 		w.writeDictionary(outer);
 		// DICTIONARY tag, "foo" as string, LIST tag, 1 as integer,
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/data/MetadataEncoderParserIntegrationTest.java b/bramble-core/src/test/java/org/briarproject/bramble/data/MetadataEncoderParserIntegrationTest.java
index 7fbdcb18d3523094b3fa916926a8fe5123199266..6822e14d83f4bb8735b1994a51e20beff2d7550f 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/data/MetadataEncoderParserIntegrationTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/data/MetadataEncoderParserIntegrationTest.java
@@ -99,7 +99,7 @@ public class MetadataEncoderParserIntegrationTest extends BrambleTestCase {
 
 	@Test
 	public void testList() throws FormatException {
-		List<Long> l = new ArrayList<Long>(4);
+		List<Long> l = new ArrayList<>(4);
 		l.add(42L);
 		l.add(1337L);
 		l.add(Long.MIN_VALUE);
@@ -114,7 +114,7 @@ public class MetadataEncoderParserIntegrationTest extends BrambleTestCase {
 
 	@Test
 	public void testDictionary() throws FormatException {
-		Map<String, Boolean> m = new HashMap<String, Boolean>();
+		Map<String, Boolean> m = new HashMap<>();
 		m.put("1", true);
 		m.put("2", false);
 
@@ -130,19 +130,19 @@ public class MetadataEncoderParserIntegrationTest extends BrambleTestCase {
 
 	@Test
 	public void testComplexDictionary() throws FormatException {
-		Map<String, List> m = new HashMap<String, List>();
-		List<String> one = new ArrayList<String>(3);
+		Map<String, List> m = new HashMap<>();
+		List<String> one = new ArrayList<>(3);
 		one.add("\uFDD0");
 		one.add("\uFDD1");
 		one.add("\uFDD2");
 		m.put("One", one);
-		List<String> two = new ArrayList<String>(2);
+		List<String> two = new ArrayList<>(2);
 		two.add("\u0080");
 		two.add("\uD800\uDC00");
 		m.put("Two", two);
 		d.put("test", m);
 
-		Map<String, Boolean> m2 = new HashMap<String, Boolean>();
+		Map<String, Boolean> m2 = new HashMap<>();
 		m2.put("should be true", true);
 		d.put("another test", m2);
 
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/db/BasicH2Test.java b/bramble-core/src/test/java/org/briarproject/bramble/db/BasicH2Test.java
index f6a21e2f864d1d4af2ac12c40f5470c8ca4d5317..5b62ba75071b94b5c8d163f5fa709f9d949d1f58 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/db/BasicH2Test.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/db/BasicH2Test.java
@@ -323,7 +323,7 @@ public class BasicH2Test extends BrambleTestCase {
 
 	private List<String> getNames() throws SQLException {
 		String sql = "SELECT name FROM foo ORDER BY uniqueId";
-		List<String> names = new ArrayList<String>();
+		List<String> names = new ArrayList<>();
 		try {
 			PreparedStatement ps = connection.prepareStatement(sql);
 			ResultSet rs = ps.executeQuery();
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/db/DatabaseComponentImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/db/DatabaseComponentImplTest.java
index 680e25652e76d3b13f10b8f1eb25f244f345deee..e25f77ee69fa8159cf61fbd1bb9e53f8954aeeeb 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/db/DatabaseComponentImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/db/DatabaseComponentImplTest.java
@@ -120,18 +120,18 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 
 	private DatabaseComponent createDatabaseComponent(Database<Object> database,
 			EventBus eventBus, ShutdownManager shutdown) {
-		return new DatabaseComponentImpl<Object>(database, Object.class,
-				eventBus, shutdown);
+		return new DatabaseComponentImpl<>(database, Object.class, eventBus,
+				shutdown);
 	}
 
 	@Test
 	@SuppressWarnings("unchecked")
 	public void testSimpleCalls() throws Exception {
-		final int shutdownHandle = 12345;
+		int shutdownHandle = 12345;
 		Mockery context = new Mockery();
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			// open()
 			oneOf(database).open();
@@ -230,9 +230,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 			throws Exception {
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
 			will(returnValue(txn));
@@ -260,9 +260,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 	public void testAddLocalMessage() throws Exception {
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
 			will(returnValue(txn));
@@ -303,9 +303,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 			throws Exception {
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			// Check whether the contact is in the DB (which it's not)
 			exactly(18).of(database).startTransaction();
@@ -509,9 +509,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 			throws Exception {
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			// Check whether the pseudonym is in the DB (which it's not)
 			exactly(3).of(database).startTransaction();
@@ -561,9 +561,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 			throws Exception {
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			// Check whether the group is in the DB (which it's not)
 			exactly(8).of(database).startTransaction();
@@ -666,9 +666,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 			throws Exception {
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			// Check whether the message is in the DB (which it's not)
 			exactly(11).of(database).startTransaction();
@@ -801,9 +801,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 			throws Exception {
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			// startTransaction()
 			oneOf(database).startTransaction();
@@ -896,13 +896,13 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 
 	@Test
 	public void testGenerateAck() throws Exception {
-		final Collection<MessageId> messagesToAck = Arrays.asList(messageId,
+		Collection<MessageId> messagesToAck = Arrays.asList(messageId,
 				messageId1);
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
 			will(returnValue(txn));
@@ -931,14 +931,14 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 
 	@Test
 	public void testGenerateBatch() throws Exception {
-		final byte[] raw1 = new byte[size];
-		final Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
-		final Collection<byte[]> messages = Arrays.asList(raw, raw1);
+		byte[] raw1 = new byte[size];
+		Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
+		Collection<byte[]> messages = Arrays.asList(raw, raw1);
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
 			will(returnValue(txn));
@@ -975,13 +975,13 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 
 	@Test
 	public void testGenerateOffer() throws Exception {
-		final MessageId messageId1 = new MessageId(TestUtils.getRandomId());
-		final Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
+		MessageId messageId1 = new MessageId(TestUtils.getRandomId());
+		Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
 			will(returnValue(txn));
@@ -1013,13 +1013,13 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 
 	@Test
 	public void testGenerateRequest() throws Exception {
-		final MessageId messageId1 = new MessageId(TestUtils.getRandomId());
-		final Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
+		MessageId messageId1 = new MessageId(TestUtils.getRandomId());
+		Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
 			will(returnValue(txn));
@@ -1048,14 +1048,14 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 
 	@Test
 	public void testGenerateRequestedBatch() throws Exception {
-		final byte[] raw1 = new byte[size];
-		final Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
-		final Collection<byte[]> messages = Arrays.asList(raw, raw1);
+		byte[] raw1 = new byte[size];
+		Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
+		Collection<byte[]> messages = Arrays.asList(raw, raw1);
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
 			will(returnValue(txn));
@@ -1095,9 +1095,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 	public void testReceiveAck() throws Exception {
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
 			will(returnValue(txn));
@@ -1128,9 +1128,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 	public void testReceiveMessage() throws Exception {
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
 			will(returnValue(txn));
@@ -1183,9 +1183,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 	public void testReceiveDuplicateMessage() throws Exception {
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
 			will(returnValue(txn));
@@ -1220,9 +1220,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 	public void testReceiveMessageWithoutVisibleGroup() throws Exception {
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
 			will(returnValue(txn));
@@ -1248,14 +1248,14 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 
 	@Test
 	public void testReceiveOffer() throws Exception {
-		final MessageId messageId1 = new MessageId(TestUtils.getRandomId());
-		final MessageId messageId2 = new MessageId(TestUtils.getRandomId());
-		final MessageId messageId3 = new MessageId(TestUtils.getRandomId());
+		MessageId messageId1 = new MessageId(TestUtils.getRandomId());
+		MessageId messageId2 = new MessageId(TestUtils.getRandomId());
+		MessageId messageId3 = new MessageId(TestUtils.getRandomId());
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
 			will(returnValue(txn));
@@ -1304,9 +1304,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 	public void testReceiveRequest() throws Exception {
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
 			will(returnValue(txn));
@@ -1338,9 +1338,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 	public void testChangingVisibilityCallsListeners() throws Exception {
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
 			will(returnValue(txn));
@@ -1379,9 +1379,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 			throws Exception {
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
 			will(returnValue(txn));
@@ -1409,14 +1409,14 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 
 	@Test
 	public void testTransportKeys() throws Exception {
-		final TransportKeys transportKeys = createTransportKeys();
-		final Map<ContactId, TransportKeys> keys = Collections.singletonMap(
+		TransportKeys transportKeys = createTransportKeys();
+		Map<ContactId, TransportKeys> keys = Collections.singletonMap(
 				contactId, transportKeys);
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			// startTransaction()
 			oneOf(database).startTransaction();
@@ -1472,19 +1472,19 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 
 	@Test
 	public void testMergeSettings() throws Exception {
-		final Settings before = new Settings();
+		Settings before = new Settings();
 		before.put("foo", "bar");
 		before.put("baz", "bam");
-		final Settings update = new Settings();
+		Settings update = new Settings();
 		update.put("baz", "qux");
-		final Settings merged = new Settings();
+		Settings merged = new Settings();
 		merged.put("foo", "bar");
 		merged.put("baz", "qux");
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			// startTransaction()
 			oneOf(database).startTransaction();
@@ -1547,9 +1547,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 			throws Exception {
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
@@ -1572,9 +1572,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 	public void testCannotAddLocalIdentityAsContact() throws Exception {
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
@@ -1607,9 +1607,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 	public void testCannotAddDuplicateContact() throws Exception {
 		Mockery context = new Mockery();
 		@SuppressWarnings("unchecked")
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
 
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
@@ -1643,12 +1643,12 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 	@Test
 	@SuppressWarnings("unchecked")
 	public void testMessageDependencies() throws Exception {
-		final int shutdownHandle = 12345;
+		int shutdownHandle = 12345;
 		Mockery context = new Mockery();
-		final Database<Object> database = context.mock(Database.class);
-		final ShutdownManager shutdown = context.mock(ShutdownManager.class);
-		final EventBus eventBus = context.mock(EventBus.class);
-		final MessageId messageId2 = new MessageId(TestUtils.getRandomId());
+		Database<Object> database = context.mock(Database.class);
+		ShutdownManager shutdown = context.mock(ShutdownManager.class);
+		EventBus eventBus = context.mock(EventBus.class);
+		MessageId messageId2 = new MessageId(TestUtils.getRandomId());
 		context.checking(new Expectations() {{
 			// open()
 			oneOf(database).open();
@@ -1703,7 +1703,7 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
 		Transaction transaction = db.startTransaction(false);
 		try {
 			db.addLocalMessage(transaction, message, metadata, true);
-			Collection<MessageId> dependencies = new ArrayList<MessageId>(2);
+			Collection<MessageId> dependencies = new ArrayList<>(2);
 			dependencies.add(messageId1);
 			dependencies.add(messageId2);
 			db.addMessageDependencies(transaction, message, dependencies);
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/db/H2DatabaseTest.java b/bramble-core/src/test/java/org/briarproject/bramble/db/H2DatabaseTest.java
index 91ab9f597e98aad2c7a52f03b6b43143102e188e..4afea4bf42a6b39b0bcb5a9bea2f6142d999e026 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/db/H2DatabaseTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/db/H2DatabaseTest.java
@@ -464,28 +464,25 @@ public class H2DatabaseTest extends BrambleTestCase {
 
 	@Test
 	public void testCloseWaitsForCommit() throws Exception {
-		final CountDownLatch closing = new CountDownLatch(1);
-		final CountDownLatch closed = new CountDownLatch(1);
-		final AtomicBoolean transactionFinished = new AtomicBoolean(false);
-		final AtomicBoolean error = new AtomicBoolean(false);
-		final Database<Connection> db = open(false);
+		CountDownLatch closing = new CountDownLatch(1);
+		CountDownLatch closed = new CountDownLatch(1);
+		AtomicBoolean transactionFinished = new AtomicBoolean(false);
+		AtomicBoolean error = new AtomicBoolean(false);
+		Database<Connection> db = open(false);
 
 		// Start a transaction
 		Connection txn = db.startTransaction();
 		// In another thread, close the database
-		Thread close = new Thread() {
-			@Override
-			public void run() {
-				try {
-					closing.countDown();
-					db.close();
-					if (!transactionFinished.get()) error.set(true);
-					closed.countDown();
-				} catch (Exception e) {
-					error.set(true);
-				}
+		Thread close = new Thread(() -> {
+			try {
+				closing.countDown();
+				db.close();
+				if (!transactionFinished.get()) error.set(true);
+				closed.countDown();
+			} catch (Exception e) {
+				error.set(true);
 			}
-		};
+		});
 		close.start();
 		closing.await();
 		// Do whatever the transaction needs to do
@@ -501,28 +498,25 @@ public class H2DatabaseTest extends BrambleTestCase {
 
 	@Test
 	public void testCloseWaitsForAbort() throws Exception {
-		final CountDownLatch closing = new CountDownLatch(1);
-		final CountDownLatch closed = new CountDownLatch(1);
-		final AtomicBoolean transactionFinished = new AtomicBoolean(false);
-		final AtomicBoolean error = new AtomicBoolean(false);
-		final Database<Connection> db = open(false);
+		CountDownLatch closing = new CountDownLatch(1);
+		CountDownLatch closed = new CountDownLatch(1);
+		AtomicBoolean transactionFinished = new AtomicBoolean(false);
+		AtomicBoolean error = new AtomicBoolean(false);
+		Database<Connection> db = open(false);
 
 		// Start a transaction
 		Connection txn = db.startTransaction();
 		// In another thread, close the database
-		Thread close = new Thread() {
-			@Override
-			public void run() {
-				try {
-					closing.countDown();
-					db.close();
-					if (!transactionFinished.get()) error.set(true);
-					closed.countDown();
-				} catch (Exception e) {
-					error.set(true);
-				}
+		Thread close = new Thread(() -> {
+			try {
+				closing.countDown();
+				db.close();
+				if (!transactionFinished.get()) error.set(true);
+				closed.countDown();
+			} catch (Exception e) {
+				error.set(true);
 			}
-		};
+		});
 		close.start();
 		closing.await();
 		// Do whatever the transaction needs to do
@@ -870,7 +864,7 @@ public class H2DatabaseTest extends BrambleTestCase {
 		assertEquals(0, db.countOfferedMessages(txn, contactId));
 
 		// Add some offered messages and count them
-		List<MessageId> ids = new ArrayList<MessageId>();
+		List<MessageId> ids = new ArrayList<>();
 		for (int i = 0; i < 10; i++) {
 			MessageId m = new MessageId(TestUtils.getRandomId());
 			db.addOfferedMessage(txn, contactId, m);
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/db/LockFairnessTest.java b/bramble-core/src/test/java/org/briarproject/bramble/db/LockFairnessTest.java
index 5b0d376106045dade93e12b2d0aea64f08e6e38e..7c89c0f08ccadd541b5c3fe93e9dfd54bca9fe2c 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/db/LockFairnessTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/db/LockFairnessTest.java
@@ -17,56 +17,50 @@ public class LockFairnessTest extends BrambleTestCase {
 	@Test
 	public void testReadersCanShareTheLock() throws Exception {
 		// Use a fair lock
-		final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
-		final CountDownLatch firstReaderHasLock = new CountDownLatch(1);
-		final CountDownLatch firstReaderHasFinished = new CountDownLatch(1);
-		final CountDownLatch secondReaderHasLock = new CountDownLatch(1);
-		final CountDownLatch secondReaderHasFinished = new CountDownLatch(1);
+		ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+		CountDownLatch firstReaderHasLock = new CountDownLatch(1);
+		CountDownLatch firstReaderHasFinished = new CountDownLatch(1);
+		CountDownLatch secondReaderHasLock = new CountDownLatch(1);
+		CountDownLatch secondReaderHasFinished = new CountDownLatch(1);
 		// First reader
-		Thread first = new Thread() {
-			@Override
-			public void run() {
+		Thread first = new Thread(() -> {
+			try {
+				// Acquire the lock
+				lock.readLock().lock();
 				try {
-					// Acquire the lock
-					lock.readLock().lock();
-					try {
-						// Allow the second reader to acquire the lock
-						firstReaderHasLock.countDown();
-						// Wait for the second reader to acquire the lock
-						assertTrue(secondReaderHasLock.await(10, SECONDS));
-					} finally {
-						// Release the lock
-						lock.readLock().unlock();
-					}
-				} catch (InterruptedException e) {
-					fail();
+					// Allow the second reader to acquire the lock
+					firstReaderHasLock.countDown();
+					// Wait for the second reader to acquire the lock
+					assertTrue(secondReaderHasLock.await(10, SECONDS));
+				} finally {
+					// Release the lock
+					lock.readLock().unlock();
 				}
-				firstReaderHasFinished.countDown();
+			} catch (InterruptedException e) {
+				fail();
 			}
-		};
+			firstReaderHasFinished.countDown();
+		});
 		first.start();
 		// Second reader
-		Thread second = new Thread() {
-			@Override
-			public void run() {
+		Thread second = new Thread(() -> {
+			try {
+				// Wait for the first reader to acquire the lock
+				assertTrue(firstReaderHasLock.await(10, SECONDS));
+				// Acquire the lock
+				lock.readLock().lock();
 				try {
-					// Wait for the first reader to acquire the lock
-					assertTrue(firstReaderHasLock.await(10, SECONDS));
-					// Acquire the lock
-					lock.readLock().lock();
-					try {
-						// Allow the first reader to release the lock
-						secondReaderHasLock.countDown();
-					} finally {
-						// Release the lock
-						lock.readLock().unlock();
-					}
-				} catch (InterruptedException e) {
-					fail();
+					// Allow the first reader to release the lock
+					secondReaderHasLock.countDown();
+				} finally {
+					// Release the lock
+					lock.readLock().unlock();
 				}
-				secondReaderHasFinished.countDown();
+			} catch (InterruptedException e) {
+				fail();
 			}
-		};
+			secondReaderHasFinished.countDown();
+		});
 		second.start();
 		// Wait for both readers to finish
 		assertTrue(firstReaderHasFinished.await(10, SECONDS));
@@ -76,86 +70,77 @@ public class LockFairnessTest extends BrambleTestCase {
 	@Test
 	public void testWritersDoNotStarve() throws Exception {
 		// Use a fair lock
-		final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
-		final CountDownLatch firstReaderHasLock = new CountDownLatch(1);
-		final CountDownLatch firstReaderHasFinished = new CountDownLatch(1);
-		final CountDownLatch secondReaderHasFinished = new CountDownLatch(1);
-		final CountDownLatch writerHasFinished = new CountDownLatch(1);
-		final AtomicBoolean secondReaderHasHeldLock = new AtomicBoolean(false);
-		final AtomicBoolean writerHasHeldLock = new AtomicBoolean(false);
+		ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+		CountDownLatch firstReaderHasLock = new CountDownLatch(1);
+		CountDownLatch firstReaderHasFinished = new CountDownLatch(1);
+		CountDownLatch secondReaderHasFinished = new CountDownLatch(1);
+		CountDownLatch writerHasFinished = new CountDownLatch(1);
+		AtomicBoolean secondReaderHasHeldLock = new AtomicBoolean(false);
+		AtomicBoolean writerHasHeldLock = new AtomicBoolean(false);
 		// First reader
-		Thread first = new Thread() {
-			@Override
-			public void run() {
+		Thread first = new Thread(() -> {
+			try {
+				// Acquire the lock
+				lock.readLock().lock();
 				try {
-					// Acquire the lock
-					lock.readLock().lock();
-					try {
-						// Allow the other threads to acquire the lock
-						firstReaderHasLock.countDown();
-						// Wait for both other threads to wait for the lock
-						while (lock.getQueueLength() < 2) Thread.sleep(10);
-						// No other thread should have acquired the lock
-						assertFalse(secondReaderHasHeldLock.get());
-						assertFalse(writerHasHeldLock.get());
-					} finally {
-						// Release the lock
-						lock.readLock().unlock();
-					}
-				} catch (InterruptedException e) {
-					fail();
+					// Allow the other threads to acquire the lock
+					firstReaderHasLock.countDown();
+					// Wait for both other threads to wait for the lock
+					while (lock.getQueueLength() < 2) Thread.sleep(10);
+					// No other thread should have acquired the lock
+					assertFalse(secondReaderHasHeldLock.get());
+					assertFalse(writerHasHeldLock.get());
+				} finally {
+					// Release the lock
+					lock.readLock().unlock();
 				}
-				firstReaderHasFinished.countDown();
+			} catch (InterruptedException e) {
+				fail();
 			}
-		};
+			firstReaderHasFinished.countDown();
+		});
 		first.start();
 		// Writer
-		Thread writer = new Thread() {
-			@Override
-			public void run() {
+		Thread writer = new Thread(() -> {
+			try {
+				// Wait for the first reader to acquire the lock
+				assertTrue(firstReaderHasLock.await(10, SECONDS));
+				// Acquire the lock
+				lock.writeLock().lock();
 				try {
-					// Wait for the first reader to acquire the lock
-					assertTrue(firstReaderHasLock.await(10, SECONDS));
-					// Acquire the lock
-					lock.writeLock().lock();
-					try {
-						writerHasHeldLock.set(true);
-						// The second reader should not overtake the writer
-						assertFalse(secondReaderHasHeldLock.get());
-					} finally {
-						lock.writeLock().unlock();
-					}
-				} catch (InterruptedException e) {
-					fail();
+					writerHasHeldLock.set(true);
+					// The second reader should not overtake the writer
+					assertFalse(secondReaderHasHeldLock.get());
+				} finally {
+					lock.writeLock().unlock();
 				}
-				writerHasFinished.countDown();
+			} catch (InterruptedException e) {
+				fail();
 			}
-		};
+			writerHasFinished.countDown();
+		});
 		writer.start();
 		// Second reader
-		Thread second = new Thread() {
-			@Override
-			public void run() {
+		Thread second = new Thread(() -> {
+			try {
+				// Wait for the first reader to acquire the lock
+				assertTrue(firstReaderHasLock.await(10, SECONDS));
+				// Wait for the writer to wait for the lock
+				while (lock.getQueueLength() < 1) Thread.sleep(10);
+				// Acquire the lock
+				lock.readLock().lock();
 				try {
-					// Wait for the first reader to acquire the lock
-					assertTrue(firstReaderHasLock.await(10, SECONDS));
-					// Wait for the writer to wait for the lock
-					while (lock.getQueueLength() < 1) Thread.sleep(10);
-					// Acquire the lock
-					lock.readLock().lock();
-					try {
-						secondReaderHasHeldLock.set(true);
-						// The second reader should not overtake the writer
-						assertTrue(writerHasHeldLock.get());
-					} finally {
-						lock.readLock().unlock();
-					}
-				} catch (InterruptedException e) {
-					fail();
+					secondReaderHasHeldLock.set(true);
+					// The second reader should not overtake the writer
+					assertTrue(writerHasHeldLock.get());
+				} finally {
+					lock.readLock().unlock();
 				}
-				secondReaderHasFinished.countDown();
+			} catch (InterruptedException e) {
+				fail();
 			}
-		};
+			secondReaderHasFinished.countDown();
+		});
 		second.start();
 		// Wait for all the threads to finish
 		assertTrue(firstReaderHasFinished.await(10, SECONDS));
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java
index e65354671422b19e4636eb01ff73c9b5e5ce3fcf..2a6e56ee01749844e284fe852fe566bf4b7e29a1 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java
@@ -80,8 +80,8 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testGetAuthorStatus() throws DbException {
-		final AuthorId authorId = new AuthorId(TestUtils.getRandomId());
-		final Collection<Contact> contacts = new ArrayList<Contact>();
+		AuthorId authorId = new AuthorId(TestUtils.getRandomId());
+		Collection<Contact> contacts = new ArrayList<>();
 
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(true);
@@ -125,8 +125,8 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
 				identityManager.getAuthorStatus(localAuthor.getId()));
 	}
 
-	private void checkAuthorStatusContext(final AuthorId authorId,
-			final Collection<Contact> contacts) throws DbException {
+	private void checkAuthorStatusContext(AuthorId authorId,
+			Collection<Contact> contacts) throws DbException {
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn));
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/keyagreement/KeyAgreementProtocolTest.java b/bramble-core/src/test/java/org/briarproject/bramble/keyagreement/KeyAgreementProtocolTest.java
index cac8923d1296bd0fa69165c0f18d932a72bdca7d..a737328780331e290cdd73a0346541098a141d23 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/keyagreement/KeyAgreementProtocolTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/keyagreement/KeyAgreementProtocolTest.java
@@ -65,11 +65,11 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
 	@Test
 	public void testAliceProtocol() throws Exception {
 		// set up
-		final Payload theirPayload = new Payload(BOB_COMMIT, null);
-		final Payload ourPayload = new Payload(ALICE_COMMIT, null);
-		final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
-		final SecretKey sharedSecret = TestUtils.getSecretKey();
-		final SecretKey masterSecret = TestUtils.getSecretKey();
+		Payload theirPayload = new Payload(BOB_COMMIT, null);
+		Payload ourPayload = new Payload(ALICE_COMMIT, null);
+		KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
+		SecretKey sharedSecret = TestUtils.getSecretKey();
+		SecretKey masterSecret = TestUtils.getSecretKey();
 
 		KeyAgreementProtocol protocol =
 				new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
@@ -129,11 +129,11 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
 	@Test
 	public void testBobProtocol() throws Exception {
 		// set up
-		final Payload theirPayload = new Payload(ALICE_COMMIT, null);
-		final Payload ourPayload = new Payload(BOB_COMMIT, null);
-		final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
-		final SecretKey sharedSecret = TestUtils.getSecretKey();
-		final SecretKey masterSecret = TestUtils.getSecretKey();
+		Payload theirPayload = new Payload(ALICE_COMMIT, null);
+		Payload ourPayload = new Payload(BOB_COMMIT, null);
+		KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
+		SecretKey sharedSecret = TestUtils.getSecretKey();
+		SecretKey masterSecret = TestUtils.getSecretKey();
 
 		KeyAgreementProtocol protocol =
 				new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
@@ -192,9 +192,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
 	@Test(expected = AbortException.class)
 	public void testAliceProtocolAbortOnBadKey() throws Exception {
 		// set up
-		final Payload theirPayload = new Payload(BOB_COMMIT, null);
-		final Payload ourPayload = new Payload(ALICE_COMMIT, null);
-		final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
+		Payload theirPayload = new Payload(BOB_COMMIT, null);
+		Payload ourPayload = new Payload(ALICE_COMMIT, null);
+		KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
 
 		KeyAgreementProtocol protocol =
 				new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
@@ -233,9 +233,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
 	@Test(expected = AbortException.class)
 	public void testBobProtocolAbortOnBadKey() throws Exception {
 		// set up
-		final Payload theirPayload = new Payload(ALICE_COMMIT, null);
-		final Payload ourPayload = new Payload(BOB_COMMIT, null);
-		final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
+		Payload theirPayload = new Payload(ALICE_COMMIT, null);
+		Payload ourPayload = new Payload(BOB_COMMIT, null);
+		KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
 
 		KeyAgreementProtocol protocol =
 				new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
@@ -270,10 +270,10 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
 	@Test(expected = AbortException.class)
 	public void testAliceProtocolAbortOnBadConfirm() throws Exception {
 		// set up
-		final Payload theirPayload = new Payload(BOB_COMMIT, null);
-		final Payload ourPayload = new Payload(ALICE_COMMIT, null);
-		final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
-		final SecretKey sharedSecret = TestUtils.getSecretKey();
+		Payload theirPayload = new Payload(BOB_COMMIT, null);
+		Payload ourPayload = new Payload(ALICE_COMMIT, null);
+		KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
+		SecretKey sharedSecret = TestUtils.getSecretKey();
 
 		KeyAgreementProtocol protocol =
 				new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
@@ -335,10 +335,10 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
 	@Test(expected = AbortException.class)
 	public void testBobProtocolAbortOnBadConfirm() throws Exception {
 		// set up
-		final Payload theirPayload = new Payload(ALICE_COMMIT, null);
-		final Payload ourPayload = new Payload(BOB_COMMIT, null);
-		final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
-		final SecretKey sharedSecret = TestUtils.getSecretKey();
+		Payload theirPayload = new Payload(ALICE_COMMIT, null);
+		Payload ourPayload = new Payload(BOB_COMMIT, null);
+		KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
+		SecretKey sharedSecret = TestUtils.getSecretKey();
 
 		KeyAgreementProtocol protocol =
 				new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/lifecycle/ShutdownManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/lifecycle/ShutdownManagerImplTest.java
index f4fc1ed706b48adb8f1d89eeedb3bda6b0b9e155..a4d439b24122bb4cc048b5ecc28707929f607025 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/lifecycle/ShutdownManagerImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/lifecycle/ShutdownManagerImplTest.java
@@ -15,13 +15,9 @@ public class ShutdownManagerImplTest extends BrambleTestCase {
 	@Test
 	public void testAddAndRemove() {
 		ShutdownManager s = createShutdownManager();
-		Set<Integer> handles = new HashSet<Integer>();
+		Set<Integer> handles = new HashSet<>();
 		for (int i = 0; i < 100; i++) {
-			int handle = s.addShutdownHook(new Runnable() {
-				@Override
-				public void run() {
-				}
-			});
+			int handle = s.addShutdownHook(() -> {});
 			// The handles should all be distinct
 			assertTrue(handles.add(handle));
 		}
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/ConnectionRegistryImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/ConnectionRegistryImplTest.java
index dba85a6b2ab33bd16630810d25b4664a67a5b4c2..f0841bc8e7d2e225c30678f52b7ced4f41816b58 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/ConnectionRegistryImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/ConnectionRegistryImplTest.java
@@ -35,7 +35,7 @@ public class ConnectionRegistryImplTest extends BrambleTestCase {
 	@Test
 	public void testRegisterAndUnregister() {
 		Mockery context = new Mockery();
-		final EventBus eventBus = context.mock(EventBus.class);
+		EventBus eventBus = context.mock(EventBus.class);
 		context.checking(new Expectations() {{
 			exactly(5).of(eventBus).broadcast(with(any(
 					ConnectionOpenedEvent.class)));
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java
index 23a40ed20db4ae08451dcf22a12d58e512366ce6..2bcc22c0fa5d477c8c9d52efcd965481d797df9e 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java
@@ -30,36 +30,36 @@ public class PluginManagerImplTest extends BrambleTestCase {
 		Mockery context = new Mockery() {{
 			setThreadingPolicy(new Synchroniser());
 		}};
-		final Executor ioExecutor = Executors.newSingleThreadExecutor();
-		final EventBus eventBus = context.mock(EventBus.class);
-		final PluginConfig pluginConfig = context.mock(PluginConfig.class);
-		final ConnectionManager connectionManager =
+		Executor ioExecutor = Executors.newSingleThreadExecutor();
+		EventBus eventBus = context.mock(EventBus.class);
+		PluginConfig pluginConfig = context.mock(PluginConfig.class);
+		ConnectionManager connectionManager =
 				context.mock(ConnectionManager.class);
-		final SettingsManager settingsManager =
+		SettingsManager settingsManager =
 				context.mock(SettingsManager.class);
-		final TransportPropertyManager transportPropertyManager =
+		TransportPropertyManager transportPropertyManager =
 				context.mock(TransportPropertyManager.class);
-		final UiCallback uiCallback = context.mock(UiCallback.class);
+		UiCallback uiCallback = context.mock(UiCallback.class);
 
 		// Two simplex plugin factories: both create plugins, one fails to start
-		final SimplexPluginFactory simplexFactory =
+		SimplexPluginFactory simplexFactory =
 				context.mock(SimplexPluginFactory.class);
-		final SimplexPlugin simplexPlugin = context.mock(SimplexPlugin.class);
-		final TransportId simplexId = new TransportId("simplex");
-		final SimplexPluginFactory simplexFailFactory =
+		SimplexPlugin simplexPlugin = context.mock(SimplexPlugin.class);
+		TransportId simplexId = new TransportId("simplex");
+		SimplexPluginFactory simplexFailFactory =
 				context.mock(SimplexPluginFactory.class, "simplexFailFactory");
-		final SimplexPlugin simplexFailPlugin =
+		SimplexPlugin simplexFailPlugin =
 				context.mock(SimplexPlugin.class, "simplexFailPlugin");
-		final TransportId simplexFailId = new TransportId("simplex1");
+		TransportId simplexFailId = new TransportId("simplex1");
 
 		// Two duplex plugin factories: one creates a plugin, the other fails
-		final DuplexPluginFactory duplexFactory =
+		DuplexPluginFactory duplexFactory =
 				context.mock(DuplexPluginFactory.class);
-		final DuplexPlugin duplexPlugin = context.mock(DuplexPlugin.class);
-		final TransportId duplexId = new TransportId("duplex");
-		final DuplexPluginFactory duplexFailFactory =
+		DuplexPlugin duplexPlugin = context.mock(DuplexPlugin.class);
+		TransportId duplexId = new TransportId("duplex");
+		DuplexPluginFactory duplexFailFactory =
 				context.mock(DuplexPluginFactory.class, "duplexFailFactory");
-		final TransportId duplexFailId = new TransportId("duplex1");
+		TransportId duplexFailId = new TransportId("duplex1");
 
 		context.checking(new Expectations() {{
 			allowing(simplexPlugin).getId();
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerTest.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerTest.java
index 89afcdf85f632796e35c71def0ff1e1e24dee112..8d9a975a766f3e858f877cfc768c10a1615d95b1 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerTest.java
@@ -42,35 +42,35 @@ public class PollerTest extends BrambleTestCase {
 	public void testConnectOnContactStatusChanged() throws Exception {
 		Mockery context = new Mockery();
 		context.setImposteriser(ClassImposteriser.INSTANCE);
-		final Executor ioExecutor = new ImmediateExecutor();
-		final ScheduledExecutorService scheduler =
+		Executor ioExecutor = new ImmediateExecutor();
+		ScheduledExecutorService scheduler =
 				context.mock(ScheduledExecutorService.class);
-		final ConnectionManager connectionManager =
+		ConnectionManager connectionManager =
 				context.mock(ConnectionManager.class);
-		final ConnectionRegistry connectionRegistry =
+		ConnectionRegistry connectionRegistry =
 				context.mock(ConnectionRegistry.class);
-		final PluginManager pluginManager = context.mock(PluginManager.class);
-		final SecureRandom random = context.mock(SecureRandom.class);
-		final Clock clock = context.mock(Clock.class);
+		PluginManager pluginManager = context.mock(PluginManager.class);
+		SecureRandom random = context.mock(SecureRandom.class);
+		Clock clock = context.mock(Clock.class);
 
 		// Two simplex plugins: one supports polling, the other doesn't
-		final SimplexPlugin simplexPlugin = context.mock(SimplexPlugin.class);
-		final SimplexPlugin simplexPlugin1 =
+		SimplexPlugin simplexPlugin = context.mock(SimplexPlugin.class);
+		SimplexPlugin simplexPlugin1 =
 				context.mock(SimplexPlugin.class, "simplexPlugin1");
-		final TransportId simplexId1 = new TransportId("simplex1");
-		final List<SimplexPlugin> simplexPlugins = Arrays.asList(simplexPlugin,
+		TransportId simplexId1 = new TransportId("simplex1");
+		List<SimplexPlugin> simplexPlugins = Arrays.asList(simplexPlugin,
 				simplexPlugin1);
-		final TransportConnectionWriter simplexWriter =
+		TransportConnectionWriter simplexWriter =
 				context.mock(TransportConnectionWriter.class);
 
 		// Two duplex plugins: one supports polling, the other doesn't
-		final DuplexPlugin duplexPlugin = context.mock(DuplexPlugin.class);
-		final TransportId duplexId = new TransportId("duplex");
-		final DuplexPlugin duplexPlugin1 =
+		DuplexPlugin duplexPlugin = context.mock(DuplexPlugin.class);
+		TransportId duplexId = new TransportId("duplex");
+		DuplexPlugin duplexPlugin1 =
 				context.mock(DuplexPlugin.class, "duplexPlugin1");
-		final List<DuplexPlugin> duplexPlugins = Arrays.asList(duplexPlugin,
+		List<DuplexPlugin> duplexPlugins = Arrays.asList(duplexPlugin,
 				duplexPlugin1);
-		final DuplexTransportConnection duplexConnection =
+		DuplexTransportConnection duplexConnection =
 				context.mock(DuplexTransportConnection.class);
 
 		context.checking(new Expectations() {{
@@ -129,20 +129,20 @@ public class PollerTest extends BrambleTestCase {
 			throws Exception {
 		Mockery context = new Mockery();
 		context.setImposteriser(ClassImposteriser.INSTANCE);
-		final Executor ioExecutor = new ImmediateExecutor();
-		final ScheduledExecutorService scheduler =
+		Executor ioExecutor = new ImmediateExecutor();
+		ScheduledExecutorService scheduler =
 				context.mock(ScheduledExecutorService.class);
-		final ConnectionManager connectionManager =
+		ConnectionManager connectionManager =
 				context.mock(ConnectionManager.class);
-		final ConnectionRegistry connectionRegistry =
+		ConnectionRegistry connectionRegistry =
 				context.mock(ConnectionRegistry.class);
-		final PluginManager pluginManager = context.mock(PluginManager.class);
-		final SecureRandom random = context.mock(SecureRandom.class);
-		final Clock clock = context.mock(Clock.class);
+		PluginManager pluginManager = context.mock(PluginManager.class);
+		SecureRandom random = context.mock(SecureRandom.class);
+		Clock clock = context.mock(Clock.class);
 
-		final DuplexPlugin plugin = context.mock(DuplexPlugin.class);
-		final TransportId transportId = new TransportId("id");
-		final DuplexTransportConnection duplexConnection =
+		DuplexPlugin plugin = context.mock(DuplexPlugin.class);
+		TransportId transportId = new TransportId("id");
+		DuplexTransportConnection duplexConnection =
 				context.mock(DuplexTransportConnection.class);
 
 		context.checking(new Expectations() {{
@@ -194,19 +194,19 @@ public class PollerTest extends BrambleTestCase {
 	public void testRescheduleOnConnectionOpened() throws Exception {
 		Mockery context = new Mockery();
 		context.setImposteriser(ClassImposteriser.INSTANCE);
-		final Executor ioExecutor = new ImmediateExecutor();
-		final ScheduledExecutorService scheduler =
+		Executor ioExecutor = new ImmediateExecutor();
+		ScheduledExecutorService scheduler =
 				context.mock(ScheduledExecutorService.class);
-		final ConnectionManager connectionManager =
+		ConnectionManager connectionManager =
 				context.mock(ConnectionManager.class);
-		final ConnectionRegistry connectionRegistry =
+		ConnectionRegistry connectionRegistry =
 				context.mock(ConnectionRegistry.class);
-		final PluginManager pluginManager = context.mock(PluginManager.class);
-		final SecureRandom random = context.mock(SecureRandom.class);
-		final Clock clock = context.mock(Clock.class);
+		PluginManager pluginManager = context.mock(PluginManager.class);
+		SecureRandom random = context.mock(SecureRandom.class);
+		Clock clock = context.mock(Clock.class);
 
-		final DuplexPlugin plugin = context.mock(DuplexPlugin.class);
-		final TransportId transportId = new TransportId("id");
+		DuplexPlugin plugin = context.mock(DuplexPlugin.class);
+		TransportId transportId = new TransportId("id");
 
 		context.checking(new Expectations() {{
 			allowing(plugin).getId();
@@ -239,19 +239,19 @@ public class PollerTest extends BrambleTestCase {
 	public void testRescheduleDoesNotReplaceEarlierTask() throws Exception {
 		Mockery context = new Mockery();
 		context.setImposteriser(ClassImposteriser.INSTANCE);
-		final Executor ioExecutor = new ImmediateExecutor();
-		final ScheduledExecutorService scheduler =
+		Executor ioExecutor = new ImmediateExecutor();
+		ScheduledExecutorService scheduler =
 				context.mock(ScheduledExecutorService.class);
-		final ConnectionManager connectionManager =
+		ConnectionManager connectionManager =
 				context.mock(ConnectionManager.class);
-		final ConnectionRegistry connectionRegistry =
+		ConnectionRegistry connectionRegistry =
 				context.mock(ConnectionRegistry.class);
-		final PluginManager pluginManager = context.mock(PluginManager.class);
-		final SecureRandom random = context.mock(SecureRandom.class);
-		final Clock clock = context.mock(Clock.class);
+		PluginManager pluginManager = context.mock(PluginManager.class);
+		SecureRandom random = context.mock(SecureRandom.class);
+		Clock clock = context.mock(Clock.class);
 
-		final DuplexPlugin plugin = context.mock(DuplexPlugin.class);
-		final TransportId transportId = new TransportId("id");
+		DuplexPlugin plugin = context.mock(DuplexPlugin.class);
+		TransportId transportId = new TransportId("id");
 
 		context.checking(new Expectations() {{
 			allowing(plugin).getId();
@@ -299,20 +299,20 @@ public class PollerTest extends BrambleTestCase {
 	public void testPollOnTransportEnabled() throws Exception {
 		Mockery context = new Mockery();
 		context.setImposteriser(ClassImposteriser.INSTANCE);
-		final Executor ioExecutor = new ImmediateExecutor();
-		final ScheduledExecutorService scheduler =
+		Executor ioExecutor = new ImmediateExecutor();
+		ScheduledExecutorService scheduler =
 				context.mock(ScheduledExecutorService.class);
-		final ConnectionManager connectionManager =
+		ConnectionManager connectionManager =
 				context.mock(ConnectionManager.class);
-		final ConnectionRegistry connectionRegistry =
+		ConnectionRegistry connectionRegistry =
 				context.mock(ConnectionRegistry.class);
-		final PluginManager pluginManager = context.mock(PluginManager.class);
-		final SecureRandom random = context.mock(SecureRandom.class);
-		final Clock clock = context.mock(Clock.class);
+		PluginManager pluginManager = context.mock(PluginManager.class);
+		SecureRandom random = context.mock(SecureRandom.class);
+		Clock clock = context.mock(Clock.class);
 
-		final Plugin plugin = context.mock(Plugin.class);
-		final TransportId transportId = new TransportId("id");
-		final List<ContactId> connected = Collections.singletonList(contactId);
+		Plugin plugin = context.mock(Plugin.class);
+		TransportId transportId = new TransportId("id");
+		List<ContactId> connected = Collections.singletonList(contactId);
 
 		context.checking(new Expectations() {{
 			allowing(plugin).getId();
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java
index 7f65a2460dfd707ee9c8e8f33f5264b47c253454..b4f360c7b53bddbc46b6e7d3ba62dd1998feb272 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java
@@ -145,11 +145,11 @@ public class LanTcpPluginTest extends BrambleTestCase {
 		assertEquals(2, split.length);
 		String addrString = split[0];
 		// Listen on the same interface as the plugin
-		final ServerSocket ss = new ServerSocket();
+		ServerSocket ss = new ServerSocket();
 		ss.bind(new InetSocketAddress(addrString, 0), 10);
 		int port = ss.getLocalPort();
-		final CountDownLatch latch = new CountDownLatch(1);
-		final AtomicBoolean error = new AtomicBoolean(false);
+		CountDownLatch latch = new CountDownLatch(1);
+		AtomicBoolean error = new AtomicBoolean(false);
 		new Thread() {
 			@Override
 			public void run() {
@@ -194,8 +194,7 @@ public class LanTcpPluginTest extends BrambleTestCase {
 				plugin.createKeyAgreementListener(new byte[COMMIT_LENGTH]);
 		assertNotNull(kal);
 		Callable<KeyAgreementConnection> c = kal.listen();
-		FutureTask<KeyAgreementConnection> f =
-				new FutureTask<KeyAgreementConnection>(c);
+		FutureTask<KeyAgreementConnection> f = new FutureTask<>(c);
 		new Thread(f).start();
 		// The plugin should have bound a socket and stored the port number
 		BdfList descriptor = kal.getDescriptor();
@@ -240,10 +239,10 @@ public class LanTcpPluginTest extends BrambleTestCase {
 		assertEquals(2, split.length);
 		String addrString = split[0];
 		// Listen on the same interface as the plugin
-		final ServerSocket ss = new ServerSocket();
+		ServerSocket ss = new ServerSocket();
 		ss.bind(new InetSocketAddress(addrString, 0), 10);
-		final CountDownLatch latch = new CountDownLatch(1);
-		final AtomicBoolean error = new AtomicBoolean(false);
+		CountDownLatch latch = new CountDownLatch(1);
+		AtomicBoolean error = new AtomicBoolean(false);
 		new Thread() {
 			@Override
 			public void run() {
@@ -291,7 +290,7 @@ public class LanTcpPluginTest extends BrambleTestCase {
 	private static class Callback implements DuplexPluginCallback {
 
 		private final Map<ContactId, TransportProperties> remote =
-				new Hashtable<ContactId, TransportProperties>();
+				new Hashtable<>();
 		private final CountDownLatch propertiesLatch = new CountDownLatch(1);
 		private final CountDownLatch connectionsLatch = new CountDownLatch(1);
 		private final TransportProperties local = new TransportProperties();
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/properties/TransportPropertyManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/properties/TransportPropertyManagerImplTest.java
index 245a4d01df532a4e374dfc4eed0b9c8e835a7dd4..ee3a2643bc987088b78784489a84afd6fc884be2 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/properties/TransportPropertyManagerImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/properties/TransportPropertyManagerImplTest.java
@@ -87,11 +87,11 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testCreatesGroupsAtStartup() throws Exception {
-		final Transaction txn = new Transaction(null, false);
-		final Contact contact1 = getContact(true);
-		final Contact contact2 = getContact(true);
-		final List<Contact> contacts = Arrays.asList(contact1, contact2);
-		final Group contactGroup1 = getGroup(), contactGroup2 = getGroup();
+		Transaction txn = new Transaction(null, false);
+		Contact contact1 = getContact(true);
+		Contact contact2 = getContact(true);
+		List<Contact> contacts = Arrays.asList(contact1, contact2);
+		Group contactGroup1 = getGroup(), contactGroup2 = getGroup();
 
 		context.checking(new Expectations() {{
 			oneOf(db).addGroup(txn, localGroup);
@@ -124,9 +124,9 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testCreatesGroupWhenAddingContact() throws Exception {
-		final Transaction txn = new Transaction(null, false);
-		final Contact contact = getContact(true);
-		final Group contactGroup = getGroup();
+		Transaction txn = new Transaction(null, false);
+		Contact contact = getContact(true);
+		Group contactGroup = getGroup();
 
 		context.checking(new Expectations() {{
 			// Create the group and share it with the contact
@@ -151,9 +151,9 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testRemovesGroupWhenRemovingContact() throws Exception {
-		final Transaction txn = new Transaction(null, false);
-		final Contact contact = getContact(true);
-		final Group contactGroup = getGroup();
+		Transaction txn = new Transaction(null, false);
+		Contact contact = getContact(true);
+		Group contactGroup = getGroup();
 
 		context.checking(new Expectations() {{
 			oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, contact);
@@ -168,18 +168,18 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 	@Test
 	public void testDoesNotDeleteAnythingWhenFirstUpdateIsDelivered()
 			throws Exception {
-		final Transaction txn = new Transaction(null, false);
-		final GroupId contactGroupId = new GroupId(getRandomId());
-		final long timestamp = 123456789;
-		final Message message = getMessage(contactGroupId, timestamp);
-		final Metadata meta = new Metadata();
-		final BdfDictionary metaDictionary = BdfDictionary.of(
+		Transaction txn = new Transaction(null, false);
+		GroupId contactGroupId = new GroupId(getRandomId());
+		long timestamp = 123456789;
+		Message message = getMessage(contactGroupId, timestamp);
+		Metadata meta = new Metadata();
+		BdfDictionary metaDictionary = BdfDictionary.of(
 				new BdfEntry("transportId", "foo"),
 				new BdfEntry("version", 2),
 				new BdfEntry("local", false)
 		);
-		final Map<MessageId, BdfDictionary> messageMetadata =
-				new LinkedHashMap<MessageId, BdfDictionary>();
+		Map<MessageId, BdfDictionary> messageMetadata =
+				new LinkedHashMap<>();
 		// A remote update for another transport should be ignored
 		MessageId barUpdateId = new MessageId(getRandomId());
 		messageMetadata.put(barUpdateId, BdfDictionary.of(
@@ -210,32 +210,32 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 	@Test
 	public void testDeletesOlderUpdatesWhenUpdateIsDelivered()
 			throws Exception {
-		final Transaction txn = new Transaction(null, false);
-		final GroupId contactGroupId = new GroupId(getRandomId());
-		final long timestamp = 123456789;
-		final Message message = getMessage(contactGroupId, timestamp);
-		final Metadata meta = new Metadata();
-		final BdfDictionary metaDictionary = BdfDictionary.of(
+		Transaction txn = new Transaction(null, false);
+		GroupId contactGroupId = new GroupId(getRandomId());
+		long timestamp = 123456789;
+		Message message = getMessage(contactGroupId, timestamp);
+		Metadata meta = new Metadata();
+		BdfDictionary metaDictionary = BdfDictionary.of(
 				new BdfEntry("transportId", "foo"),
 				new BdfEntry("version", 4),
 				new BdfEntry("local", false)
 		);
-		final Map<MessageId, BdfDictionary> messageMetadata =
-				new LinkedHashMap<MessageId, BdfDictionary>();
+		Map<MessageId, BdfDictionary> messageMetadata =
+				new LinkedHashMap<>();
 		// Old remote updates for the same transport should be deleted
-		final MessageId fooVersion2 = new MessageId(getRandomId());
+		MessageId fooVersion2 = new MessageId(getRandomId());
 		messageMetadata.put(fooVersion2, BdfDictionary.of(
 				new BdfEntry("transportId", "foo"),
 				new BdfEntry("version", 2),
 				new BdfEntry("local", false)
 		));
-		final MessageId fooVersion1 = new MessageId(getRandomId());
+		MessageId fooVersion1 = new MessageId(getRandomId());
 		messageMetadata.put(fooVersion1, BdfDictionary.of(
 				new BdfEntry("transportId", "foo"),
 				new BdfEntry("version", 1),
 				new BdfEntry("local", false)
 		));
-		final MessageId fooVersion3 = new MessageId(getRandomId());
+		MessageId fooVersion3 = new MessageId(getRandomId());
 		messageMetadata.put(fooVersion3, BdfDictionary.of(
 				new BdfEntry("transportId", "foo"),
 				new BdfEntry("version", 3),
@@ -263,33 +263,33 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testDeletesObsoleteUpdateWhenDelivered() throws Exception {
-		final Transaction txn = new Transaction(null, false);
-		final GroupId contactGroupId = new GroupId(getRandomId());
-		final long timestamp = 123456789;
-		final Message message = getMessage(contactGroupId, timestamp);
-		final Metadata meta = new Metadata();
-		final BdfDictionary metaDictionary = BdfDictionary.of(
+		Transaction txn = new Transaction(null, false);
+		GroupId contactGroupId = new GroupId(getRandomId());
+		long timestamp = 123456789;
+		Message message = getMessage(contactGroupId, timestamp);
+		Metadata meta = new Metadata();
+		BdfDictionary metaDictionary = BdfDictionary.of(
 				new BdfEntry("transportId", "foo"),
 				new BdfEntry("version", 3),
 				new BdfEntry("local", false)
 		);
-		final Map<MessageId, BdfDictionary> messageMetadata =
-				new LinkedHashMap<MessageId, BdfDictionary>();
+		Map<MessageId, BdfDictionary> messageMetadata =
+				new LinkedHashMap<>();
 		// Old remote updates for the same transport should be deleted
-		final MessageId fooVersion2 = new MessageId(getRandomId());
+		MessageId fooVersion2 = new MessageId(getRandomId());
 		messageMetadata.put(fooVersion2, BdfDictionary.of(
 				new BdfEntry("transportId", "foo"),
 				new BdfEntry("version", 2),
 				new BdfEntry("local", false)
 		));
-		final MessageId fooVersion1 = new MessageId(getRandomId());
+		MessageId fooVersion1 = new MessageId(getRandomId());
 		messageMetadata.put(fooVersion1, BdfDictionary.of(
 				new BdfEntry("transportId", "foo"),
 				new BdfEntry("version", 1),
 				new BdfEntry("local", false)
 		));
 		// A newer remote update for the same transport should not be deleted
-		final MessageId fooVersion4 = new MessageId(getRandomId());
+		MessageId fooVersion4 = new MessageId(getRandomId());
 		messageMetadata.put(fooVersion4, BdfDictionary.of(
 				new BdfEntry("transportId", "foo"),
 				new BdfEntry("version", 4),
@@ -318,11 +318,11 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testStoresRemotePropertiesWithVersion0() throws Exception {
-		final Contact contact = getContact(true);
-		final Group contactGroup = getGroup();
-		final Transaction txn = new Transaction(null, false);
+		Contact contact = getContact(true);
+		Group contactGroup = getGroup();
+		Transaction txn = new Transaction(null, false);
 		Map<TransportId, TransportProperties> properties =
-				new LinkedHashMap<TransportId, TransportProperties>();
+				new LinkedHashMap<>();
 		properties.put(new TransportId("foo"), fooProperties);
 		properties.put(new TransportId("bar"), barProperties);
 
@@ -357,9 +357,9 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 	@Test
 	public void testReturnsEmptyPropertiesIfNoLocalPropertiesAreFound()
 			throws Exception {
-		final Transaction txn = new Transaction(null, false);
-		final Map<MessageId, BdfDictionary> messageMetadata =
-				new LinkedHashMap<MessageId, BdfDictionary>();
+		Transaction txn = new Transaction(null, false);
+		Map<MessageId, BdfDictionary> messageMetadata =
+				new LinkedHashMap<>();
 		// A local update for another transport should be ignored
 		MessageId barUpdateId = new MessageId(getRandomId());
 		messageMetadata.put(barUpdateId, BdfDictionary.of(
@@ -384,9 +384,9 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testReturnsLocalProperties() throws Exception {
-		final Transaction txn = new Transaction(null, false);
-		final Map<MessageId, BdfDictionary> messageMetadata =
-				new LinkedHashMap<MessageId, BdfDictionary>();
+		Transaction txn = new Transaction(null, false);
+		Map<MessageId, BdfDictionary> messageMetadata =
+				new LinkedHashMap<>();
 		// A local update for another transport should be ignored
 		MessageId barUpdateId = new MessageId(getRandomId());
 		messageMetadata.put(barUpdateId, BdfDictionary.of(
@@ -395,13 +395,13 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 				new BdfEntry("local", true)
 		));
 		// A local update for the right transport should be returned
-		final MessageId fooUpdateId = new MessageId(getRandomId());
+		MessageId fooUpdateId = new MessageId(getRandomId());
 		messageMetadata.put(fooUpdateId, BdfDictionary.of(
 				new BdfEntry("transportId", "foo"),
 				new BdfEntry("version", 1),
 				new BdfEntry("local", true)
 		));
-		final BdfList fooUpdate = BdfList.of("foo", 1, fooPropertiesDict);
+		BdfList fooUpdate = BdfList.of("foo", 1, fooPropertiesDict);
 
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(false);
@@ -423,16 +423,16 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 	@Test
 	public void testReturnsRemotePropertiesOrEmptyProperties()
 			throws Exception {
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 		Contact contact1 = getContact(false);
-		final Contact contact2 = getContact(true);
-		final Contact contact3 = getContact(true);
-		final List<Contact> contacts =
+		Contact contact2 = getContact(true);
+		Contact contact3 = getContact(true);
+		List<Contact> contacts =
 				Arrays.asList(contact1, contact2, contact3);
-		final Group contactGroup2 = getGroup();
-		final Group contactGroup3 = getGroup();
-		final Map<MessageId, BdfDictionary> messageMetadata3 =
-				new LinkedHashMap<MessageId, BdfDictionary>();
+		Group contactGroup2 = getGroup();
+		Group contactGroup3 = getGroup();
+		Map<MessageId, BdfDictionary> messageMetadata3 =
+				new LinkedHashMap<>();
 		// A remote update for another transport should be ignored
 		MessageId barUpdateId = new MessageId(getRandomId());
 		messageMetadata3.put(barUpdateId, BdfDictionary.of(
@@ -448,13 +448,13 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 				new BdfEntry("local", true)
 		));
 		// A remote update for the right transport should be returned
-		final MessageId fooUpdateId = new MessageId(getRandomId());
+		MessageId fooUpdateId = new MessageId(getRandomId());
 		messageMetadata3.put(fooUpdateId, BdfDictionary.of(
 				new BdfEntry("transportId", "foo"),
 				new BdfEntry("version", 1),
 				new BdfEntry("local", false)
 		));
-		final BdfList fooUpdate = BdfList.of("foo", 1, fooPropertiesDict);
+		BdfList fooUpdate = BdfList.of("foo", 1, fooPropertiesDict);
 
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(false);
@@ -492,15 +492,15 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 	@Test
 	public void testMergingUnchangedPropertiesDoesNotCreateUpdate()
 			throws Exception {
-		final Transaction txn = new Transaction(null, false);
-		final MessageId updateId = new MessageId(getRandomId());
-		final Map<MessageId, BdfDictionary> messageMetadata =
+		Transaction txn = new Transaction(null, false);
+		MessageId updateId = new MessageId(getRandomId());
+		Map<MessageId, BdfDictionary> messageMetadata =
 				Collections.singletonMap(updateId, BdfDictionary.of(
 						new BdfEntry("transportId", "foo"),
 						new BdfEntry("version", 1),
 						new BdfEntry("local", true)
 				));
-		final BdfList update = BdfList.of("foo", 1, fooPropertiesDict);
+		BdfList update = BdfList.of("foo", 1, fooPropertiesDict);
 
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(false);
@@ -522,9 +522,9 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testMergingNewPropertiesCreatesUpdate() throws Exception {
-		final Transaction txn = new Transaction(null, false);
-		final Contact contact = getContact(true);
-		final Group contactGroup = getGroup();
+		Transaction txn = new Transaction(null, false);
+		Contact contact = getContact(true);
+		Group contactGroup = getGroup();
 
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(false);
@@ -556,21 +556,21 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testMergingUpdatedPropertiesCreatesUpdate() throws Exception {
-		final Transaction txn = new Transaction(null, false);
-		final Contact contact = getContact(true);
-		final Group contactGroup = getGroup();
+		Transaction txn = new Transaction(null, false);
+		Contact contact = getContact(true);
+		Group contactGroup = getGroup();
 		BdfDictionary oldMetadata = BdfDictionary.of(
 				new BdfEntry("transportId", "foo"),
 				new BdfEntry("version", 1),
 				new BdfEntry("local", true)
 		);
-		final MessageId localGroupUpdateId = new MessageId(getRandomId());
-		final Map<MessageId, BdfDictionary> localGroupMessageMetadata =
+		MessageId localGroupUpdateId = new MessageId(getRandomId());
+		Map<MessageId, BdfDictionary> localGroupMessageMetadata =
 				Collections.singletonMap(localGroupUpdateId, oldMetadata);
-		final MessageId contactGroupUpdateId = new MessageId(getRandomId());
-		final Map<MessageId, BdfDictionary> contactGroupMessageMetadata =
+		MessageId contactGroupUpdateId = new MessageId(getRandomId());
+		Map<MessageId, BdfDictionary> contactGroupMessageMetadata =
 				Collections.singletonMap(contactGroupUpdateId, oldMetadata);
-		final BdfList oldUpdate = BdfList.of("foo", 1, BdfDictionary.of(
+		BdfList oldUpdate = BdfList.of("foo", 1, BdfDictionary.of(
 				new BdfEntry("fooKey1", "oldFooValue1")
 		));
 
@@ -638,36 +638,36 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 		return new Message(messageId, g, timestamp, raw);
 	}
 
-	private void expectGetLocalProperties(final Transaction txn)
+	private void expectGetLocalProperties(Transaction txn)
 			throws Exception {
-		final Map<MessageId, BdfDictionary> messageMetadata =
-				new LinkedHashMap<MessageId, BdfDictionary>();
+		Map<MessageId, BdfDictionary> messageMetadata =
+				new LinkedHashMap<>();
 		// The only update for transport "foo" should be returned
-		final MessageId fooVersion999 = new MessageId(getRandomId());
+		MessageId fooVersion999 = new MessageId(getRandomId());
 		messageMetadata.put(fooVersion999, BdfDictionary.of(
 				new BdfEntry("transportId", "foo"),
 				new BdfEntry("version", 999)
 		));
 		// An old update for transport "bar" should be deleted
-		final MessageId barVersion2 = new MessageId(getRandomId());
+		MessageId barVersion2 = new MessageId(getRandomId());
 		messageMetadata.put(barVersion2, BdfDictionary.of(
 				new BdfEntry("transportId", "bar"),
 				new BdfEntry("version", 2)
 		));
 		// An even older update for transport "bar" should be deleted
-		final MessageId barVersion1 = new MessageId(getRandomId());
+		MessageId barVersion1 = new MessageId(getRandomId());
 		messageMetadata.put(barVersion1, BdfDictionary.of(
 				new BdfEntry("transportId", "bar"),
 				new BdfEntry("version", 1)
 		));
 		// The latest update for transport "bar" should be returned
-		final MessageId barVersion3 = new MessageId(getRandomId());
+		MessageId barVersion3 = new MessageId(getRandomId());
 		messageMetadata.put(barVersion3, BdfDictionary.of(
 				new BdfEntry("transportId", "bar"),
 				new BdfEntry("version", 3)
 		));
-		final BdfList fooUpdate = BdfList.of("foo", 999, fooPropertiesDict);
-		final BdfList barUpdate = BdfList.of("bar", 3, barPropertiesDict);
+		BdfList fooUpdate = BdfList.of("foo", 999, fooPropertiesDict);
+		BdfList barUpdate = BdfList.of("bar", 3, barPropertiesDict);
 
 		context.checking(new Expectations() {{
 			// Find the latest local update for each transport
@@ -684,13 +684,13 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 		}});
 	}
 
-	private void expectStoreMessage(final Transaction txn, final GroupId g,
-			String transportId, final BdfDictionary properties, long version,
-			boolean local, final boolean shared) throws Exception {
-		final long timestamp = 123456789;
-		final BdfList body = BdfList.of(transportId, version, properties);
-		final Message message = getMessage(g, timestamp);
-		final BdfDictionary meta = BdfDictionary.of(
+	private void expectStoreMessage(Transaction txn, GroupId g,
+			String transportId, BdfDictionary properties, long version,
+			boolean local, boolean shared) throws Exception {
+		long timestamp = 123456789;
+		BdfList body = BdfList.of(transportId, version, properties);
+		Message message = getMessage(g, timestamp);
+		BdfDictionary meta = BdfDictionary.of(
 				new BdfEntry("transportId", transportId),
 				new BdfEntry("version", version),
 				new BdfEntry("local", local)
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/sync/SimplexOutgoingSessionTest.java b/bramble-core/src/test/java/org/briarproject/bramble/sync/SimplexOutgoingSessionTest.java
index a2ebedfeb9a7e115dfdfbcf2631984b577d22434..92f030052fd6e37578e32318ff1e02dea6669bfe 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/sync/SimplexOutgoingSessionTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/sync/SimplexOutgoingSessionTest.java
@@ -6,10 +6,10 @@ import org.briarproject.bramble.api.db.Transaction;
 import org.briarproject.bramble.api.event.EventBus;
 import org.briarproject.bramble.api.sync.Ack;
 import org.briarproject.bramble.api.sync.MessageId;
+import org.briarproject.bramble.api.sync.RecordWriter;
 import org.briarproject.bramble.test.BrambleTestCase;
 import org.briarproject.bramble.test.ImmediateExecutor;
 import org.briarproject.bramble.test.TestUtils;
-import org.briarproject.bramble.api.sync.RecordWriter;
 import org.jmock.Expectations;
 import org.jmock.Mockery;
 import org.junit.Test;
@@ -44,10 +44,10 @@ public class SimplexOutgoingSessionTest extends BrambleTestCase {
 
 	@Test
 	public void testNothingToSend() throws Exception {
-		final SimplexOutgoingSession session = new SimplexOutgoingSession(db,
+		SimplexOutgoingSession session = new SimplexOutgoingSession(db,
 				dbExecutor, eventBus, contactId, maxLatency, recordWriter);
-		final Transaction noAckTxn = new Transaction(null, false);
-		final Transaction noMsgTxn = new Transaction(null, false);
+		Transaction noAckTxn = new Transaction(null, false);
+		Transaction noMsgTxn = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			// Add listener
@@ -80,14 +80,14 @@ public class SimplexOutgoingSessionTest extends BrambleTestCase {
 
 	@Test
 	public void testSomethingToSend() throws Exception {
-		final Ack ack = new Ack(Collections.singletonList(messageId));
-		final byte[] raw = new byte[1234];
-		final SimplexOutgoingSession session = new SimplexOutgoingSession(db,
+		Ack ack = new Ack(Collections.singletonList(messageId));
+		byte[] raw = new byte[1234];
+		SimplexOutgoingSession session = new SimplexOutgoingSession(db,
 				dbExecutor, eventBus, contactId, maxLatency, recordWriter);
-		final Transaction ackTxn = new Transaction(null, false);
-		final Transaction noAckTxn = new Transaction(null, false);
-		final Transaction msgTxn = new Transaction(null, false);
-		final Transaction noMsgTxn = new Transaction(null, false);
+		Transaction ackTxn = new Transaction(null, false);
+		Transaction noAckTxn = new Transaction(null, false);
+		Transaction msgTxn = new Transaction(null, false);
+		Transaction noMsgTxn = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			// Add listener
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/sync/ValidationManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/sync/ValidationManagerImplTest.java
index 28af730180ce39f6f1f4c02f90b7c04a25feb74d..c2285bd5f61694f9feca500ccf2e272141e3f88d 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/sync/ValidationManagerImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/sync/ValidationManagerImplTest.java
@@ -92,9 +92,9 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testStartAndStop() throws Exception {
-		final Transaction txn = new Transaction(null, true);
-		final Transaction txn1 = new Transaction(null, true);
-		final Transaction txn2 = new Transaction(null, true);
+		Transaction txn = new Transaction(null, true);
+		Transaction txn1 = new Transaction(null, true);
+		Transaction txn2 = new Transaction(null, true);
 
 		context.checking(new Expectations() {{
 			// validateOutstandingMessages()
@@ -126,13 +126,13 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testMessagesAreValidatedAtStartup() throws Exception {
-		final Transaction txn = new Transaction(null, true);
-		final Transaction txn1 = new Transaction(null, true);
-		final Transaction txn2 = new Transaction(null, false);
-		final Transaction txn3 = new Transaction(null, true);
-		final Transaction txn4 = new Transaction(null, false);
-		final Transaction txn5 = new Transaction(null, true);
-		final Transaction txn6 = new Transaction(null, true);
+		Transaction txn = new Transaction(null, true);
+		Transaction txn1 = new Transaction(null, true);
+		Transaction txn2 = new Transaction(null, false);
+		Transaction txn3 = new Transaction(null, true);
+		Transaction txn4 = new Transaction(null, false);
+		Transaction txn5 = new Transaction(null, true);
+		Transaction txn6 = new Transaction(null, true);
 
 		context.checking(new Expectations() {{
 			// Get messages to validate
@@ -217,11 +217,11 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testPendingMessagesAreDeliveredAtStartup() throws Exception {
-		final Transaction txn = new Transaction(null, true);
-		final Transaction txn1 = new Transaction(null, true);
-		final Transaction txn2 = new Transaction(null, false);
-		final Transaction txn3 = new Transaction(null, false);
-		final Transaction txn4 = new Transaction(null, true);
+		Transaction txn = new Transaction(null, true);
+		Transaction txn1 = new Transaction(null, true);
+		Transaction txn2 = new Transaction(null, false);
+		Transaction txn3 = new Transaction(null, false);
+		Transaction txn4 = new Transaction(null, true);
 
 		context.checking(new Expectations() {{
 			// Get messages to validate
@@ -303,11 +303,11 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testMessagesAreSharedAtStartup() throws Exception {
-		final Transaction txn = new Transaction(null, true);
-		final Transaction txn1 = new Transaction(null, true);
-		final Transaction txn2 = new Transaction(null, true);
-		final Transaction txn3 = new Transaction(null, false);
-		final Transaction txn4 = new Transaction(null, false);
+		Transaction txn = new Transaction(null, true);
+		Transaction txn1 = new Transaction(null, true);
+		Transaction txn2 = new Transaction(null, true);
+		Transaction txn3 = new Transaction(null, false);
+		Transaction txn4 = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			// No messages to validate
@@ -355,9 +355,9 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testIncomingMessagesAreShared() throws Exception {
-		final Transaction txn = new Transaction(null, true);
-		final Transaction txn1 = new Transaction(null, false);
-		final Transaction txn2 = new Transaction(null, false);
+		Transaction txn = new Transaction(null, true);
+		Transaction txn1 = new Transaction(null, false);
+		Transaction txn2 = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			// Load the group
@@ -405,12 +405,12 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
 	@Test
 	public void testValidationContinuesAfterNoSuchMessageException()
 			throws Exception {
-		final Transaction txn = new Transaction(null, true);
-		final Transaction txn1 = new Transaction(null, true);
-		final Transaction txn2 = new Transaction(null, true);
-		final Transaction txn3 = new Transaction(null, false);
-		final Transaction txn4 = new Transaction(null, true);
-		final Transaction txn5 = new Transaction(null, true);
+		Transaction txn = new Transaction(null, true);
+		Transaction txn1 = new Transaction(null, true);
+		Transaction txn2 = new Transaction(null, true);
+		Transaction txn3 = new Transaction(null, false);
+		Transaction txn4 = new Transaction(null, true);
+		Transaction txn5 = new Transaction(null, true);
 
 		context.checking(new Expectations() {{
 			// Get messages to validate
@@ -476,12 +476,12 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
 	@Test
 	public void testValidationContinuesAfterNoSuchGroupException()
 			throws Exception {
-		final Transaction txn = new Transaction(null, true);
-		final Transaction txn1 = new Transaction(null, true);
-		final Transaction txn2 = new Transaction(null, true);
-		final Transaction txn3 = new Transaction(null, false);
-		final Transaction txn4 = new Transaction(null, true);
-		final Transaction txn5 = new Transaction(null, true);
+		Transaction txn = new Transaction(null, true);
+		Transaction txn1 = new Transaction(null, true);
+		Transaction txn2 = new Transaction(null, true);
+		Transaction txn3 = new Transaction(null, false);
+		Transaction txn4 = new Transaction(null, true);
+		Transaction txn5 = new Transaction(null, true);
 
 		context.checking(new Expectations() {{
 			// Get messages to validate
@@ -551,8 +551,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testNonLocalMessagesAreValidatedWhenAdded() throws Exception {
-		final Transaction txn = new Transaction(null, true);
-		final Transaction txn1 = new Transaction(null, false);
+		Transaction txn = new Transaction(null, true);
+		Transaction txn1 = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			// Load the group
@@ -591,8 +591,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
 	@Test
 	public void testMessagesWithUndeliveredDependenciesArePending()
 			throws Exception {
-		final Transaction txn = new Transaction(null, true);
-		final Transaction txn1 = new Transaction(null, false);
+		Transaction txn = new Transaction(null, true);
+		Transaction txn1 = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			// Load the group
@@ -624,8 +624,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
 	@Test
 	public void testMessagesWithDeliveredDependenciesGetDelivered()
 			throws Exception {
-		final Transaction txn = new Transaction(null, true);
-		final Transaction txn1 = new Transaction(null, false);
+		Transaction txn = new Transaction(null, true);
+		Transaction txn1 = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			// Load the group
@@ -663,9 +663,9 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
 	@Test
 	public void testMessagesWithInvalidDependenciesAreInvalid()
 			throws Exception {
-		final Transaction txn = new Transaction(null, true);
-		final Transaction txn1 = new Transaction(null, false);
-		final Transaction txn2 = new Transaction(null, false);
+		Transaction txn = new Transaction(null, true);
+		Transaction txn1 = new Transaction(null, false);
+		Transaction txn2 = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			// Load the group
@@ -716,19 +716,18 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testRecursiveInvalidation() throws Exception {
-		final MessageId messageId3 = new MessageId(TestUtils.getRandomId());
-		final MessageId messageId4 = new MessageId(TestUtils.getRandomId());
-		final Map<MessageId, State> twoDependents =
-				new LinkedHashMap<MessageId, State>();
+		MessageId messageId3 = new MessageId(TestUtils.getRandomId());
+		MessageId messageId4 = new MessageId(TestUtils.getRandomId());
+		Map<MessageId, State> twoDependents = new LinkedHashMap<>();
 		twoDependents.put(messageId1, PENDING);
 		twoDependents.put(messageId2, PENDING);
-		final Transaction txn = new Transaction(null, true);
-		final Transaction txn1 = new Transaction(null, false);
-		final Transaction txn2 = new Transaction(null, false);
-		final Transaction txn3 = new Transaction(null, false);
-		final Transaction txn4 = new Transaction(null, false);
-		final Transaction txn5 = new Transaction(null, false);
-		final Transaction txn6 = new Transaction(null, false);
+		Transaction txn = new Transaction(null, true);
+		Transaction txn1 = new Transaction(null, false);
+		Transaction txn2 = new Transaction(null, false);
+		Transaction txn3 = new Transaction(null, false);
+		Transaction txn4 = new Transaction(null, false);
+		Transaction txn5 = new Transaction(null, false);
+		Transaction txn6 = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			// Load the group
@@ -820,27 +819,25 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testPendingDependentsGetDelivered() throws Exception {
-		final MessageId messageId3 = new MessageId(TestUtils.getRandomId());
-		final MessageId messageId4 = new MessageId(TestUtils.getRandomId());
-		final Message message3 = new Message(messageId3, groupId, timestamp,
+		MessageId messageId3 = new MessageId(TestUtils.getRandomId());
+		MessageId messageId4 = new MessageId(TestUtils.getRandomId());
+		Message message3 = new Message(messageId3, groupId, timestamp,
 				raw);
-		final Message message4 = new Message(messageId4, groupId, timestamp,
+		Message message4 = new Message(messageId4, groupId, timestamp,
 				raw);
-		final Map<MessageId, State> twoDependents =
-				new LinkedHashMap<MessageId, State>();
+		Map<MessageId, State> twoDependents = new LinkedHashMap<>();
 		twoDependents.put(messageId1, PENDING);
 		twoDependents.put(messageId2, PENDING);
-		final Map<MessageId, State> twoDependencies =
-				new LinkedHashMap<MessageId, State>();
+		Map<MessageId, State> twoDependencies = new LinkedHashMap<>();
 		twoDependencies.put(messageId1, DELIVERED);
 		twoDependencies.put(messageId2, DELIVERED);
-		final Transaction txn = new Transaction(null, true);
-		final Transaction txn1 = new Transaction(null, false);
-		final Transaction txn2 = new Transaction(null, false);
-		final Transaction txn3 = new Transaction(null, false);
-		final Transaction txn4 = new Transaction(null, false);
-		final Transaction txn5 = new Transaction(null, false);
-		final Transaction txn6 = new Transaction(null, false);
+		Transaction txn = new Transaction(null, true);
+		Transaction txn1 = new Transaction(null, false);
+		Transaction txn2 = new Transaction(null, false);
+		Transaction txn3 = new Transaction(null, false);
+		Transaction txn4 = new Transaction(null, false);
+		Transaction txn5 = new Transaction(null, false);
+		Transaction txn6 = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			// Load the group
@@ -979,13 +976,12 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testOnlyReadyPendingDependentsGetDelivered() throws Exception {
-		final Map<MessageId, State> twoDependencies =
-				new LinkedHashMap<MessageId, State>();
+		Map<MessageId, State> twoDependencies = new LinkedHashMap<>();
 		twoDependencies.put(messageId, DELIVERED);
 		twoDependencies.put(messageId2, UNKNOWN);
-		final Transaction txn = new Transaction(null, true);
-		final Transaction txn1 = new Transaction(null, false);
-		final Transaction txn2 = new Transaction(null, false);
+		Transaction txn = new Transaction(null, true);
+		Transaction txn1 = new Transaction(null, false);
+		Transaction txn2 = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			// Load the group
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/system/LinuxSecureRandomSpiTest.java b/bramble-core/src/test/java/org/briarproject/bramble/system/LinuxSecureRandomSpiTest.java
index 4a3ac7313d2428fe4f4ab0fc994a8096d3b0e167..3d48b647af75f93b5a32ad15451025c92c5b52f3 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/system/LinuxSecureRandomSpiTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/system/LinuxSecureRandomSpiTest.java
@@ -38,7 +38,7 @@ public class LinuxSecureRandomSpiTest extends BrambleTestCase {
 			System.err.println("WARNING: Skipping test, can't run on this OS");
 			return;
 		}
-		Set<Bytes> seeds = new HashSet<Bytes>();
+		Set<Bytes> seeds = new HashSet<>();
 		LinuxSecureRandomSpi engine = new LinuxSecureRandomSpi();
 		for (int i = 0; i < 1000; i++) {
 			byte[] seed = engine.engineGenerateSeed(SEED_BYTES);
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/transport/KeyManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/transport/KeyManagerImplTest.java
index 340dfb1468ef6b38c3951cf247e19e948733cb20..ade43e14486ed9a9f23b7825e1d6e8a8021ea1b2 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/transport/KeyManagerImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/transport/KeyManagerImplTest.java
@@ -58,21 +58,21 @@ public class KeyManagerImplTest extends BrambleTestCase {
 
 	@Before
 	public void testStartService() throws Exception {
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 		AuthorId remoteAuthorId = new AuthorId(getRandomId());
 		Author remoteAuthor = new Author(remoteAuthorId, "author",
 				getRandomBytes(42));
 		AuthorId localAuthorId = new AuthorId(getRandomId());
-		final Collection<Contact> contacts = new ArrayList<Contact>();
+		Collection<Contact> contacts = new ArrayList<>();
 		contacts.add(new Contact(contactId, remoteAuthor, localAuthorId, true,
 				true));
 		contacts.add(new Contact(inactiveContactId, remoteAuthor, localAuthorId,
 				true, false));
-		final SimplexPluginFactory pluginFactory =
+		SimplexPluginFactory pluginFactory =
 				context.mock(SimplexPluginFactory.class);
-		final Collection<SimplexPluginFactory> factories = Collections
+		Collection<SimplexPluginFactory> factories = Collections
 				.singletonList(pluginFactory);
-		final int maxLatency = 1337;
+		int maxLatency = 1337;
 
 		context.checking(new Expectations() {{
 			oneOf(pluginConfig).getSimplexFactories();
@@ -100,9 +100,9 @@ public class KeyManagerImplTest extends BrambleTestCase {
 
 	@Test
 	public void testAddContact() throws Exception {
-		final SecretKey secretKey = getSecretKey();
-		final long timestamp = 42L;
-		final boolean alice =  true;
+		SecretKey secretKey = getSecretKey();
+		long timestamp = 42L;
+		boolean alice =  true;
 
 		context.checking(new Expectations() {{
 			oneOf(transportKeyManager)
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/transport/StreamReaderImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/transport/StreamReaderImplTest.java
index 40ff0763105d6756b87752fc08af10dda68fef3c..d8e2ae1dea1c1aa81104728e027cd93d3ad8fbee 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/transport/StreamReaderImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/transport/StreamReaderImplTest.java
@@ -14,7 +14,7 @@ public class StreamReaderImplTest extends BrambleTestCase {
 	@Test
 	public void testEmptyFramesAreSkipped() throws Exception {
 		Mockery context = new Mockery();
-		final StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
+		StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
 		context.checking(new Expectations() {{
 			oneOf(decrypter).readFrame(with(any(byte[].class)));
 			will(returnValue(0)); // Empty frame
@@ -37,7 +37,7 @@ public class StreamReaderImplTest extends BrambleTestCase {
 	@Test
 	public void testEmptyFramesAreSkippedWithBuffer() throws Exception {
 		Mockery context = new Mockery();
-		final StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
+		StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
 		context.checking(new Expectations() {{
 			oneOf(decrypter).readFrame(with(any(byte[].class)));
 			will(returnValue(0)); // Empty frame
@@ -63,7 +63,7 @@ public class StreamReaderImplTest extends BrambleTestCase {
 	@Test
 	public void testMultipleReadsPerFrame() throws Exception {
 		Mockery context = new Mockery();
-		final StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
+		StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
 		context.checking(new Expectations() {{
 			oneOf(decrypter).readFrame(with(any(byte[].class)));
 			will(returnValue(MAX_PAYLOAD_LENGTH)); // Nice long frame
@@ -85,7 +85,7 @@ public class StreamReaderImplTest extends BrambleTestCase {
 	@Test
 	public void testMultipleReadsPerFrameWithOffsets() throws Exception {
 		Mockery context = new Mockery();
-		final StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
+		StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
 		context.checking(new Expectations() {{
 			oneOf(decrypter).readFrame(with(any(byte[].class)));
 			will(returnValue(MAX_PAYLOAD_LENGTH)); // Nice long frame
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/transport/StreamWriterImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/transport/StreamWriterImplTest.java
index b0db082ba8d4b968d0fe6f4bcd1e25929df6ba38..53f1038bdbd60ace0d20216ccc634902d801b4ff 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/transport/StreamWriterImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/transport/StreamWriterImplTest.java
@@ -14,7 +14,7 @@ public class StreamWriterImplTest extends BrambleTestCase {
 	@Test
 	public void testCloseWithoutWritingWritesFinalFrame() throws Exception {
 		Mockery context = new Mockery();
-		final StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
+		StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
 		context.checking(new Expectations() {{
 			// Write an empty final frame
 			oneOf(encrypter).writeFrame(with(any(byte[].class)), with(0),
@@ -31,7 +31,7 @@ public class StreamWriterImplTest extends BrambleTestCase {
 	public void testFlushWithoutBufferedDataWritesFrameAndFlushes()
 			throws Exception {
 		Mockery context = new Mockery();
-		final StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
+		StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
 		StreamWriterImpl w = new StreamWriterImpl(encrypter);
 		context.checking(new Expectations() {{
 			// Write a non-final frame with an empty payload
@@ -58,7 +58,7 @@ public class StreamWriterImplTest extends BrambleTestCase {
 	public void testFlushWithBufferedDataWritesFrameAndFlushes()
 			throws Exception {
 		Mockery context = new Mockery();
-		final StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
+		StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
 		StreamWriterImpl w = new StreamWriterImpl(encrypter);
 		context.checking(new Expectations() {{
 			// Write a non-final frame with one payload byte
@@ -85,7 +85,7 @@ public class StreamWriterImplTest extends BrambleTestCase {
 	@Test
 	public void testSingleByteWritesWriteFullFrame() throws Exception {
 		Mockery context = new Mockery();
-		final StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
+		StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
 		StreamWriterImpl w = new StreamWriterImpl(encrypter);
 		context.checking(new Expectations() {{
 			// Write a full non-final frame
@@ -109,7 +109,7 @@ public class StreamWriterImplTest extends BrambleTestCase {
 	@Test
 	public void testMultiByteWritesWriteFullFrames() throws Exception {
 		Mockery context = new Mockery();
-		final StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
+		StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
 		StreamWriterImpl w = new StreamWriterImpl(encrypter);
 		context.checking(new Expectations() {{
 			// Write two full non-final frames
@@ -140,7 +140,7 @@ public class StreamWriterImplTest extends BrambleTestCase {
 	@Test
 	public void testLargeMultiByteWriteWritesFullFrames() throws Exception {
 		Mockery context = new Mockery();
-		final StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
+		StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
 		StreamWriterImpl w = new StreamWriterImpl(encrypter);
 		context.checking(new Expectations() {{
 			// Write two full non-final frames
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/transport/TransportKeyManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/transport/TransportKeyManagerImplTest.java
index b66f5c745493e42ccdaaa2fd491da2a80e1be1e6..0cdfaeb561228cfd7d22c991a7dae780ba5becb4 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/transport/TransportKeyManagerImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/transport/TransportKeyManagerImplTest.java
@@ -56,21 +56,20 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
 	@Test
 	public void testKeysAreRotatedAtStartup() throws Exception {
 		Mockery context = new Mockery();
-		final DatabaseComponent db = context.mock(DatabaseComponent.class);
-		final CryptoComponent crypto = context.mock(CryptoComponent.class);
-		final Executor dbExecutor = context.mock(Executor.class);
-		final ScheduledExecutorService scheduler =
+		DatabaseComponent db = context.mock(DatabaseComponent.class);
+		CryptoComponent crypto = context.mock(CryptoComponent.class);
+		Executor dbExecutor = context.mock(Executor.class);
+		ScheduledExecutorService scheduler =
 				context.mock(ScheduledExecutorService.class);
-		final Clock clock = context.mock(Clock.class);
+		Clock clock = context.mock(Clock.class);
 
-		final Map<ContactId, TransportKeys> loaded =
-				new LinkedHashMap<ContactId, TransportKeys>();
-		final TransportKeys shouldRotate = createTransportKeys(900, 0);
-		final TransportKeys shouldNotRotate = createTransportKeys(1000, 0);
+		Map<ContactId, TransportKeys> loaded = new LinkedHashMap<>();
+		TransportKeys shouldRotate = createTransportKeys(900, 0);
+		TransportKeys shouldNotRotate = createTransportKeys(1000, 0);
 		loaded.put(contactId, shouldRotate);
 		loaded.put(contactId1, shouldNotRotate);
-		final TransportKeys rotated = createTransportKeys(1000, 0);
-		final Transaction txn = new Transaction(null, false);
+		TransportKeys rotated = createTransportKeys(1000, 0);
+		Transaction txn = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			// Get the current time (1 ms after start of rotation period 1000)
@@ -109,17 +108,17 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
 	@Test
 	public void testKeysAreRotatedWhenAddingContact() throws Exception {
 		Mockery context = new Mockery();
-		final DatabaseComponent db = context.mock(DatabaseComponent.class);
-		final CryptoComponent crypto = context.mock(CryptoComponent.class);
-		final Executor dbExecutor = context.mock(Executor.class);
-		final ScheduledExecutorService scheduler =
+		DatabaseComponent db = context.mock(DatabaseComponent.class);
+		CryptoComponent crypto = context.mock(CryptoComponent.class);
+		Executor dbExecutor = context.mock(Executor.class);
+		ScheduledExecutorService scheduler =
 				context.mock(ScheduledExecutorService.class);
-		final Clock clock = context.mock(Clock.class);
+		Clock clock = context.mock(Clock.class);
 
-		final boolean alice = true;
-		final TransportKeys transportKeys = createTransportKeys(999, 0);
-		final TransportKeys rotated = createTransportKeys(1000, 0);
-		final Transaction txn = new Transaction(null, false);
+		boolean alice = true;
+		TransportKeys transportKeys = createTransportKeys(999, 0);
+		TransportKeys rotated = createTransportKeys(1000, 0);
+		Transaction txn = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			oneOf(crypto).deriveTransportKeys(transportId, masterKey, 999,
@@ -156,14 +155,14 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
 	public void testOutgoingStreamContextIsNullIfContactIsNotFound()
 			throws Exception {
 		Mockery context = new Mockery();
-		final DatabaseComponent db = context.mock(DatabaseComponent.class);
-		final CryptoComponent crypto = context.mock(CryptoComponent.class);
-		final Executor dbExecutor = context.mock(Executor.class);
-		final ScheduledExecutorService scheduler =
+		DatabaseComponent db = context.mock(DatabaseComponent.class);
+		CryptoComponent crypto = context.mock(CryptoComponent.class);
+		Executor dbExecutor = context.mock(Executor.class);
+		ScheduledExecutorService scheduler =
 				context.mock(ScheduledExecutorService.class);
-		final Clock clock = context.mock(Clock.class);
+		Clock clock = context.mock(Clock.class);
 
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 
 		TransportKeyManager
 				transportKeyManager = new TransportKeyManagerImpl(db,
@@ -177,18 +176,18 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
 	public void testOutgoingStreamContextIsNullIfStreamCounterIsExhausted()
 			throws Exception {
 		Mockery context = new Mockery();
-		final DatabaseComponent db = context.mock(DatabaseComponent.class);
-		final CryptoComponent crypto = context.mock(CryptoComponent.class);
-		final Executor dbExecutor = context.mock(Executor.class);
-		final ScheduledExecutorService scheduler =
+		DatabaseComponent db = context.mock(DatabaseComponent.class);
+		CryptoComponent crypto = context.mock(CryptoComponent.class);
+		Executor dbExecutor = context.mock(Executor.class);
+		ScheduledExecutorService scheduler =
 				context.mock(ScheduledExecutorService.class);
-		final Clock clock = context.mock(Clock.class);
+		Clock clock = context.mock(Clock.class);
 
-		final boolean alice = true;
+		boolean alice = true;
 		// The stream counter has been exhausted
-		final TransportKeys transportKeys = createTransportKeys(1000,
+		TransportKeys transportKeys = createTransportKeys(1000,
 				MAX_32_BIT_UNSIGNED + 1);
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			oneOf(crypto).deriveTransportKeys(transportId, masterKey, 1000,
@@ -225,18 +224,18 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
 	@Test
 	public void testOutgoingStreamCounterIsIncremented() throws Exception {
 		Mockery context = new Mockery();
-		final DatabaseComponent db = context.mock(DatabaseComponent.class);
-		final CryptoComponent crypto = context.mock(CryptoComponent.class);
-		final Executor dbExecutor = context.mock(Executor.class);
-		final ScheduledExecutorService scheduler =
+		DatabaseComponent db = context.mock(DatabaseComponent.class);
+		CryptoComponent crypto = context.mock(CryptoComponent.class);
+		Executor dbExecutor = context.mock(Executor.class);
+		ScheduledExecutorService scheduler =
 				context.mock(ScheduledExecutorService.class);
-		final Clock clock = context.mock(Clock.class);
+		Clock clock = context.mock(Clock.class);
 
-		final boolean alice = true;
+		boolean alice = true;
 		// The stream counter can be used one more time before being exhausted
-		final TransportKeys transportKeys = createTransportKeys(1000,
+		TransportKeys transportKeys = createTransportKeys(1000,
 				MAX_32_BIT_UNSIGNED);
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			oneOf(crypto).deriveTransportKeys(transportId, masterKey, 1000,
@@ -286,16 +285,16 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
 	public void testIncomingStreamContextIsNullIfTagIsNotFound()
 			throws Exception {
 		Mockery context = new Mockery();
-		final DatabaseComponent db = context.mock(DatabaseComponent.class);
-		final CryptoComponent crypto = context.mock(CryptoComponent.class);
-		final Executor dbExecutor = context.mock(Executor.class);
-		final ScheduledExecutorService scheduler =
+		DatabaseComponent db = context.mock(DatabaseComponent.class);
+		CryptoComponent crypto = context.mock(CryptoComponent.class);
+		Executor dbExecutor = context.mock(Executor.class);
+		ScheduledExecutorService scheduler =
 				context.mock(ScheduledExecutorService.class);
-		final Clock clock = context.mock(Clock.class);
+		Clock clock = context.mock(Clock.class);
 
-		final boolean alice = true;
-		final TransportKeys transportKeys = createTransportKeys(1000, 0);
-		final Transaction txn = new Transaction(null, false);
+		boolean alice = true;
+		TransportKeys transportKeys = createTransportKeys(1000, 0);
+		Transaction txn = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			oneOf(crypto).deriveTransportKeys(transportId, masterKey, 1000,
@@ -333,18 +332,18 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
 	@Test
 	public void testTagIsNotRecognisedTwice() throws Exception {
 		Mockery context = new Mockery();
-		final DatabaseComponent db = context.mock(DatabaseComponent.class);
-		final CryptoComponent crypto = context.mock(CryptoComponent.class);
-		final Executor dbExecutor = context.mock(Executor.class);
-		final ScheduledExecutorService scheduler =
+		DatabaseComponent db = context.mock(DatabaseComponent.class);
+		CryptoComponent crypto = context.mock(CryptoComponent.class);
+		Executor dbExecutor = context.mock(Executor.class);
+		ScheduledExecutorService scheduler =
 				context.mock(ScheduledExecutorService.class);
-		final Clock clock = context.mock(Clock.class);
+		Clock clock = context.mock(Clock.class);
 
-		final boolean alice = true;
-		final TransportKeys transportKeys = createTransportKeys(1000, 0);
+		boolean alice = true;
+		TransportKeys transportKeys = createTransportKeys(1000, 0);
 		// Keep a copy of the tags
-		final List<byte[]> tags = new ArrayList<byte[]>();
-		final Transaction txn = new Transaction(null, false);
+		List<byte[]> tags = new ArrayList<>();
+		Transaction txn = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			oneOf(crypto).deriveTransportKeys(transportId, masterKey, 1000,
@@ -403,19 +402,19 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
 	@Test
 	public void testKeysAreRotatedToCurrentPeriod() throws Exception {
 		Mockery context = new Mockery();
-		final DatabaseComponent db = context.mock(DatabaseComponent.class);
-		final CryptoComponent crypto = context.mock(CryptoComponent.class);
-		final Executor dbExecutor = context.mock(Executor.class);
-		final ScheduledExecutorService scheduler =
+		DatabaseComponent db = context.mock(DatabaseComponent.class);
+		CryptoComponent crypto = context.mock(CryptoComponent.class);
+		Executor dbExecutor = context.mock(Executor.class);
+		ScheduledExecutorService scheduler =
 				context.mock(ScheduledExecutorService.class);
-		final Clock clock = context.mock(Clock.class);
+		Clock clock = context.mock(Clock.class);
 
-		final TransportKeys transportKeys = createTransportKeys(1000, 0);
-		final Map<ContactId, TransportKeys> loaded =
+		TransportKeys transportKeys = createTransportKeys(1000, 0);
+		Map<ContactId, TransportKeys> loaded =
 				Collections.singletonMap(contactId, transportKeys);
-		final TransportKeys rotated = createTransportKeys(1001, 0);
-		final Transaction txn = new Transaction(null, false);
-		final Transaction txn1 = new Transaction(null, false);
+		TransportKeys rotated = createTransportKeys(1001, 0);
+		Transaction txn = new Transaction(null, false);
+		Transaction txn1 = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			// Get the current time (the start of rotation period 1000)
diff --git a/bramble-j2se/src/main/java/org/briarproject/bramble/lifecycle/WindowsShutdownManagerImpl.java b/bramble-j2se/src/main/java/org/briarproject/bramble/lifecycle/WindowsShutdownManagerImpl.java
index aac6a02199ac434434d9a4d131ce64a39ebae8c4..da27f3ba06a4c40d4f414e91012874918238c4f1 100644
--- a/bramble-j2se/src/main/java/org/briarproject/bramble/lifecycle/WindowsShutdownManagerImpl.java
+++ b/bramble-j2se/src/main/java/org/briarproject/bramble/lifecycle/WindowsShutdownManagerImpl.java
@@ -110,20 +110,16 @@ class WindowsShutdownManagerImpl extends ShutdownManagerImpl {
 		public void run() {
 			try {
 				// Load user32.dll
-				final User32 user32 = (User32) Native.loadLibrary("user32",
+				User32 user32 = (User32) Native.loadLibrary("user32",
 						User32.class, options);
 				// Create a callback to handle the WM_QUERYENDSESSION message
-				WindowProc proc = new WindowProc() {
-					@Override
-					public LRESULT callback(HWND hwnd, int msg, WPARAM wp,
-							LPARAM lp) {
-						if (msg == WM_QUERYENDSESSION) {
-							// It's safe to delay returning from this message
-							runShutdownHooks();
-						}
-						// Pass the message to the default window procedure
-						return user32.DefWindowProc(hwnd, msg, wp, lp);
+				WindowProc proc = (hwnd, msg, wp, lp) -> {
+					if (msg == WM_QUERYENDSESSION) {
+						// It's safe to delay returning from this message
+						runShutdownHooks();
 					}
+					// Pass the message to the default window procedure
+					return user32.DefWindowProc(hwnd, msg, wp, lp);
 				};
 				// Create a native window
 				HWND hwnd = user32.CreateWindowEx(0, "STATIC", "", WS_MINIMIZE,
diff --git a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/DesktopPluginModule.java b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/DesktopPluginModule.java
index 616f9661109541df235f5eab8f2a571d02843ce1..a2a8f0b8d2b96911b876b786f3ee5c6a9f1698f6 100644
--- a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/DesktopPluginModule.java
+++ b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/DesktopPluginModule.java
@@ -41,9 +41,9 @@ public class DesktopPluginModule extends PluginModule {
 				backoffFactory, shutdownManager);
 		SimplexPluginFactory removable =
 				new RemovableDrivePluginFactory(ioExecutor);
-		final Collection<SimplexPluginFactory> simplex =
+		Collection<SimplexPluginFactory> simplex =
 				Collections.singletonList(removable);
-		final Collection<DuplexPluginFactory> duplex =
+		Collection<DuplexPluginFactory> duplex =
 				Arrays.asList(bluetooth, modem, lan, wan);
 		@NotNullByDefault
 		PluginConfig pluginConfig = new PluginConfig() {
diff --git a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java
index 22783756b27fb559811ecb37f703e69ab6692a71..6e119909a85b2bbb324f10165e3abac213219d79 100644
--- a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java
+++ b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java
@@ -108,33 +108,30 @@ class BluetoothPlugin implements DuplexPlugin {
 	}
 
 	private void bind() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				if (!running) return;
-				// Advertise the Bluetooth address to contacts
-				TransportProperties p = new TransportProperties();
-				p.put(PROP_ADDRESS, localDevice.getBluetoothAddress());
-				callback.mergeLocalProperties(p);
-				// Bind a server socket to accept connections from contacts
-				String url = makeUrl("localhost", getUuid());
-				StreamConnectionNotifier ss;
-				try {
-					ss = (StreamConnectionNotifier) Connector.open(url);
-				} catch (IOException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					return;
-				}
-				if (!running) {
-					tryToClose(ss);
-					return;
-				}
-				socket = ss;
-				backoff.reset();
-				callback.transportEnabled();
-				acceptContactConnections(ss);
+		ioExecutor.execute(() -> {
+			if (!running) return;
+			// Advertise the Bluetooth address to contacts
+			TransportProperties p = new TransportProperties();
+			p.put(PROP_ADDRESS, localDevice.getBluetoothAddress());
+			callback.mergeLocalProperties(p);
+			// Bind a server socket to accept connections from contacts
+			String url = makeUrl("localhost", getUuid());
+			StreamConnectionNotifier ss;
+			try {
+				ss = (StreamConnectionNotifier) Connector.open(url);
+			} catch (IOException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				return;
+			}
+			if (!running) {
+				tryToClose(ss);
+				return;
 			}
+			socket = ss;
+			backoff.reset();
+			callback.transportEnabled();
+			acceptContactConnections(ss);
 		});
 	}
 
@@ -207,33 +204,31 @@ class BluetoothPlugin implements DuplexPlugin {
 	}
 
 	@Override
-	public void poll(final Collection<ContactId> connected) {
+	public void poll(Collection<ContactId> connected) {
 		if (!running) return;
 		backoff.increment();
 		// Try to connect to known devices in parallel
 		Map<ContactId, TransportProperties> remote =
 				callback.getRemoteProperties();
 		for (Entry<ContactId, TransportProperties> e : remote.entrySet()) {
-			final ContactId c = e.getKey();
+			ContactId c = e.getKey();
 			if (connected.contains(c)) continue;
-			final String address = e.getValue().get(PROP_ADDRESS);
+			String address = e.getValue().get(PROP_ADDRESS);
 			if (StringUtils.isNullOrEmpty(address)) continue;
-			final String uuid = e.getValue().get(PROP_UUID);
+			String uuid = e.getValue().get(PROP_UUID);
 			if (StringUtils.isNullOrEmpty(uuid)) continue;
-			ioExecutor.execute(new Runnable() {
-				@Override
-				public void run() {
-					if (!running) return;
-					StreamConnection s = connect(makeUrl(address, uuid));
-					if (s != null) {
-						backoff.reset();
-						callback.outgoingConnectionCreated(c, wrapSocket(s));
-					}
+			ioExecutor.execute(() -> {
+				if (!running) return;
+				StreamConnection s = connect(makeUrl(address, uuid));
+				if (s != null) {
+					backoff.reset();
+					callback.outgoingConnectionCreated(c, wrapSocket(s));
 				}
 			});
 		}
 	}
 
+	@Nullable
 	private StreamConnection connect(String url) {
 		if (LOG.isLoggable(INFO)) LOG.info("Connecting to " + url);
 		try {
@@ -275,7 +270,7 @@ class BluetoothPlugin implements DuplexPlugin {
 		// Make the device discoverable if possible
 		makeDeviceDiscoverable();
 		// Bind a server socket for receiving key agreementconnections
-		final StreamConnectionNotifier ss;
+		StreamConnectionNotifier ss;
 		try {
 			ss = (StreamConnectionNotifier) Connector.open(url);
 		} catch (IOException e) {
@@ -341,16 +336,13 @@ class BluetoothPlugin implements DuplexPlugin {
 
 		@Override
 		public Callable<KeyAgreementConnection> listen() {
-			return new Callable<KeyAgreementConnection>() {
-				@Override
-				public KeyAgreementConnection call() throws Exception {
-					StreamConnection s = ss.acceptAndOpen();
-					if (LOG.isLoggable(INFO))
-						LOG.info(ID.getString() + ": Incoming connection");
-					return new KeyAgreementConnection(
-							new BluetoothTransportConnection(
-									BluetoothPlugin.this, s), ID);
-				}
+			return () -> {
+				StreamConnection s = ss.acceptAndOpen();
+				if (LOG.isLoggable(INFO))
+					LOG.info(ID.getString() + ": Incoming connection");
+				return new KeyAgreementConnection(
+						new BluetoothTransportConnection(
+								BluetoothPlugin.this, s), ID);
 			};
 		}
 
diff --git a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/file/UnixRemovableDriveMonitor.java b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/file/UnixRemovableDriveMonitor.java
index 8fcc0a539ad96516cccb042522a69158df5869be..4ca1a30843271160b9e039990036870f6aad3196 100644
--- a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/file/UnixRemovableDriveMonitor.java
+++ b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/file/UnixRemovableDriveMonitor.java
@@ -13,6 +13,8 @@ import java.util.List;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
+import javax.annotation.Nullable;
+
 @MethodsNotNullByDefault
 @ParametersNotNullByDefault
 abstract class UnixRemovableDriveMonitor implements RemovableDriveMonitor,
@@ -34,13 +36,12 @@ JNotifyListener {
 
 	protected abstract String[] getPathsToWatch();
 
+	@Nullable
 	private static Throwable tryLoad() {
 		try {
 			Class.forName("net.contentobjects.jnotify.JNotify");
 			return null;
-		} catch (UnsatisfiedLinkError e) {
-			return e;
-		} catch (ClassNotFoundException e) {
+		} catch (UnsatisfiedLinkError | ClassNotFoundException e) {
 			return e;
 		}
 	}
diff --git a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/modem/ModemImpl.java b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/modem/ModemImpl.java
index 4aff1d94c16537bf5541977c1cf42268cc6c7808..2ba97b1e2c5a22b8aac0562467d8eea5ba078751 100644
--- a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/modem/ModemImpl.java
+++ b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/modem/ModemImpl.java
@@ -390,15 +390,12 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
 						lock.unlock();
 					}
 				} else if (s.equals("RING")) {
-					ioExecutor.execute(new Runnable() {
-						@Override
-						public void run() {
-							try {
-								answer();
-							} catch (IOException e) {
-								if (LOG.isLoggable(WARNING))
-									LOG.log(WARNING, e.toString(), e);
-							}
+					ioExecutor.execute(() -> {
+						try {
+							answer();
+						} catch (IOException e) {
+							if (LOG.isLoggable(WARNING))
+								LOG.log(WARNING, e.toString(), e);
 						}
 					});
 				}
diff --git a/bramble-j2se/src/test/java/org/briarproject/bramble/plugin/file/PollingRemovableDriveMonitorTest.java b/bramble-j2se/src/test/java/org/briarproject/bramble/plugin/file/PollingRemovableDriveMonitorTest.java
index 9d8db1b84ddcc7743ee2bf91a6e6b62bf097e284..2c694b53bffefd0599e01e98eadf894712f22f20 100644
--- a/bramble-j2se/src/test/java/org/briarproject/bramble/plugin/file/PollingRemovableDriveMonitorTest.java
+++ b/bramble-j2se/src/test/java/org/briarproject/bramble/plugin/file/PollingRemovableDriveMonitorTest.java
@@ -26,10 +26,10 @@ public class PollingRemovableDriveMonitorTest extends BrambleTestCase {
 	@Test
 	public void testOneCallbackPerFile() throws Exception {
 		// Create a finder that returns no files the first time, then two files
-		final File file1 = new File("foo");
-		final File file2 = new File("bar");
+		File file1 = new File("foo");
+		File file2 = new File("bar");
 		@NotNullByDefault
-		final RemovableDriveFinder finder = new RemovableDriveFinder() {
+		RemovableDriveFinder finder = new RemovableDriveFinder() {
 
 			private AtomicBoolean firstCall = new AtomicBoolean(true);
 
@@ -40,8 +40,8 @@ public class PollingRemovableDriveMonitorTest extends BrambleTestCase {
 			}
 		};
 		// Create a callback that waits for two files
-		final CountDownLatch latch = new CountDownLatch(2);
-		final List<File> detected = new ArrayList<>();
+		CountDownLatch latch = new CountDownLatch(2);
+		List<File> detected = new ArrayList<>();
 		@NotNullByDefault
 		Callback callback = new Callback() {
 
@@ -57,7 +57,7 @@ public class PollingRemovableDriveMonitorTest extends BrambleTestCase {
 			}
 		};
 		// Create the monitor and start it
-		final RemovableDriveMonitor monitor = new PollingRemovableDriveMonitor(
+		RemovableDriveMonitor monitor = new PollingRemovableDriveMonitor(
 				Executors.newCachedThreadPool(), finder, 1);
 		monitor.start(callback);
 		// Wait for the monitor to detect the files
@@ -72,7 +72,7 @@ public class PollingRemovableDriveMonitorTest extends BrambleTestCase {
 	@Test
 	public void testExceptionCallback() throws Exception {
 		// Create a finder that throws an exception the second time it's polled
-		final RemovableDriveFinder finder = new RemovableDriveFinder() {
+		RemovableDriveFinder finder = new RemovableDriveFinder() {
 
 			private AtomicBoolean firstCall = new AtomicBoolean(true);
 
@@ -83,7 +83,7 @@ public class PollingRemovableDriveMonitorTest extends BrambleTestCase {
 			}
 		};
 		// Create a callback that waits for an exception
-		final CountDownLatch latch = new CountDownLatch(1);
+		CountDownLatch latch = new CountDownLatch(1);
 		@NotNullByDefault
 		Callback callback = new Callback() {
 
@@ -98,7 +98,7 @@ public class PollingRemovableDriveMonitorTest extends BrambleTestCase {
 			}
 		};
 		// Create the monitor and start it
-		final RemovableDriveMonitor monitor = new PollingRemovableDriveMonitor(
+		RemovableDriveMonitor monitor = new PollingRemovableDriveMonitor(
 				Executors.newCachedThreadPool(), finder, 1);
 		monitor.start(callback);
 		assertTrue(latch.await(10, SECONDS));
diff --git a/bramble-j2se/src/test/java/org/briarproject/bramble/plugin/file/RemovableDrivePluginTest.java b/bramble-j2se/src/test/java/org/briarproject/bramble/plugin/file/RemovableDrivePluginTest.java
index 101c74cf7796368a1995dcdd58d178f8833c96e7..7ab6001b16890fa86958840da42c5bdf7c116099 100644
--- a/bramble-j2se/src/test/java/org/briarproject/bramble/plugin/file/RemovableDrivePluginTest.java
+++ b/bramble-j2se/src/test/java/org/briarproject/bramble/plugin/file/RemovableDrivePluginTest.java
@@ -41,17 +41,17 @@ public class RemovableDrivePluginTest extends BrambleTestCase {
 
 	@Test
 	public void testWriterIsNullIfNoDrivesAreFound() throws Exception {
-		final List<File> drives = Collections.emptyList();
+		List<File> drives = Collections.emptyList();
 
 		Mockery context = new Mockery() {{
 			setThreadingPolicy(new Synchroniser());
 		}};
-		final Executor executor = context.mock(Executor.class);
-		final SimplexPluginCallback callback =
+		Executor executor = context.mock(Executor.class);
+		SimplexPluginCallback callback =
 				context.mock(SimplexPluginCallback.class);
-		final RemovableDriveFinder finder =
+		RemovableDriveFinder finder =
 				context.mock(RemovableDriveFinder.class);
-		final RemovableDriveMonitor monitor =
+		RemovableDriveMonitor monitor =
 				context.mock(RemovableDriveMonitor.class);
 
 		context.checking(new Expectations() {{
@@ -71,21 +71,21 @@ public class RemovableDrivePluginTest extends BrambleTestCase {
 
 	@Test
 	public void testWriterIsNullIfNoDriveIsChosen() throws Exception {
-		final File drive1 = new File(testDir, "1");
-		final File drive2 = new File(testDir, "2");
-		final List<File> drives = new ArrayList<>();
+		File drive1 = new File(testDir, "1");
+		File drive2 = new File(testDir, "2");
+		List<File> drives = new ArrayList<>();
 		drives.add(drive1);
 		drives.add(drive2);
 
 		Mockery context = new Mockery() {{
 			setThreadingPolicy(new Synchroniser());
 		}};
-		final Executor executor = context.mock(Executor.class);
-		final SimplexPluginCallback callback =
+		Executor executor = context.mock(Executor.class);
+		SimplexPluginCallback callback =
 				context.mock(SimplexPluginCallback.class);
-		final RemovableDriveFinder finder =
+		RemovableDriveFinder finder =
 				context.mock(RemovableDriveFinder.class);
-		final RemovableDriveMonitor monitor =
+		RemovableDriveMonitor monitor =
 				context.mock(RemovableDriveMonitor.class);
 
 		context.checking(new Expectations() {{
@@ -110,21 +110,21 @@ public class RemovableDrivePluginTest extends BrambleTestCase {
 
 	@Test
 	public void testWriterIsNullIfOutputDirDoesNotExist() throws Exception {
-		final File drive1 = new File(testDir, "1");
-		final File drive2 = new File(testDir, "2");
-		final List<File> drives = new ArrayList<>();
+		File drive1 = new File(testDir, "1");
+		File drive2 = new File(testDir, "2");
+		List<File> drives = new ArrayList<>();
 		drives.add(drive1);
 		drives.add(drive2);
 
 		Mockery context = new Mockery() {{
 			setThreadingPolicy(new Synchroniser());
 		}};
-		final Executor executor = context.mock(Executor.class);
-		final SimplexPluginCallback callback =
+		Executor executor = context.mock(Executor.class);
+		SimplexPluginCallback callback =
 				context.mock(SimplexPluginCallback.class);
-		final RemovableDriveFinder finder =
+		RemovableDriveFinder finder =
 				context.mock(RemovableDriveFinder.class);
-		final RemovableDriveMonitor monitor =
+		RemovableDriveMonitor monitor =
 				context.mock(RemovableDriveMonitor.class);
 
 		context.checking(new Expectations() {{
@@ -149,9 +149,9 @@ public class RemovableDrivePluginTest extends BrambleTestCase {
 
 	@Test
 	public void testWriterIsNullIfOutputDirIsAFile() throws Exception {
-		final File drive1 = new File(testDir, "1");
-		final File drive2 = new File(testDir, "2");
-		final List<File> drives = new ArrayList<>();
+		File drive1 = new File(testDir, "1");
+		File drive2 = new File(testDir, "2");
+		List<File> drives = new ArrayList<>();
 		drives.add(drive1);
 		drives.add(drive2);
 		// Create drive1 as a file rather than a directory
@@ -160,12 +160,12 @@ public class RemovableDrivePluginTest extends BrambleTestCase {
 		Mockery context = new Mockery() {{
 			setThreadingPolicy(new Synchroniser());
 		}};
-		final Executor executor = context.mock(Executor.class);
-		final SimplexPluginCallback callback =
+		Executor executor = context.mock(Executor.class);
+		SimplexPluginCallback callback =
 				context.mock(SimplexPluginCallback.class);
-		final RemovableDriveFinder finder =
+		RemovableDriveFinder finder =
 				context.mock(RemovableDriveFinder.class);
-		final RemovableDriveMonitor monitor =
+		RemovableDriveMonitor monitor =
 				context.mock(RemovableDriveMonitor.class);
 
 		context.checking(new Expectations() {{
@@ -190,9 +190,9 @@ public class RemovableDrivePluginTest extends BrambleTestCase {
 
 	@Test
 	public void testWriterIsNotNullIfOutputDirIsADir() throws Exception {
-		final File drive1 = new File(testDir, "1");
-		final File drive2 = new File(testDir, "2");
-		final List<File> drives = new ArrayList<>();
+		File drive1 = new File(testDir, "1");
+		File drive2 = new File(testDir, "2");
+		List<File> drives = new ArrayList<>();
 		drives.add(drive1);
 		drives.add(drive2);
 		// Create drive1 as a directory
@@ -201,12 +201,12 @@ public class RemovableDrivePluginTest extends BrambleTestCase {
 		Mockery context = new Mockery() {{
 			setThreadingPolicy(new Synchroniser());
 		}};
-		final Executor executor = context.mock(Executor.class);
-		final SimplexPluginCallback callback =
+		Executor executor = context.mock(Executor.class);
+		SimplexPluginCallback callback =
 				context.mock(SimplexPluginCallback.class);
-		final RemovableDriveFinder finder =
+		RemovableDriveFinder finder =
 				context.mock(RemovableDriveFinder.class);
-		final RemovableDriveMonitor monitor =
+		RemovableDriveMonitor monitor =
 				context.mock(RemovableDriveMonitor.class);
 
 		context.checking(new Expectations() {{
@@ -234,9 +234,9 @@ public class RemovableDrivePluginTest extends BrambleTestCase {
 
 	@Test
 	public void testWritingToWriter() throws Exception {
-		final File drive1 = new File(testDir, "1");
-		final File drive2 = new File(testDir, "2");
-		final List<File> drives = new ArrayList<>();
+		File drive1 = new File(testDir, "1");
+		File drive2 = new File(testDir, "2");
+		List<File> drives = new ArrayList<>();
 		drives.add(drive1);
 		drives.add(drive2);
 		// Create drive1 as a directory
@@ -245,12 +245,12 @@ public class RemovableDrivePluginTest extends BrambleTestCase {
 		Mockery context = new Mockery() {{
 			setThreadingPolicy(new Synchroniser());
 		}};
-		final Executor executor = context.mock(Executor.class);
-		final SimplexPluginCallback callback =
+		Executor executor = context.mock(Executor.class);
+		SimplexPluginCallback callback =
 				context.mock(SimplexPluginCallback.class);
-		final RemovableDriveFinder finder =
+		RemovableDriveFinder finder =
 				context.mock(RemovableDriveFinder.class);
-		final RemovableDriveMonitor monitor =
+		RemovableDriveMonitor monitor =
 				context.mock(RemovableDriveMonitor.class);
 
 		context.checking(new Expectations() {{
@@ -292,12 +292,12 @@ public class RemovableDrivePluginTest extends BrambleTestCase {
 		Mockery context = new Mockery() {{
 			setThreadingPolicy(new Synchroniser());
 		}};
-		final Executor executor = context.mock(Executor.class);
-		final SimplexPluginCallback callback =
+		Executor executor = context.mock(Executor.class);
+		SimplexPluginCallback callback =
 				context.mock(SimplexPluginCallback.class);
-		final RemovableDriveFinder finder =
+		RemovableDriveFinder finder =
 				context.mock(RemovableDriveFinder.class);
-		final RemovableDriveMonitor monitor =
+		RemovableDriveMonitor monitor =
 				context.mock(RemovableDriveMonitor.class);
 
 		context.checking(new Expectations() {{
@@ -318,12 +318,12 @@ public class RemovableDrivePluginTest extends BrambleTestCase {
 		Mockery context = new Mockery() {{
 			setThreadingPolicy(new Synchroniser());
 		}};
-		final Executor executor = context.mock(Executor.class);
-		final SimplexPluginCallback callback =
+		Executor executor = context.mock(Executor.class);
+		SimplexPluginCallback callback =
 				context.mock(SimplexPluginCallback.class);
-		final RemovableDriveFinder finder =
+		RemovableDriveFinder finder =
 				context.mock(RemovableDriveFinder.class);
-		final RemovableDriveMonitor monitor =
+		RemovableDriveMonitor monitor =
 				context.mock(RemovableDriveMonitor.class);
 
 		RemovableDrivePlugin plugin = new RemovableDrivePlugin(executor,
@@ -344,11 +344,11 @@ public class RemovableDrivePluginTest extends BrambleTestCase {
 		Mockery context = new Mockery() {{
 			setThreadingPolicy(new Synchroniser());
 		}};
-		final SimplexPluginCallback callback =
+		SimplexPluginCallback callback =
 				context.mock(SimplexPluginCallback.class);
-		final RemovableDriveFinder finder =
+		RemovableDriveFinder finder =
 				context.mock(RemovableDriveFinder.class);
-		final RemovableDriveMonitor monitor =
+		RemovableDriveMonitor monitor =
 				context.mock(RemovableDriveMonitor.class);
 
 		context.checking(new Expectations() {{
diff --git a/bramble-j2se/src/test/java/org/briarproject/bramble/plugin/file/UnixRemovableDriveMonitorTest.java b/bramble-j2se/src/test/java/org/briarproject/bramble/plugin/file/UnixRemovableDriveMonitorTest.java
index 0a43ba1538ca19a3bc14bf33cad82614688a13a0..f2d5204ed04242c51b5f55179bf6454960cef23a 100644
--- a/bramble-j2se/src/test/java/org/briarproject/bramble/plugin/file/UnixRemovableDriveMonitorTest.java
+++ b/bramble-j2se/src/test/java/org/briarproject/bramble/plugin/file/UnixRemovableDriveMonitorTest.java
@@ -61,10 +61,10 @@ public class UnixRemovableDriveMonitorTest extends BrambleTestCase {
 			return;
 		}
 		// Create a callback that will wait for two files before stopping
-		final List<File> detected = new ArrayList<>();
-		final CountDownLatch latch = new CountDownLatch(2);
+		List<File> detected = new ArrayList<>();
+		CountDownLatch latch = new CountDownLatch(2);
 		@NotNullByDefault
-		final Callback callback = new Callback() {
+		Callback callback = new Callback() {
 
 			@Override
 			public void driveInserted(File f) {
@@ -99,7 +99,7 @@ public class UnixRemovableDriveMonitorTest extends BrambleTestCase {
 		TestUtils.deleteTestDirectory(testDir);
 	}
 
-	private RemovableDriveMonitor createMonitor(final File dir) {
+	private RemovableDriveMonitor createMonitor(File dir) {
 		@NotNullByDefault
 		RemovableDriveMonitor monitor = new UnixRemovableDriveMonitor() {
 			@Override
diff --git a/bramble-j2se/src/test/java/org/briarproject/bramble/plugin/modem/ModemPluginTest.java b/bramble-j2se/src/test/java/org/briarproject/bramble/plugin/modem/ModemPluginTest.java
index 6f8cd501604704e5b4efb479c758f950deb2f534..6d12af19a6c95bfcfcb40703769d433639cc85fe 100644
--- a/bramble-j2se/src/test/java/org/briarproject/bramble/plugin/modem/ModemPluginTest.java
+++ b/bramble-j2se/src/test/java/org/briarproject/bramble/plugin/modem/ModemPluginTest.java
@@ -21,12 +21,12 @@ public class ModemPluginTest extends BrambleTestCase {
 	@Test
 	public void testModemCreation() throws Exception {
 		Mockery context = new Mockery();
-		final ModemFactory modemFactory = context.mock(ModemFactory.class);
-		final SerialPortList serialPortList =
+		ModemFactory modemFactory = context.mock(ModemFactory.class);
+		SerialPortList serialPortList =
 				context.mock(SerialPortList.class);
-		final ModemPlugin plugin = new ModemPlugin(modemFactory,
+		ModemPlugin plugin = new ModemPlugin(modemFactory,
 				serialPortList, null, 0);
-		final Modem modem = context.mock(Modem.class);
+		Modem modem = context.mock(Modem.class);
 		context.checking(new Expectations() {{
 			oneOf(serialPortList).getPortNames();
 			will(returnValue(new String[] { "foo", "bar", "baz" }));
@@ -53,20 +53,20 @@ public class ModemPluginTest extends BrambleTestCase {
 	@Test
 	public void testCreateConnection() throws Exception {
 		Mockery context = new Mockery();
-		final ModemFactory modemFactory = context.mock(ModemFactory.class);
-		final SerialPortList serialPortList =
+		ModemFactory modemFactory = context.mock(ModemFactory.class);
+		SerialPortList serialPortList =
 				context.mock(SerialPortList.class);
-		final DuplexPluginCallback callback =
+		DuplexPluginCallback callback =
 				context.mock(DuplexPluginCallback.class);
-		final ModemPlugin plugin = new ModemPlugin(modemFactory,
+		ModemPlugin plugin = new ModemPlugin(modemFactory,
 				serialPortList, callback, 0);
-		final Modem modem = context.mock(Modem.class);
-		final TransportProperties local = new TransportProperties();
+		Modem modem = context.mock(Modem.class);
+		TransportProperties local = new TransportProperties();
 		local.put("iso3166", ISO_1336);
-		final TransportProperties remote = new TransportProperties();
+		TransportProperties remote = new TransportProperties();
 		remote.put("iso3166", ISO_1336);
 		remote.put("number", NUMBER);
-		final ContactId contactId = new ContactId(234);
+		ContactId contactId = new ContactId(234);
 		context.checking(new Expectations() {{
 			// start()
 			oneOf(serialPortList).getPortNames();
@@ -92,20 +92,20 @@ public class ModemPluginTest extends BrambleTestCase {
 	@Test
 	public void testCreateConnectionWhenDialReturnsFalse() throws Exception {
 		Mockery context = new Mockery();
-		final ModemFactory modemFactory = context.mock(ModemFactory.class);
-		final SerialPortList serialPortList =
+		ModemFactory modemFactory = context.mock(ModemFactory.class);
+		SerialPortList serialPortList =
 				context.mock(SerialPortList.class);
-		final DuplexPluginCallback callback =
+		DuplexPluginCallback callback =
 				context.mock(DuplexPluginCallback.class);
-		final ModemPlugin plugin = new ModemPlugin(modemFactory,
+		ModemPlugin plugin = new ModemPlugin(modemFactory,
 				serialPortList, callback, 0);
-		final Modem modem = context.mock(Modem.class);
-		final TransportProperties local = new TransportProperties();
+		Modem modem = context.mock(Modem.class);
+		TransportProperties local = new TransportProperties();
 		local.put("iso3166", ISO_1336);
-		final TransportProperties remote = new TransportProperties();
+		TransportProperties remote = new TransportProperties();
 		remote.put("iso3166", ISO_1336);
 		remote.put("number", NUMBER);
-		final ContactId contactId = new ContactId(234);
+		ContactId contactId = new ContactId(234);
 		context.checking(new Expectations() {{
 			// start()
 			oneOf(serialPortList).getPortNames();
@@ -131,20 +131,20 @@ public class ModemPluginTest extends BrambleTestCase {
 	@Test
 	public void testCreateConnectionWhenDialThrowsException() throws Exception {
 		Mockery context = new Mockery();
-		final ModemFactory modemFactory = context.mock(ModemFactory.class);
-		final SerialPortList serialPortList =
+		ModemFactory modemFactory = context.mock(ModemFactory.class);
+		SerialPortList serialPortList =
 				context.mock(SerialPortList.class);
-		final DuplexPluginCallback callback =
+		DuplexPluginCallback callback =
 				context.mock(DuplexPluginCallback.class);
-		final ModemPlugin plugin = new ModemPlugin(modemFactory,
+		ModemPlugin plugin = new ModemPlugin(modemFactory,
 				serialPortList, callback, 0);
-		final Modem modem = context.mock(Modem.class);
-		final TransportProperties local = new TransportProperties();
+		Modem modem = context.mock(Modem.class);
+		TransportProperties local = new TransportProperties();
 		local.put("iso3166", ISO_1336);
-		final TransportProperties remote = new TransportProperties();
+		TransportProperties remote = new TransportProperties();
 		remote.put("iso3166", ISO_1336);
 		remote.put("number", NUMBER);
-		final ContactId contactId = new ContactId(234);
+		ContactId contactId = new ContactId(234);
 		context.checking(new Expectations() {{
 			// start()
 			oneOf(serialPortList).getPortNames();
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java
index 329f7b9968433d9a064e12cd81cfd635a66eab86..41463fe850c3a1646ae856290c4e0e7fde5b2877 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java
@@ -44,7 +44,6 @@ import org.briarproject.briar.api.sharing.event.InvitationResponseReceivedEvent;
 
 import java.util.HashMap;
 import java.util.Map;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Future;
@@ -138,16 +137,13 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
 	@Override
 	public void stopService() throws ServiceException {
 		// Clear all notifications
-		Future<Void> f = androidExecutor.runOnUiThread(new Callable<Void>() {
-			@Override
-			public Void call() {
-				clearContactNotification();
-				clearGroupMessageNotification();
-				clearForumPostNotification();
-				clearBlogPostNotification();
-				clearIntroductionSuccessNotification();
-				return null;
-			}
+		Future<Void> f = androidExecutor.runOnUiThread(() -> {
+			clearContactNotification();
+			clearGroupMessageNotification();
+			clearForumPostNotification();
+			clearBlogPostNotification();
+			clearIntroductionSuccessNotification();
+			return null;
 		});
 		try {
 			f.get();
@@ -236,44 +232,35 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
 	}
 
 	private void loadSettings() {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		dbExecutor.execute(() -> {
+			try {
+				settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
-	private void showContactNotification(final ContactId c) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				if (blockContacts) return;
-				if (c.equals(blockedContact)) return;
-				Integer count = contactCounts.get(c);
-				if (count == null) contactCounts.put(c, 1);
-				else contactCounts.put(c, count + 1);
-				contactTotal++;
-				updateContactNotification(true);
-			}
+	private void showContactNotification(ContactId c) {
+		androidExecutor.runOnUiThread(() -> {
+			if (blockContacts) return;
+			if (c.equals(blockedContact)) return;
+			Integer count = contactCounts.get(c);
+			if (count == null) contactCounts.put(c, 1);
+			else contactCounts.put(c, count + 1);
+			contactTotal++;
+			updateContactNotification(true);
 		});
 	}
 
 	@Override
-	public void clearContactNotification(final ContactId c) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				Integer count = contactCounts.remove(c);
-				if (count == null) return; // Already cleared
-				contactTotal -= count;
-				updateContactNotification(false);
-			}
+	public void clearContactNotification(ContactId c) {
+		androidExecutor.runOnUiThread(() -> {
+			Integer count = contactCounts.remove(c);
+			if (count == null) return; // Already cleared
+			contactTotal -= count;
+			updateContactNotification(false);
 		});
 	}
 
@@ -358,40 +345,30 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
 
 	@Override
 	public void clearAllContactNotifications() {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				clearContactNotification();
-			}
-		});
+		androidExecutor.runOnUiThread(
+				(Runnable) this::clearContactNotification);
 	}
 
 	@UiThread
-	private void showGroupMessageNotification(final GroupId g) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				if (blockGroups) return;
-				if (g.equals(blockedGroup)) return;
-				Integer count = groupCounts.get(g);
-				if (count == null) groupCounts.put(g, 1);
-				else groupCounts.put(g, count + 1);
-				groupTotal++;
-				updateGroupMessageNotification(true);
-			}
+	private void showGroupMessageNotification(GroupId g) {
+		androidExecutor.runOnUiThread(() -> {
+			if (blockGroups) return;
+			if (g.equals(blockedGroup)) return;
+			Integer count = groupCounts.get(g);
+			if (count == null) groupCounts.put(g, 1);
+			else groupCounts.put(g, count + 1);
+			groupTotal++;
+			updateGroupMessageNotification(true);
 		});
 	}
 
 	@Override
-	public void clearGroupMessageNotification(final GroupId g) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				Integer count = groupCounts.remove(g);
-				if (count == null) return; // Already cleared
-				groupTotal -= count;
-				updateGroupMessageNotification(false);
-			}
+	public void clearGroupMessageNotification(GroupId g) {
+		androidExecutor.runOnUiThread(() -> {
+			Integer count = groupCounts.remove(g);
+			if (count == null) return; // Already cleared
+			groupTotal -= count;
+			updateGroupMessageNotification(false);
 		});
 	}
 
@@ -445,40 +422,30 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
 
 	@Override
 	public void clearAllGroupMessageNotifications() {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				clearGroupMessageNotification();
-			}
-		});
+		androidExecutor.runOnUiThread(
+				(Runnable) this::clearGroupMessageNotification);
 	}
 
 	@UiThread
-	private void showForumPostNotification(final GroupId g) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				if (blockForums) return;
-				if (g.equals(blockedGroup)) return;
-				Integer count = forumCounts.get(g);
-				if (count == null) forumCounts.put(g, 1);
-				else forumCounts.put(g, count + 1);
-				forumTotal++;
-				updateForumPostNotification(true);
-			}
+	private void showForumPostNotification(GroupId g) {
+		androidExecutor.runOnUiThread(() -> {
+			if (blockForums) return;
+			if (g.equals(blockedGroup)) return;
+			Integer count = forumCounts.get(g);
+			if (count == null) forumCounts.put(g, 1);
+			else forumCounts.put(g, count + 1);
+			forumTotal++;
+			updateForumPostNotification(true);
 		});
 	}
 
 	@Override
-	public void clearForumPostNotification(final GroupId g) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				Integer count = forumCounts.remove(g);
-				if (count == null) return; // Already cleared
-				forumTotal -= count;
-				updateForumPostNotification(false);
-			}
+	public void clearForumPostNotification(GroupId g) {
+		androidExecutor.runOnUiThread(() -> {
+			Integer count = forumCounts.remove(g);
+			if (count == null) return; // Already cleared
+			forumTotal -= count;
+			updateForumPostNotification(false);
 		});
 	}
 
@@ -532,40 +499,30 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
 
 	@Override
 	public void clearAllForumPostNotifications() {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				clearForumPostNotification();
-			}
-		});
+		androidExecutor.runOnUiThread(
+				(Runnable) this::clearForumPostNotification);
 	}
 
 	@UiThread
-	private void showBlogPostNotification(final GroupId g) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				if (blockBlogs) return;
-				if (g.equals(blockedGroup)) return;
-				Integer count = blogCounts.get(g);
-				if (count == null) blogCounts.put(g, 1);
-				else blogCounts.put(g, count + 1);
-				blogTotal++;
-				updateBlogPostNotification(true);
-			}
+	private void showBlogPostNotification(GroupId g) {
+		androidExecutor.runOnUiThread(() -> {
+			if (blockBlogs) return;
+			if (g.equals(blockedGroup)) return;
+			Integer count = blogCounts.get(g);
+			if (count == null) blogCounts.put(g, 1);
+			else blogCounts.put(g, count + 1);
+			blogTotal++;
+			updateBlogPostNotification(true);
 		});
 	}
 
 	@Override
-	public void clearBlogPostNotification(final GroupId g) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				Integer count = blogCounts.remove(g);
-				if (count == null) return; // Already cleared
-				blogTotal -= count;
-				updateBlogPostNotification(false);
-			}
+	public void clearBlogPostNotification(GroupId g) {
+		androidExecutor.runOnUiThread(() -> {
+			Integer count = blogCounts.remove(g);
+			if (count == null) return; // Already cleared
+			blogTotal -= count;
+			updateBlogPostNotification(false);
 		});
 	}
 
@@ -606,22 +563,15 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
 
 	@Override
 	public void clearAllBlogPostNotifications() {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				clearBlogPostNotification();
-			}
-		});
+		androidExecutor.runOnUiThread(
+				(Runnable) this::clearBlogPostNotification);
 	}
 
 	private void showIntroductionNotification() {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				if (blockIntroductions) return;
-				introductionTotal++;
-				updateIntroductionNotification();
-			}
+		androidExecutor.runOnUiThread(() -> {
+			if (blockIntroductions) return;
+			introductionTotal++;
+			updateIntroductionNotification();
 		});
 	}
 
@@ -656,71 +606,41 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
 
 	@Override
 	public void clearAllIntroductionNotifications() {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				clearIntroductionSuccessNotification();
-			}
-		});
+		androidExecutor.runOnUiThread(
+				this::clearIntroductionSuccessNotification);
 	}
 
 	@Override
-	public void blockNotification(final GroupId g) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				blockedGroup = g;
-			}
-		});
+	public void blockNotification(GroupId g) {
+		androidExecutor.runOnUiThread((Runnable) () -> blockedGroup = g);
 	}
 
 	@Override
-	public void unblockNotification(final GroupId g) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				if (g.equals(blockedGroup)) blockedGroup = null;
-			}
+	public void unblockNotification(GroupId g) {
+		androidExecutor.runOnUiThread(() -> {
+			if (g.equals(blockedGroup)) blockedGroup = null;
 		});
 	}
 
 	@Override
-	public void blockContactNotification(final ContactId c) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				blockedContact = c;
-			}
-		});
+	public void blockContactNotification(ContactId c) {
+		androidExecutor.runOnUiThread((Runnable) () -> blockedContact = c);
 	}
 
 	@Override
-	public void unblockContactNotification(final ContactId c) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				if (c.equals(blockedContact)) blockedContact = null;
-			}
+	public void unblockContactNotification(ContactId c) {
+		androidExecutor.runOnUiThread(() -> {
+			if (c.equals(blockedContact)) blockedContact = null;
 		});
 	}
 
 	@Override
 	public void blockAllBlogPostNotifications() {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				blockBlogs = true;
-			}
-		});
+		androidExecutor.runOnUiThread((Runnable) () -> blockBlogs = true);
 	}
 
 	@Override
 	public void unblockAllBlogPostNotifications() {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				blockBlogs = false;
-			}
-		});
+		androidExecutor.runOnUiThread((Runnable) () -> blockBlogs = false);
 	}
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java
index 4d5dad242d716b61466463ff9e3ce5dc95e1d33a..725a690475b0249b1b2456cbd6f425fcecfde02f 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java
@@ -80,7 +80,7 @@ public class AppModule {
 	@Provides
 	@Singleton
 	DatabaseConfig provideDatabaseConfig(Application app) {
-		final File dir = app.getApplicationContext().getDir("db", MODE_PRIVATE);
+		File dir = app.getApplicationContext().getDir("db", MODE_PRIVATE);
 		@MethodsNotNullByDefault
 		@ParametersNotNullByDefault
 		DatabaseConfig databaseConfig = new DatabaseConfig() {
@@ -132,7 +132,7 @@ public class AppModule {
 
 	@Provides
 	@Singleton
-	DevConfig provideDevConfig(final CryptoComponent crypto) {
+	DevConfig provideDevConfig(CryptoComponent crypto) {
 		@NotNullByDefault
 		DevConfig devConfig = new DevConfig() {
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java b/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java
index 9c12a7ace5cb929d46a0efa531d81630884229b0..0e6bb7c399b79d68f0bc942164f8d0b4013b6125 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java
@@ -111,34 +111,31 @@ public class BriarService extends Service {
 		}.start();
 	}
 
-	private void showStartupFailureNotification(final StartResult result) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				NotificationCompat.Builder b =
-						new NotificationCompat.Builder(BriarService.this);
-				b.setSmallIcon(android.R.drawable.stat_notify_error);
-				b.setContentTitle(getText(
-						R.string.startup_failed_notification_title));
-				b.setContentText(getText(
-						R.string.startup_failed_notification_text));
-				Intent i = new Intent(BriarService.this,
-						StartupFailureActivity.class);
-				i.setFlags(FLAG_ACTIVITY_NEW_TASK);
-				i.putExtra("briar.START_RESULT", result);
-				i.putExtra("briar.FAILURE_NOTIFICATION_ID",
-						FAILURE_NOTIFICATION_ID);
-				b.setContentIntent(PendingIntent.getActivity(BriarService.this,
-						0, i, FLAG_UPDATE_CURRENT));
-				Object o = getSystemService(NOTIFICATION_SERVICE);
-				NotificationManager nm = (NotificationManager) o;
-				nm.notify(FAILURE_NOTIFICATION_ID, b.build());
-				// Bring the dashboard to the front to clear the back stack
-				i = new Intent(BriarService.this, NavDrawerActivity.class);
-				i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP);
-				i.putExtra("briar.STARTUP_FAILED", true);
-				startActivity(i);
-			}
+	private void showStartupFailureNotification(StartResult result) {
+		androidExecutor.runOnUiThread(() -> {
+			NotificationCompat.Builder b =
+					new NotificationCompat.Builder(BriarService.this);
+			b.setSmallIcon(android.R.drawable.stat_notify_error);
+			b.setContentTitle(getText(
+					R.string.startup_failed_notification_title));
+			b.setContentText(getText(
+					R.string.startup_failed_notification_text));
+			Intent i = new Intent(BriarService.this,
+					StartupFailureActivity.class);
+			i.setFlags(FLAG_ACTIVITY_NEW_TASK);
+			i.putExtra("briar.START_RESULT", result);
+			i.putExtra("briar.FAILURE_NOTIFICATION_ID",
+					FAILURE_NOTIFICATION_ID);
+			b.setContentIntent(PendingIntent.getActivity(BriarService.this,
+					0, i, FLAG_UPDATE_CURRENT));
+			Object o = getSystemService(NOTIFICATION_SERVICE);
+			NotificationManager nm = (NotificationManager) o;
+			nm.notify(FAILURE_NOTIFICATION_ID, b.build());
+			// Bring the dashboard to the front to clear the back stack
+			i = new Intent(BriarService.this, NavDrawerActivity.class);
+			i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP);
+			i.putExtra("briar.STARTUP_FAILED", true);
+			startActivity(i);
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/BaseActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/BaseActivity.java
index 628c9e646ff56ce0e3357771c7da840615fde6c6..218f5b13ca2b6be0d9f46740cdb3ce26693b0cff 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/activity/BaseActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/BaseActivity.java
@@ -151,12 +151,9 @@ public abstract class BaseActivity extends AppCompatActivity
 	}
 
 	@Override
-	public void runOnUiThreadUnlessDestroyed(final Runnable r) {
-		runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				if (!destroyed && !isFinishing()) r.run();
-			}
+	public void runOnUiThreadUnlessDestroyed(Runnable r) {
+		runOnUiThread(() -> {
+			if (!destroyed && !isFinishing()) r.run();
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java
index 33ed5bfc3aae4d5354979d4f8a9891cc64751f7b..e98a63cfa560756c7a97e53cbce1fe84966991e1 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java
@@ -13,7 +13,6 @@ import android.view.Window;
 import org.briarproject.briar.R;
 import org.briarproject.briar.android.controller.BriarController;
 import org.briarproject.briar.android.controller.DbController;
-import org.briarproject.briar.android.controller.handler.ResultHandler;
 import org.briarproject.briar.android.login.PasswordActivity;
 import org.briarproject.briar.android.panic.ExitActivity;
 
@@ -98,21 +97,12 @@ public abstract class BriarActivity extends BaseActivity {
 		return toolbar;
 	}
 
-	protected void signOut(final boolean removeFromRecentApps) {
+	protected void signOut(boolean removeFromRecentApps) {
 		if (briarController.hasEncryptionKey()) {
 			// Don't use UiResultHandler because we want the result even if
 			// this activity has been destroyed
-			briarController.signOut(new ResultHandler<Void>() {
-				@Override
-				public void onResult(Void result) {
-					runOnUiThread(new Runnable() {
-						@Override
-						public void run() {
-							exit(removeFromRecentApps);
-						}
-					});
-				}
-			});
+			briarController.signOut(result -> runOnUiThread(
+					() -> exit(removeFromRecentApps)));
 		} else {
 			exit(removeFromRecentApps);
 		}
@@ -146,11 +136,6 @@ public abstract class BriarActivity extends BaseActivity {
 
 	@Deprecated
 	protected void finishOnUiThread() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				supportFinishAfterTransition();
-			}
-		});
+		runOnUiThreadUnlessDestroyed(this::supportFinishAfterTransition);
 	}
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/BaseControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/BaseControllerImpl.java
index 457dd26fa1cae932312e638ebfae30e028980c4d..e2b588dfa00ff7c0ac9b50958efd0f164a1e94fa 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/BaseControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/BaseControllerImpl.java
@@ -84,39 +84,26 @@ abstract class BaseControllerImpl extends DbControllerImpl
 		this.listener = listener;
 	}
 
-	void onBlogPostAdded(final BlogPostHeader h, final boolean local) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onBlogPostAdded(h, local);
-			}
-		});
+	void onBlogPostAdded(BlogPostHeader h, boolean local) {
+		listener.runOnUiThreadUnlessDestroyed(
+				() -> listener.onBlogPostAdded(h, local));
 	}
 
 	void onBlogRemoved() {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onBlogRemoved();
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(() -> listener.onBlogRemoved());
 	}
 
-
 	@Override
-	public void loadBlogPosts(final GroupId groupId,
-			final ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Collection<BlogPostItem> items = loadItems(groupId);
-					handler.onResult(items);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+	public void loadBlogPosts(GroupId groupId,
+			ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				Collection<BlogPostItem> items = loadItems(groupId);
+				handler.onResult(items);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -142,8 +129,8 @@ abstract class BaseControllerImpl extends DbControllerImpl
 	}
 
 	@Override
-	public void loadBlogPost(final BlogPostHeader header,
-			final ResultExceptionHandler<BlogPostItem, DbException> handler) {
+	public void loadBlogPost(BlogPostHeader header,
+			ResultExceptionHandler<BlogPostItem, DbException> handler) {
 
 		String body = bodyCache.get(header.getId());
 		if (body != null) {
@@ -151,28 +138,25 @@ abstract class BaseControllerImpl extends DbControllerImpl
 			handler.onResult(new BlogPostItem(header, body));
 			return;
 		}
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					BlogPostItem item = getItem(header);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading body took " + duration + " ms");
-					handler.onResult(item);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				BlogPostItem item = getItem(header);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading body took " + duration + " ms");
+				handler.onResult(item);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
 
 	@Override
-	public void loadBlogPost(final GroupId g, final MessageId m,
-			final ResultExceptionHandler<BlogPostItem, DbException> handler) {
+	public void loadBlogPost(GroupId g, MessageId m,
+			ResultExceptionHandler<BlogPostItem, DbException> handler) {
 
 		BlogPostHeader header = headerCache.get(m);
 		if (header != null) {
@@ -180,43 +164,36 @@ abstract class BaseControllerImpl extends DbControllerImpl
 			loadBlogPost(header, handler);
 			return;
 		}
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					BlogPostHeader header = getPostHeader(g, m);
-					BlogPostItem item = getItem(header);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading post took " + duration + " ms");
-					handler.onResult(item);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				BlogPostHeader header1 = getPostHeader(g, m);
+				BlogPostItem item = getItem(header1);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading post took " + duration + " ms");
+				handler.onResult(item);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
 
 	@Override
-	public void repeatPost(final BlogPostItem item,
-			final @Nullable String comment,
-			final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					LocalAuthor a = identityManager.getLocalAuthor();
-					Blog b = blogManager.getPersonalBlog(a);
-					BlogPostHeader h = item.getHeader();
-					blogManager.addLocalComment(a, b.getId(), comment, h);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+	public void repeatPost(BlogPostItem item, @Nullable String comment,
+			ExceptionHandler<DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				LocalAuthor a = identityManager.getLocalAuthor();
+				Blog b = blogManager.getPersonalBlog(a);
+				BlogPostHeader h = item.getHeader();
+				blogManager.addLocalComment(a, b.getId(), comment, h);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/BasePostFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/BasePostFragment.java
index 222b7cae83042b90d9c08d6e0a3092006da2dd30..7817c5a3ae05f3b3ca75f7e3a182d0667cedd2c8 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/BasePostFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/BasePostFragment.java
@@ -99,13 +99,10 @@ abstract class BasePostFragment extends BaseFragment {
 	}
 
 	private void startPeriodicUpdate() {
-		refresher = new Runnable() {
-			@Override
-			public void run() {
-				LOG.info("Updating Content...");
-				ui.updateDate(post.getTimestamp());
-				handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
-			}
+		refresher = () -> {
+			LOG.info("Updating Content...");
+			ui.updateDate(post.getTimestamp());
+			handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
 		};
 		LOG.info("Adding Handler Callback");
 		handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogActivity.java
index 5521b9bea4cbacae4635c12cfcff408dd08e40ed..2d3c9b3972a240e5b115d97be529bac7baf10729 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogActivity.java
@@ -3,7 +3,6 @@ package org.briarproject.briar.android.blog;
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.v7.widget.Toolbar;
-import android.view.View;
 
 import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
 import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
@@ -33,7 +32,7 @@ public class BlogActivity extends BriarActivity
 		Intent i = getIntent();
 		byte[] b = i.getByteArrayExtra(GROUP_ID);
 		if (b == null) throw new IllegalStateException("No group ID in intent");
-		final GroupId groupId = new GroupId(b);
+		GroupId groupId = new GroupId(b);
 		blogController.setGroupId(groupId);
 
 		setContentView(R.layout.activity_fragment_container_toolbar);
@@ -41,16 +40,12 @@ public class BlogActivity extends BriarActivity
 
 		// Open Sharing Status on Toolbar click
 		if (toolbar != null) {
-			toolbar.setOnClickListener(
-					new View.OnClickListener() {
-						@Override
-						public void onClick(View v) {
-							Intent i = new Intent(BlogActivity.this,
-									BlogSharingStatusActivity.class);
-							i.putExtra(GROUP_ID, groupId.getBytes());
-							startActivity(i);
-						}
-					});
+			toolbar.setOnClickListener(v -> {
+				Intent i1 = new Intent(BlogActivity.this,
+						BlogSharingStatusActivity.class);
+				i1.putExtra(GROUP_ID, groupId.getBytes());
+				startActivity(i1);
+			});
 		}
 
 		if (state == null) {
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogControllerImpl.java
index 21d0856c222cc3bf7d9baea2b329842c9c48dd7b..be7b8ff2222cd4fc230f6393f7dbd193efc8bd87 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogControllerImpl.java
@@ -125,108 +125,89 @@ class BlogControllerImpl extends BaseControllerImpl
 		}
 	}
 
-	private void onBlogInvitationAccepted(final ContactId c) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onBlogInvitationAccepted(c);
-			}
-		});
+	private void onBlogInvitationAccepted(ContactId c) {
+		listener.runOnUiThreadUnlessDestroyed(
+				() -> listener.onBlogInvitationAccepted(c));
 	}
 
-	private void onBlogLeft(final ContactId c) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onBlogLeft(c);
-			}
-		});
+	private void onBlogLeft(ContactId c) {
+		listener.runOnUiThreadUnlessDestroyed(() -> listener.onBlogLeft(c));
 	}
 
 	@Override
 	public void loadBlogPosts(
-			final ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {
+			ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {
 		if (groupId == null) throw new IllegalStateException();
 		loadBlogPosts(groupId, handler);
 	}
 
 	@Override
-	public void loadBlogPost(final MessageId m,
-			final ResultExceptionHandler<BlogPostItem, DbException> handler) {
+	public void loadBlogPost(MessageId m,
+			ResultExceptionHandler<BlogPostItem, DbException> handler) {
 		if (groupId == null) throw new IllegalStateException();
 		loadBlogPost(groupId, m, handler);
 	}
 
 	@Override
 	public void loadBlog(
-			final ResultExceptionHandler<BlogItem, DbException> handler) {
+			ResultExceptionHandler<BlogItem, DbException> handler) {
 		if (groupId == null) throw new IllegalStateException();
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					LocalAuthor a = identityManager.getLocalAuthor();
-					Blog b = blogManager.getBlog(groupId);
-					boolean ours = a.getId().equals(b.getAuthor().getId());
-					boolean removable = blogManager.canBeRemoved(b);
-					BlogItem blog = new BlogItem(b, ours, removable);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading blog took " + duration + " ms");
-					handler.onResult(blog);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				LocalAuthor a = identityManager.getLocalAuthor();
+				Blog b = blogManager.getBlog(groupId);
+				boolean ours = a.getId().equals(b.getAuthor().getId());
+				boolean removable = blogManager.canBeRemoved(b);
+				BlogItem blog = new BlogItem(b, ours, removable);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading blog took " + duration + " ms");
+				handler.onResult(blog);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
 
 	@Override
-	public void deleteBlog(
-			final ResultExceptionHandler<Void, DbException> handler) {
+	public void deleteBlog(ResultExceptionHandler<Void, DbException> handler) {
 		if (groupId == null) throw new IllegalStateException();
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					Blog b = blogManager.getBlog(groupId);
-					blogManager.removeBlog(b);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Removing blog took " + duration + " ms");
-					handler.onResult(null);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				Blog b = blogManager.getBlog(groupId);
+				blogManager.removeBlog(b);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Removing blog took " + duration + " ms");
+				handler.onResult(null);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
 
 	@Override
 	public void loadSharingContacts(
-			final ResultExceptionHandler<Collection<ContactId>, DbException> handler) {
+			ResultExceptionHandler<Collection<ContactId>, DbException> handler) {
 		if (groupId == null) throw new IllegalStateException();
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Collection<Contact> contacts =
-							blogSharingManager.getSharedWith(groupId);
-					Collection<ContactId> contactIds =
-							new ArrayList<>(contacts.size());
-					for (Contact c : contacts) contactIds.add(c.getId());
-					handler.onResult(contactIds);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				Collection<Contact> contacts =
+						blogSharingManager.getSharedWith(groupId);
+				Collection<ContactId> contactIds =
+						new ArrayList<>(contacts.size());
+				for (Contact c : contacts) contactIds.add(c.getId());
+				handler.onResult(contactIds);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogFragment.java
index d1fb275e55a10ceea44dc261368f22d844f50004..7f6e36eda4787ef0a02a75b9856b9e46b6116080 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogFragment.java
@@ -137,7 +137,7 @@ public class BlogFragment extends BaseFragment
 	}
 
 	@Override
-	public boolean onOptionsItemSelected(final MenuItem item) {
+	public boolean onOptionsItemSelected(MenuItem item) {
 		switch (item.getItemId()) {
 			case R.id.action_write_blog_post:
 				Intent i = new Intent(getActivity(),
@@ -184,7 +184,7 @@ public class BlogFragment extends BaseFragment
 	}
 
 	@Override
-	public void onBlogPostAdded(BlogPostHeader header, final boolean local) {
+	public void onBlogPostAdded(BlogPostHeader header, boolean local) {
 		blogController.loadBlogPost(header,
 				new UiResultExceptionHandler<BlogPostItem, DbException>(
 						this) {
@@ -224,7 +224,7 @@ public class BlogFragment extends BaseFragment
 		getContext().startActivity(i);
 	}
 
-	private void loadBlogPosts(final boolean reload) {
+	private void loadBlogPosts(boolean reload) {
 		blogController.loadBlogPosts(
 				new UiResultExceptionHandler<Collection<BlogPostItem>,
 						DbException>(this) {
@@ -331,12 +331,7 @@ public class BlogFragment extends BaseFragment
 				Snackbar.make(list, stringId, Snackbar.LENGTH_LONG);
 		snackbar.getView().setBackgroundResource(R.color.briar_primary);
 		if (scroll) {
-			View.OnClickListener onClick = new View.OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					list.smoothScrollToPosition(0);
-				}
-			};
+			View.OnClickListener onClick = v -> list.smoothScrollToPosition(0);
 			snackbar.setActionTextColor(ContextCompat
 					.getColor(getContext(),
 							R.color.briar_button_positive));
@@ -347,12 +342,7 @@ public class BlogFragment extends BaseFragment
 
 	private void showDeleteDialog() {
 		DialogInterface.OnClickListener okListener =
-				new DialogInterface.OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialog, int which) {
-						deleteBlog();
-					}
-				};
+				(dialog, which) -> deleteBlog();
 		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(),
 				R.style.BriarDialogTheme);
 		builder.setTitle(getString(R.string.blogs_remove_blog));
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogPostViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogPostViewHolder.java
index 484605f6e732e73782fc0c8dcb29351501f789e9..4e01c943f6e67d80bcaacd1f422cb94107160869 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogPostViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogPostViewHolder.java
@@ -13,7 +13,6 @@ import android.support.v7.widget.RecyclerView;
 import android.text.Spanned;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.TextView;
@@ -89,18 +88,13 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
 		return "blogPost" + id.hashCode();
 	}
 
-	void bindItem(@Nullable final BlogPostItem item) {
+	void bindItem(@Nullable BlogPostItem item) {
 		if (item == null) return;
 
 		setTransitionName(item.getId());
 		if (!fullText) {
 			layout.setClickable(true);
-			layout.setOnClickListener(new OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					listener.onBlogPostClick(item);
-				}
-			});
+			layout.setOnClickListener(v -> listener.onBlogPostClick(item));
 		}
 
 		// author and date
@@ -113,12 +107,7 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
 				item.isRssFeed() ? AuthorView.RSS_FEED : AuthorView.NORMAL);
 		// TODO make author clickable more often #624
 		if (!fullText && item.getHeader().getType() == POST) {
-			author.setAuthorClickable(new OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					listener.onAuthorClick(item);
-				}
-			});
+			author.setAuthorClickable(v -> listener.onAuthorClick(item));
 		} else {
 			author.setAuthorNotClickable();
 		}
@@ -137,23 +126,20 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
 		}
 
 		// reblog button
-		reblogButton.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				Intent i = new Intent(ctx, ReblogActivity.class);
-				i.putExtra(GROUP_ID, item.getGroupId().getBytes());
-				i.putExtra(POST_ID, item.getId().getBytes());
-
-				if (Build.VERSION.SDK_INT >= 23) {
-					ActivityOptionsCompat options =
-							makeSceneTransitionAnimation((Activity) ctx, layout,
-									getTransitionName(item.getId()));
-					ActivityCompat.startActivity((Activity) ctx, i,
-							options.toBundle());
-				} else {
-					// work-around for android bug #224270
-					ctx.startActivity(i);
-				}
+		reblogButton.setOnClickListener(v -> {
+			Intent i = new Intent(ctx, ReblogActivity.class);
+			i.putExtra(GROUP_ID, item.getGroupId().getBytes());
+			i.putExtra(POST_ID, item.getId().getBytes());
+
+			if (Build.VERSION.SDK_INT >= 23) {
+				ActivityOptionsCompat options =
+						makeSceneTransitionAnimation((Activity) ctx, layout,
+								getTransitionName(item.getId()));
+				ActivityCompat.startActivity((Activity) ctx, i,
+						options.toBundle());
+			} else {
+				// work-around for android bug #224270
+				ctx.startActivity(i);
 			}
 		});
 
@@ -166,18 +152,13 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
 		}
 	}
 
-	private void onBindComment(final BlogCommentItem item) {
+	private void onBindComment(BlogCommentItem item) {
 		// reblogger
 		reblogger.setAuthor(item.getAuthor());
 		reblogger.setAuthorStatus(item.getAuthorStatus());
 		reblogger.setDate(item.getTimestamp());
 		if (!fullText) {
-			reblogger.setAuthorClickable(new OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					listener.onAuthorClick(item);
-				}
-			});
+			reblogger.setAuthorClickable(v -> listener.onAuthorClick(item));
 		}
 		reblogger.setVisibility(VISIBLE);
 		reblogger.setPersona(AuthorView.REBLOGGER);
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedControllerImpl.java
index 1d02c8fdc197cd99c58cd6a3c3497c301202c0e4..1118fe654da6c0fd0a44d32b04717dbdbedb9525 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedControllerImpl.java
@@ -91,63 +91,50 @@ class FeedControllerImpl extends BaseControllerImpl
 	}
 
 	private void onBlogAdded() {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onBlogAdded();
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(() -> listener.onBlogAdded());
 	}
 
 	@Override
 	public void loadBlogPosts(
-			final ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					Collection<BlogPostItem> posts = new ArrayList<>();
-					for (Blog b : blogManager.getBlogs()) {
-						try {
-							posts.addAll(loadItems(b.getId()));
-						} catch (NoSuchGroupException | NoSuchMessageException e) {
-							if (LOG.isLoggable(WARNING))
-								LOG.log(WARNING, e.toString(), e);
-						}
+			ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				Collection<BlogPostItem> posts = new ArrayList<>();
+				for (Blog b : blogManager.getBlogs()) {
+					try {
+						posts.addAll(loadItems(b.getId()));
+					} catch (NoSuchGroupException | NoSuchMessageException e) {
+						if (LOG.isLoggable(WARNING))
+							LOG.log(WARNING, e.toString(), e);
 					}
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading all posts took " + duration + " ms");
-					handler.onResult(posts);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
 				}
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading all posts took " + duration + " ms");
+				handler.onResult(posts);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
 
 	@Override
 	public void loadPersonalBlog(
-			final ResultExceptionHandler<Blog, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					Author a = identityManager.getLocalAuthor();
-					Blog b = blogManager.getPersonalBlog(a);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading blog took " + duration + " ms");
-					handler.onResult(b);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+			ResultExceptionHandler<Blog, DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				Author a = identityManager.getLocalAuthor();
+				Blog b = blogManager.getPersonalBlog(a);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading blog took " + duration + " ms");
+				handler.onResult(b);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedFragment.java
index 097de3921ef188f285b43b90337244bea0f1f431..a884510a0ff8c9c9d5f40d3f5ea86c7c3fb6b62a 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedFragment.java
@@ -135,8 +135,8 @@ public class FeedFragment extends BaseFragment implements
 				});
 	}
 
-	private void loadBlogPosts(final boolean clear) {
-		final int revision = adapter.getRevision();
+	private void loadBlogPosts(boolean clear) {
+		int revision = adapter.getRevision();
 		feedController.loadBlogPosts(
 				new UiResultExceptionHandler<Collection<BlogPostItem>, DbException>(
 						this) {
@@ -167,7 +167,7 @@ public class FeedFragment extends BaseFragment implements
 	}
 
 	@Override
-	public boolean onOptionsItemSelected(final MenuItem item) {
+	public boolean onOptionsItemSelected(MenuItem item) {
 		if (personalBlog == null) return false;
 		switch (item.getItemId()) {
 			case R.id.action_write_blog_post:
@@ -193,7 +193,7 @@ public class FeedFragment extends BaseFragment implements
 	}
 
 	@Override
-	public void onBlogPostAdded(BlogPostHeader header, final boolean local) {
+	public void onBlogPostAdded(BlogPostHeader header, boolean local) {
 		feedController.loadBlogPost(header,
 				new UiResultExceptionHandler<BlogPostItem, DbException>(
 						this) {
@@ -246,12 +246,7 @@ public class FeedFragment extends BaseFragment implements
 		Snackbar s = Snackbar.make(list, stringRes, LENGTH_LONG);
 		s.getView().setBackgroundResource(R.color.briar_primary);
 		if (scroll) {
-			OnClickListener onClick = new OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					list.smoothScrollToPosition(0);
-				}
-			};
+			OnClickListener onClick = v -> list.smoothScrollToPosition(0);
 			s.setActionTextColor(ContextCompat
 					.getColor(getContext(),
 							R.color.briar_button_positive));
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/ReblogFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/ReblogFragment.java
index 6029cd79f73497040d4b0bba055ab6a715344697..db6625bf7b5878ee361a98c017104c318e25b883 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/ReblogFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/ReblogFragment.java
@@ -114,12 +114,7 @@ public class ReblogFragment extends BaseFragment implements TextInputListener {
 
 		ui.input.setListener(this);
 		ui.input.setSendButtonEnabled(true);
-		ui.scrollView.post(new Runnable() {
-			@Override
-			public void run() {
-				ui.scrollView.fullScroll(FOCUS_DOWN);
-			}
-		});
+		ui.scrollView.post(() -> ui.scrollView.fullScroll(FOCUS_DOWN));
 	}
 
 	@Override
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedAdapter.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedAdapter.java
index e4ed107b6a9686509956a6e2bc717f417763dcd0..4318958cd4bece6f0896f1f11f87436db311975c 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedAdapter.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedAdapter.java
@@ -4,7 +4,6 @@ import android.content.Context;
 import android.support.v7.widget.RecyclerView;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.ImageButton;
 import android.widget.TextView;
@@ -35,19 +34,14 @@ class RssFeedAdapter extends BriarAdapter<Feed, RssFeedAdapter.FeedViewHolder> {
 
 	@Override
 	public void onBindViewHolder(FeedViewHolder ui, int position) {
-		final Feed item = getItemAt(position);
+		Feed item = getItemAt(position);
 		if (item == null) return;
 
 		// Feed Title
 		ui.title.setText(item.getTitle());
 
 		// Delete Button
-		ui.delete.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				listener.onDeleteClick(item);
-			}
-		});
+		ui.delete.setOnClickListener(v -> listener.onDeleteClick(item));
 
 		// Author
 		if (item.getAuthor() != null) {
@@ -72,12 +66,7 @@ class RssFeedAdapter extends BriarAdapter<Feed, RssFeedAdapter.FeedViewHolder> {
 		}
 
 		// Open feed's blog when clicked
-		ui.layout.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				listener.onFeedClick(item);
-			}
-		});
+		ui.layout.setOnClickListener(v -> listener.onFeedClick(item));
 	}
 
 	@Override
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportActivity.java
index c382f1a8cb6f7df6bf67a5ad104c0120180d84d7..3629f9bef02809bfcf9ffc7cf104483bf1d752a9 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportActivity.java
@@ -1,6 +1,5 @@
 package org.briarproject.briar.android.blog;
 
-import android.content.DialogInterface;
 import android.os.Bundle;
 import android.support.v7.app.AlertDialog;
 import android.text.Editable;
@@ -8,7 +7,6 @@ import android.text.TextWatcher;
 import android.util.Patterns;
 import android.view.Menu;
 import android.view.MenuItem;
-import android.view.View;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ProgressBar;
@@ -75,12 +73,7 @@ public class RssFeedImportActivity extends BriarActivity {
 		});
 
 		importButton = (Button) findViewById(R.id.importButton);
-		importButton.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				publish();
-			}
-		});
+		importButton.setOnClickListener(v -> publish());
 
 		progressBar = (ProgressBar) findViewById(R.id.progressBar);
 	}
@@ -125,55 +118,38 @@ public class RssFeedImportActivity extends BriarActivity {
 		importFeed(url);
 	}
 
-	private void importFeed(final String url) {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					feedManager.addFeed(url);
-					feedImported();
-				} catch (DbException | IOException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					importFailed();
-				}
+	private void importFeed(String url) {
+		ioExecutor.execute(() -> {
+			try {
+				feedManager.addFeed(url);
+				feedImported();
+			} catch (DbException | IOException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				importFailed();
 			}
 		});
 	}
 
 	private void feedImported() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				supportFinishAfterTransition();
-			}
-		});
+		runOnUiThreadUnlessDestroyed(this::supportFinishAfterTransition);
 	}
 
 	private void importFailed() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				// hide progress bar, show publish button
-				progressBar.setVisibility(GONE);
-				importButton.setVisibility(VISIBLE);
-
-				// show error dialog
-				AlertDialog.Builder builder =
-						new AlertDialog.Builder(RssFeedImportActivity.this,
-								R.style.BriarDialogTheme);
-				builder.setMessage(R.string.blogs_rss_feeds_import_error);
-				builder.setNegativeButton(R.string.cancel, null);
-				builder.setPositiveButton(R.string.try_again_button,
-						new DialogInterface.OnClickListener() {
-							@Override
-							public void onClick(DialogInterface dialog, int which) {
-								publish();
-							}
-						});
-				AlertDialog dialog = builder.create();
-				dialog.show();
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			// hide progress bar, show publish button
+			progressBar.setVisibility(GONE);
+			importButton.setVisibility(VISIBLE);
+
+			// show error dialog
+			AlertDialog.Builder builder =
+					new AlertDialog.Builder(RssFeedImportActivity.this,
+							R.style.BriarDialogTheme);
+			builder.setMessage(R.string.blogs_rss_feeds_import_error);
+			builder.setNegativeButton(R.string.cancel, null);
+			builder.setPositiveButton(R.string.try_again_button,
+					(dialog, which) -> publish());
+			AlertDialog dialog = builder.create();
+			dialog.show();
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedManageActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedManageActivity.java
index 8525f1f653f5e1547612504624567664b1cea465..49dbc997d33a5931552c7212f49e08778fc9a84c 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedManageActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedManageActivity.java
@@ -103,14 +103,9 @@ public class RssFeedManageActivity extends BriarActivity
 	}
 
 	@Override
-	public void onDeleteClick(final Feed feed) {
+	public void onDeleteClick(Feed feed) {
 		DialogInterface.OnClickListener okListener =
-				new DialogInterface.OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialog, int which) {
-						deleteFeed(feed);
-					}
-				};
+				(dialog, which) -> deleteFeed(feed);
 		AlertDialog.Builder builder = new AlertDialog.Builder(this,
 				R.style.BriarDialogTheme);
 		builder.setTitle(getString(R.string.blogs_rss_remove_feed));
@@ -123,82 +118,60 @@ public class RssFeedManageActivity extends BriarActivity
 	}
 
 	private void loadFeeds() {
-		final int revision = adapter.getRevision();
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					displayFeeds(revision, feedManager.getFeeds());
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					onLoadError();
-				}
+		int revision = adapter.getRevision();
+		runOnDbThread(() -> {
+			try {
+				displayFeeds(revision, feedManager.getFeeds());
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				onLoadError();
 			}
 		});
 	}
 
-	private void displayFeeds(final int revision, final List<Feed> feeds) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (revision == adapter.getRevision()) {
-					adapter.incrementRevision();
-					if (feeds.isEmpty()) list.showData();
-					else adapter.addAll(feeds);
-				} else {
-					LOG.info("Concurrent update, reloading");
-					loadFeeds();
-				}
+	private void displayFeeds(int revision, List<Feed> feeds) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (revision == adapter.getRevision()) {
+				adapter.incrementRevision();
+				if (feeds.isEmpty()) list.showData();
+				else adapter.addAll(feeds);
+			} else {
+				LOG.info("Concurrent update, reloading");
+				loadFeeds();
 			}
 		});
 	}
 
-	private void deleteFeed(final Feed feed) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					feedManager.removeFeed(feed);
-					onFeedDeleted(feed);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					onDeleteError();
-				}
+	private void deleteFeed(Feed feed) {
+		runOnDbThread(() -> {
+			try {
+				feedManager.removeFeed(feed);
+				onFeedDeleted(feed);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				onDeleteError();
 			}
 		});
 	}
 
 	private void onLoadError() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				list.setEmptyText(R.string.blogs_rss_feeds_manage_error);
-				list.showData();
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			list.setEmptyText(R.string.blogs_rss_feeds_manage_error);
+			list.showData();
 		});
 	}
 
-	private void onFeedDeleted(final Feed feed) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				adapter.incrementRevision();
-				adapter.remove(feed);
-			}
+	private void onFeedDeleted(Feed feed) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			adapter.incrementRevision();
+			adapter.remove(feed);
 		});
 	}
 
 	private void onDeleteError() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				Snackbar.make(list,
-						R.string.blogs_rss_feeds_manage_delete_error,
-						LENGTH_LONG).show();
-			}
-		});
+		runOnUiThreadUnlessDestroyed(() -> Snackbar.make(list,
+				R.string.blogs_rss_feeds_manage_delete_error,
+				LENGTH_LONG).show());
 	}
 }
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/WriteBlogPostActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/WriteBlogPostActivity.java
index 1217d94b714ea89966bee32edc11413937157b27..45ed94f948a6d623e8634189eeb65f521ac86cb4 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/WriteBlogPostActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/WriteBlogPostActivity.java
@@ -140,45 +140,36 @@ public class WriteBlogPostActivity extends BriarActivity
 		storePost(body);
 	}
 
-	private void storePost(final String body) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				long now = System.currentTimeMillis();
-				try {
-					LocalAuthor author = identityManager.getLocalAuthor();
-					BlogPost p = blogPostFactory
-							.createBlogPost(groupId, now, null, author, body);
-					blogManager.addLocalPost(p);
-					postPublished();
-				} catch (DbException | GeneralSecurityException | FormatException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					postFailedToPublish();
-				}
+	private void storePost(String body) {
+		runOnDbThread(() -> {
+			long now = System.currentTimeMillis();
+			try {
+				LocalAuthor author = identityManager.getLocalAuthor();
+				BlogPost p = blogPostFactory
+						.createBlogPost(groupId, now, null, author, body);
+				blogManager.addLocalPost(p);
+				postPublished();
+			} catch (DbException | GeneralSecurityException
+					| FormatException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				postFailedToPublish();
 			}
 		});
 	}
 
 	private void postPublished() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				setResult(RESULT_OK);
-				supportFinishAfterTransition();
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			setResult(RESULT_OK);
+			supportFinishAfterTransition();
 		});
 	}
 
 	private void postFailedToPublish() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				// hide progress bar, show publish button
-				progressBar.setVisibility(GONE);
-				input.setVisibility(VISIBLE);
-				// TODO show error
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			// hide progress bar, show publish button
+			progressBar.setVisibility(GONE);
+			input.setVisibility(VISIBLE);
+			// TODO show error
 		});
 	}
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/BaseContactListAdapter.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/BaseContactListAdapter.java
index fb89f85d1be08462ab29a24f38f986bec37f601f..1f577c366936ed72507ff598c44bcc0f3dccfd37 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contact/BaseContactListAdapter.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/BaseContactListAdapter.java
@@ -23,7 +23,7 @@ public abstract class BaseContactListAdapter<I extends ContactItem, VH extends C
 	}
 
 	@Override
-	public void onBindViewHolder(final VH ui, int position) {
+	public void onBindViewHolder(VH ui, int position) {
 		I item = items.get(position);
 		ui.bind(item, listener);
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItemViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItemViewHolder.java
index 839c0563b79a5eeaaa48150935d6c2de0bc8272b..a21e9ae1b3a1ee89727f45b06712bd594ada9b73 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItemViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItemViewHolder.java
@@ -37,8 +37,7 @@ public class ContactItemViewHolder<I extends ContactItem>
 		bulb = (ImageView) v.findViewById(R.id.bulbView);
 	}
 
-	protected void bind(final I item,
-			@Nullable final OnContactClickListener<I> listener) {
+	protected void bind(I item, @Nullable OnContactClickListener<I> listener) {
 		Author author = item.getContact().getAuthor();
 		avatar.setImageDrawable(
 				new IdenticonDrawable(author.getId().getBytes()));
@@ -54,11 +53,8 @@ public class ContactItemViewHolder<I extends ContactItem>
 			}
 		}
 
-		layout.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				if (listener != null) listener.onItemClick(avatar, item);
-			}
+		layout.setOnClickListener(v -> {
+			if (listener != null) listener.onItemClick(avatar, item);
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java
index 0faca234140bf3fdd8de0d2c3e036b0c3d2abefd..47826355fba0674ace514f842335b6de636e19a5 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java
@@ -114,36 +114,32 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 		View contentView = inflater.inflate(R.layout.list, container, false);
 
 		OnContactClickListener<ContactListItem> onContactClickListener =
-				new OnContactClickListener<ContactListItem>() {
-					@Override
-					public void onItemClick(View view, ContactListItem item) {
-						Intent i = new Intent(getActivity(),
-								ConversationActivity.class);
-						ContactId contactId = item.getContact().getId();
-						i.putExtra(CONTACT_ID, contactId.getInt());
+				(view, item) -> {
+					Intent i = new Intent(getActivity(),
+							ConversationActivity.class);
+					ContactId contactId = item.getContact().getId();
+					i.putExtra(CONTACT_ID, contactId.getInt());
 
-						if (Build.VERSION.SDK_INT >= 23) {
-							ContactListItemViewHolder holder =
-									(ContactListItemViewHolder) list
-											.getRecyclerView()
-											.findViewHolderForAdapterPosition(
-													adapter.findItemPosition(
-															item));
-							Pair<View, String> avatar =
-									Pair.create((View) holder.avatar,
-											getTransitionName(holder.avatar));
-							Pair<View, String> bulb =
-									Pair.create((View) holder.bulb,
-											getTransitionName(holder.bulb));
-							ActivityOptionsCompat options =
-									makeSceneTransitionAnimation(getActivity(),
-											avatar, bulb);
-							ActivityCompat.startActivity(getActivity(), i,
-									options.toBundle());
-						} else {
-							// work-around for android bug #224270
-							startActivity(i);
-						}
+					if (Build.VERSION.SDK_INT >= 23) {
+						ContactListItemViewHolder holder =
+								(ContactListItemViewHolder) list
+										.getRecyclerView()
+										.findViewHolderForAdapterPosition(
+												adapter.findItemPosition(item));
+						Pair<View, String> avatar =
+								Pair.create(holder.avatar,
+										getTransitionName(holder.avatar));
+						Pair<View, String> bulb =
+								Pair.create(holder.bulb,
+										getTransitionName(holder.bulb));
+						ActivityOptionsCompat options =
+								makeSceneTransitionAnimation(getActivity(),
+										avatar, bulb);
+						ActivityCompat.startActivity(getActivity(), i,
+								options.toBundle());
+					} else {
+						// work-around for android bug #224270
+						startActivity(i);
 					}
 				};
 		adapter = new ContactListAdapter(getContext(), onContactClickListener);
@@ -162,7 +158,7 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 	}
 
 	@Override
-	public boolean onOptionsItemSelected(final MenuItem item) {
+	public boolean onOptionsItemSelected(MenuItem item) {
 		// Handle presses on the action bar items
 		switch (item.getItemId()) {
 			case R.id.action_add_contact:
@@ -195,51 +191,42 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 	}
 
 	private void loadContacts() {
-		final int revision = adapter.getRevision();
-		listener.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					List<ContactListItem> contacts = new ArrayList<>();
-					for (Contact c : contactManager.getActiveContacts()) {
-						try {
-							ContactId id = c.getId();
-							GroupCount count =
-									conversationManager.getGroupCount(id);
-							boolean connected =
-									connectionRegistry.isConnected(c.getId());
-							contacts.add(new ContactListItem(c, connected,
-									count));
-						} catch (NoSuchContactException e) {
-							// Continue
-						}
+		int revision = adapter.getRevision();
+		listener.runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				List<ContactListItem> contacts = new ArrayList<>();
+				for (Contact c : contactManager.getActiveContacts()) {
+					try {
+						ContactId id = c.getId();
+						GroupCount count =
+								conversationManager.getGroupCount(id);
+						boolean connected =
+								connectionRegistry.isConnected(c.getId());
+						contacts.add(new ContactListItem(c, connected, count));
+					} catch (NoSuchContactException e) {
+						// Continue
 					}
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Full load took " + duration + " ms");
-					displayContacts(revision, contacts);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
 				}
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Full load took " + duration + " ms");
+				displayContacts(revision, contacts);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
-	private void displayContacts(final int revision,
-			final List<ContactListItem> contacts) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (revision == adapter.getRevision()) {
-					adapter.incrementRevision();
-					if (contacts.isEmpty()) list.showData();
-					else adapter.addAll(contacts);
-				} else {
-					LOG.info("Concurrent update, reloading");
-					loadContacts();
-				}
+	private void displayContacts(int revision, List<ContactListItem> contacts) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (revision == adapter.getRevision()) {
+				adapter.incrementRevision();
+				if (contacts.isEmpty()) list.showData();
+				else adapter.addAll(contacts);
+			} else {
+				LOG.info("Concurrent update, reloading");
+				loadContacts();
 			}
 		});
 	}
@@ -294,45 +281,36 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 		}
 	}
 
-	private void updateItem(final ContactId c, final BaseMessageHeader h) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				adapter.incrementRevision();
-				int position = adapter.findItemPosition(c);
-				ContactListItem item = adapter.getItemAt(position);
-				if (item != null) {
-					ConversationItem i = ConversationItem.from(getContext(), h);
-					item.addMessage(i);
-					adapter.updateItemAt(position, item);
-				}
+	private void updateItem(ContactId c, BaseMessageHeader h) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			adapter.incrementRevision();
+			int position = adapter.findItemPosition(c);
+			ContactListItem item = adapter.getItemAt(position);
+			if (item != null) {
+				ConversationItem i = ConversationItem.from(getContext(), h);
+				item.addMessage(i);
+				adapter.updateItemAt(position, item);
 			}
 		});
 	}
 
-	private void removeItem(final ContactId c) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				adapter.incrementRevision();
-				int position = adapter.findItemPosition(c);
-				ContactListItem item = adapter.getItemAt(position);
-				if (item != null) adapter.remove(item);
-			}
+	private void removeItem(ContactId c) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			adapter.incrementRevision();
+			int position = adapter.findItemPosition(c);
+			ContactListItem item = adapter.getItemAt(position);
+			if (item != null) adapter.remove(item);
 		});
 	}
 
-	private void setConnected(final ContactId c, final boolean connected) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				adapter.incrementRevision();
-				int position = adapter.findItemPosition(c);
-				ContactListItem item = adapter.getItemAt(position);
-				if (item != null) {
-					item.setConnected(connected);
-					adapter.notifyItemChanged(position);
-				}
+	private void setConnected(ContactId c, boolean connected) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			adapter.incrementRevision();
+			int position = adapter.findItemPosition(c);
+			ContactListItem item = adapter.getItemAt(position);
+			if (item != null) {
+				item.setConnected(connected);
+				adapter.notifyItemChanged(position);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationActivity.java
index 1bebf0c53716169c48550e76c7bcece66c877ba9..d0ae82427af1938bb94d7528c7798dd3860937c6 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationActivity.java
@@ -268,7 +268,7 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	@Override
-	public boolean onOptionsItemSelected(final MenuItem item) {
+	public boolean onOptionsItemSelected(MenuItem item) {
 		// Handle presses on the action bar items
 		switch (item.getItemId()) {
 			case android.R.id.home:
@@ -289,126 +289,104 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void loadContactDetailsAndMessages() {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					if (contactName == null || contactAuthorId == null) {
-						Contact contact = contactManager.getContact(contactId);
-						contactName = contact.getAuthor().getName();
-						contactAuthorId = contact.getAuthor().getId();
-					}
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading contact took " + duration + " ms");
-					loadMessages();
-					displayContactDetails();
-				} catch (NoSuchContactException e) {
-					finishOnUiThread();
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				if (contactName == null || contactAuthorId == null) {
+					Contact contact = contactManager.getContact(contactId);
+					contactName = contact.getAuthor().getName();
+					contactAuthorId = contact.getAuthor().getId();
 				}
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading contact took " + duration + " ms");
+				loadMessages();
+				displayContactDetails();
+			} catch (NoSuchContactException e) {
+				finishOnUiThread();
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	private void displayContactDetails() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				//noinspection ConstantConditions
-				toolbarAvatar.setImageDrawable(
-						new IdenticonDrawable(contactAuthorId.getBytes()));
-				toolbarTitle.setText(contactName);
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			//noinspection ConstantConditions
+			toolbarAvatar.setImageDrawable(
+					new IdenticonDrawable(contactAuthorId.getBytes()));
+			toolbarTitle.setText(contactName);
 		});
 	}
 
 	private void displayContactOnlineStatus() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (connectionRegistry.isConnected(contactId)) {
-					toolbarStatus.setImageDrawable(ContextCompat
-							.getDrawable(ConversationActivity.this,
-									R.drawable.contact_online));
-					toolbarStatus
-							.setContentDescription(getString(R.string.online));
-				} else {
-					toolbarStatus.setImageDrawable(ContextCompat
-							.getDrawable(ConversationActivity.this,
-									R.drawable.contact_offline));
-					toolbarStatus
-							.setContentDescription(getString(R.string.offline));
-				}
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (connectionRegistry.isConnected(contactId)) {
+				toolbarStatus.setImageDrawable(ContextCompat
+						.getDrawable(ConversationActivity.this,
+								R.drawable.contact_online));
+				toolbarStatus
+						.setContentDescription(getString(R.string.online));
+			} else {
+				toolbarStatus.setImageDrawable(ContextCompat
+						.getDrawable(ConversationActivity.this,
+								R.drawable.contact_offline));
+				toolbarStatus
+						.setContentDescription(getString(R.string.offline));
 			}
 		});
 	}
 
 	private void loadMessages() {
-		final int revision = adapter.getRevision();
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					Collection<PrivateMessageHeader> headers =
-							messagingManager.getMessageHeaders(contactId);
-					Collection<IntroductionMessage> introductions =
-							introductionManager
-									.getIntroductionMessages(contactId);
-					Collection<InvitationMessage> forumInvitations =
-							forumSharingManager
-									.getInvitationMessages(contactId);
-					Collection<InvitationMessage> blogInvitations =
-							blogSharingManager
-									.getInvitationMessages(contactId);
-					Collection<InvitationMessage> groupInvitations =
-							groupInvitationManager
-									.getInvitationMessages(contactId);
-					List<InvitationMessage> invitations = new ArrayList<>(
-							forumInvitations.size() + blogInvitations.size() +
-									groupInvitations.size());
-					invitations.addAll(forumInvitations);
-					invitations.addAll(blogInvitations);
-					invitations.addAll(groupInvitations);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading messages took " + duration + " ms");
-					displayMessages(revision, headers, introductions,
-							invitations);
-				} catch (NoSuchContactException e) {
-					finishOnUiThread();
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		int revision = adapter.getRevision();
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				Collection<PrivateMessageHeader> headers =
+						messagingManager.getMessageHeaders(contactId);
+				Collection<IntroductionMessage> introductions =
+						introductionManager.getIntroductionMessages(contactId);
+				Collection<InvitationMessage> forumInvitations =
+						forumSharingManager.getInvitationMessages(contactId);
+				Collection<InvitationMessage> blogInvitations =
+						blogSharingManager.getInvitationMessages(contactId);
+				Collection<InvitationMessage> groupInvitations =
+						groupInvitationManager.getInvitationMessages(contactId);
+				List<InvitationMessage> invitations = new ArrayList<>(
+						forumInvitations.size() + blogInvitations.size() +
+								groupInvitations.size());
+				invitations.addAll(forumInvitations);
+				invitations.addAll(blogInvitations);
+				invitations.addAll(groupInvitations);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading messages took " + duration + " ms");
+				displayMessages(revision, headers, introductions, invitations);
+			} catch (NoSuchContactException e) {
+				finishOnUiThread();
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
-	private void displayMessages(final int revision,
-			final Collection<PrivateMessageHeader> headers,
-			final Collection<IntroductionMessage> introductions,
-			final Collection<InvitationMessage> invitations) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (revision == adapter.getRevision()) {
-					adapter.incrementRevision();
-					textInputView.setSendButtonEnabled(true);
-					List<ConversationItem> items = createItems(headers,
-							introductions, invitations);
-					if (items.isEmpty()) list.showData();
-					else adapter.addAll(items);
-					// Scroll to the bottom
-					list.scrollToPosition(adapter.getItemCount() - 1);
-				} else {
-					LOG.info("Concurrent update, reloading");
-					loadMessages();
-				}
+	private void displayMessages(int revision,
+			Collection<PrivateMessageHeader> headers,
+			Collection<IntroductionMessage> introductions,
+			Collection<InvitationMessage> invitations) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (revision == adapter.getRevision()) {
+				adapter.incrementRevision();
+				textInputView.setSendButtonEnabled(true);
+				List<ConversationItem> items = createItems(headers,
+						introductions, invitations);
+				if (items.isEmpty()) list.showData();
+				else adapter.addAll(items);
+				// Scroll to the bottom
+				list.scrollToPosition(adapter.getItemCount() - 1);
+			} else {
+				LOG.info("Concurrent update, reloading");
+				loadMessages();
 			}
 		});
 	}
@@ -458,40 +436,33 @@ public class ConversationActivity extends BriarActivity
 		return items;
 	}
 
-	private void loadMessageBody(final MessageId m) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					String body = messagingManager.getMessageBody(m);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading body took " + duration + " ms");
-					displayMessageBody(m, body);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+	private void loadMessageBody(MessageId m) {
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				String body = messagingManager.getMessageBody(m);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading body took " + duration + " ms");
+				displayMessageBody(m, body);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
-	private void displayMessageBody(final MessageId m, final String body) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				bodyCache.put(m, body);
-				SparseArray<ConversationItem> messages =
-						adapter.getPrivateMessages();
-				for (int i = 0; i < messages.size(); i++) {
-					ConversationItem item = messages.valueAt(i);
-					if (item.getId().equals(m)) {
-						item.setBody(body);
-						adapter.notifyItemChanged(messages.keyAt(i));
-						list.scrollToPosition(adapter.getItemCount() - 1);
-						return;
-					}
+	private void displayMessageBody(MessageId m, String body) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			bodyCache.put(m, body);
+			SparseArray<ConversationItem> messages =
+					adapter.getPrivateMessages();
+			for (int i = 0; i < messages.size(); i++) {
+				ConversationItem item = messages.valueAt(i);
+				if (item.getId().equals(m)) {
+					item.setBody(body);
+					adapter.notifyItemChanged(messages.keyAt(i));
+					list.scrollToPosition(adapter.getItemCount() - 1);
+					return;
 				}
 			}
 		});
@@ -572,138 +543,100 @@ public class ConversationActivity extends BriarActivity
 		}
 	}
 
-	private void addConversationItem(final ConversationItem item) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				adapter.incrementRevision();
-				adapter.add(item);
-				// Scroll to the bottom
-				list.scrollToPosition(adapter.getItemCount() - 1);
-			}
+	private void addConversationItem(ConversationItem item) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			adapter.incrementRevision();
+			adapter.add(item);
+			// Scroll to the bottom
+			list.scrollToPosition(adapter.getItemCount() - 1);
 		});
 	}
 
-	private void handleIntroductionRequest(final IntroductionRequest m) {
+	private void handleIntroductionRequest(IntroductionRequest m) {
 		getContactNameTask().addListener(new FutureTaskListener<String>() {
 			@Override
-			public void onSuccess(final String contactName) {
-				runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						ConversationItem item = ConversationItem
-								.from(ConversationActivity.this, contactName,
-										m);
-						addConversationItem(item);
-					}
+			public void onSuccess(String contactName) {
+				runOnUiThreadUnlessDestroyed(() -> {
+					ConversationItem item = ConversationItem
+							.from(ConversationActivity.this, contactName, m);
+					addConversationItem(item);
 				});
 			}
 			@Override
-			public void onFailure(final Throwable exception) {
-				runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						handleDbException((DbException) exception);
-					}
-				});
+			public void onFailure(Throwable exception) {
+				runOnUiThreadUnlessDestroyed(
+						() -> handleDbException((DbException) exception));
 			}
 		});
 	}
 
-	private void handleIntroductionResponse(final IntroductionResponse m) {
+	private void handleIntroductionResponse(IntroductionResponse m) {
 		getContactNameTask().addListener(new FutureTaskListener<String>() {
 			@Override
-			public void onSuccess(final String contactName) {
-				runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						ConversationItem item = ConversationItem
-								.from(ConversationActivity.this, contactName,
-										m);
-						addConversationItem(item);
-					}
+			public void onSuccess(String contactName) {
+				runOnUiThreadUnlessDestroyed(() -> {
+					ConversationItem item = ConversationItem
+							.from(ConversationActivity.this, contactName, m);
+					addConversationItem(item);
 				});
 			}
 			@Override
-			public void onFailure(final Throwable exception) {
-				runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						handleDbException((DbException) exception);
-					}
-				});
+			public void onFailure(Throwable exception) {
+				runOnUiThreadUnlessDestroyed(
+						() -> handleDbException((DbException) exception));
 			}
 		});
 	}
 
-	private void handleInvitationRequest(final InvitationRequest m) {
+	private void handleInvitationRequest(InvitationRequest m) {
 		getContactNameTask().addListener(new FutureTaskListener<String>() {
 			@Override
-			public void onSuccess(final String contactName) {
-				runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						ConversationItem item = ConversationItem
-								.from(ConversationActivity.this, contactName,
-										m);
-						addConversationItem(item);
-					}
+			public void onSuccess(String contactName) {
+				runOnUiThreadUnlessDestroyed(() -> {
+					ConversationItem item = ConversationItem
+							.from(ConversationActivity.this, contactName, m);
+					addConversationItem(item);
 				});
 			}
 			@Override
-			public void onFailure(final Throwable exception) {
-				runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						handleDbException((DbException) exception);
-					}
-				});
+			public void onFailure(Throwable exception) {
+				runOnUiThreadUnlessDestroyed(
+						() -> handleDbException((DbException) exception));
 			}
 		});
 	}
 
-	private void handleInvitationResponse(final InvitationResponse m) {
+	private void handleInvitationResponse(InvitationResponse m) {
 		getContactNameTask().addListener(new FutureTaskListener<String>() {
 			@Override
-			public void onSuccess(final String contactName) {
-				runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						ConversationItem item = ConversationItem
-								.from(ConversationActivity.this, contactName,
-										m);
-						addConversationItem(item);
-					}
+			public void onSuccess(String contactName) {
+				runOnUiThreadUnlessDestroyed(() -> {
+					ConversationItem item = ConversationItem
+							.from(ConversationActivity.this, contactName, m);
+					addConversationItem(item);
 				});
 			}
 			@Override
-			public void onFailure(final Throwable exception) {
-				runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						handleDbException((DbException) exception);
-					}
-				});
+			public void onFailure(Throwable exception) {
+				runOnUiThreadUnlessDestroyed(
+						() -> handleDbException((DbException) exception));
 			}
 		});
 	}
 
-	private void markMessages(final Collection<MessageId> messageIds,
-			final boolean sent, final boolean seen) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				adapter.incrementRevision();
-				Set<MessageId> messages = new HashSet<>(messageIds);
-				SparseArray<ConversationOutItem> list =
-						adapter.getOutgoingMessages();
-				for (int i = 0; i < list.size(); i++) {
-					ConversationOutItem item = list.valueAt(i);
-					if (messages.contains(item.getId())) {
-						item.setSent(sent);
-						item.setSeen(seen);
-						adapter.notifyItemChanged(list.keyAt(i));
-					}
+	private void markMessages(Collection<MessageId> messageIds,
+			boolean sent, boolean seen) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			adapter.incrementRevision();
+			Set<MessageId> messages = new HashSet<>(messageIds);
+			SparseArray<ConversationOutItem> list =
+					adapter.getOutgoingMessages();
+			for (int i = 0; i < list.size(); i++) {
+				ConversationOutItem item = list.valueAt(i);
+				if (messages.contains(item.getId())) {
+					item.setSent(sent);
+					item.setSeen(seen);
+					adapter.notifyItemChanged(list.keyAt(i));
 				}
 			}
 		});
@@ -726,72 +659,55 @@ public class ConversationActivity extends BriarActivity
 		return item == null ? 0 : item.getTime() + 1;
 	}
 
-	private void loadGroupId(final String body, final long timestamp) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					messagingGroupId =
-							messagingManager.getConversationId(contactId);
-					createMessage(body, timestamp);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
-
+	private void loadGroupId(String body, long timestamp) {
+		runOnDbThread(() -> {
+			try {
+				messagingGroupId =
+						messagingManager.getConversationId(contactId);
+				createMessage(body, timestamp);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
+
 		});
 	}
 
-	private void createMessage(final String body, final long timestamp) {
-		cryptoExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					//noinspection ConstantConditions init in loadGroupId()
-					storeMessage(privateMessageFactory.createPrivateMessage(
-							messagingGroupId, timestamp, body), body);
-				} catch (FormatException e) {
-					throw new RuntimeException(e);
-				}
+	private void createMessage(String body, long timestamp) {
+		cryptoExecutor.execute(() -> {
+			try {
+				//noinspection ConstantConditions init in loadGroupId()
+				storeMessage(privateMessageFactory.createPrivateMessage(
+						messagingGroupId, timestamp, body), body);
+			} catch (FormatException e) {throw new RuntimeException(e);
 			}
 		});
 	}
 
-	private void storeMessage(final PrivateMessage m, final String body) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					messagingManager.addLocalMessage(m);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Storing message took " + duration + " ms");
-					Message message = m.getMessage();
-					PrivateMessageHeader h = new PrivateMessageHeader(
-							message.getId(), message.getGroupId(),
-							message.getTimestamp(), true, false, false, false);
-					ConversationItem item = ConversationItem.from(h);
-					item.setBody(body);
-					bodyCache.put(message.getId(), body);
-					addConversationItem(item);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+	private void storeMessage(PrivateMessage m, String body) {
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				messagingManager.addLocalMessage(m);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Storing message took " + duration + " ms");
+				Message message = m.getMessage();
+				PrivateMessageHeader h = new PrivateMessageHeader(
+						message.getId(), message.getGroupId(),
+						message.getTimestamp(), true, false, false, false);
+				ConversationItem item = ConversationItem.from(h);
+				item.setBody(body);
+				bodyCache.put(message.getId(), body);
+				addConversationItem(item);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	private void askToRemoveContact() {
 		DialogInterface.OnClickListener okListener =
-				new DialogInterface.OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialog, int which) {
-						removeContact();
-					}
-				};
+				(dialog, which) -> removeContact();
 		AlertDialog.Builder builder =
 				new AlertDialog.Builder(ConversationActivity.this,
 						R.style.BriarDialogTheme);
@@ -803,118 +719,95 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void removeContact() {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					contactManager.removeContact(contactId);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				} finally {
-					finishAfterContactRemoved();
-				}
+		runOnDbThread(() -> {
+			try {
+				contactManager.removeContact(contactId);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+			} finally {
+				finishAfterContactRemoved();
 			}
 		});
 	}
 
 	private void finishAfterContactRemoved() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				String deleted = getString(R.string.contact_deleted_toast);
-				Toast.makeText(ConversationActivity.this, deleted, LENGTH_SHORT)
-						.show();
-				supportFinishAfterTransition();
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			String deleted = getString(R.string.contact_deleted_toast);
+			Toast.makeText(ConversationActivity.this, deleted, LENGTH_SHORT)
+					.show();
+			supportFinishAfterTransition();
 		});
 	}
 
-	private void enableIntroductionActionIfAvailable(final MenuItem item) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					if (contactManager.getActiveContacts().size() > 1) {
-						enableIntroductionAction(item);
-						Settings settings =
-								settingsManager.getSettings(SETTINGS_NAMESPACE);
-						if (settings.getBoolean(SHOW_ONBOARDING_INTRODUCTION,
-								true)) {
-							showIntroductionOnboarding();
-						}
+	private void enableIntroductionActionIfAvailable(MenuItem item) {
+		runOnDbThread(() -> {
+			try {
+				if (contactManager.getActiveContacts().size() > 1) {
+					enableIntroductionAction(item);
+					Settings settings =
+							settingsManager.getSettings(SETTINGS_NAMESPACE);
+					if (settings.getBoolean(SHOW_ONBOARDING_INTRODUCTION,
+							true)) {
+						showIntroductionOnboarding();
 					}
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
 				}
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
-	private void enableIntroductionAction(final MenuItem item) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				item.setEnabled(true);
-			}
-		});
+	private void enableIntroductionAction(MenuItem item) {
+		runOnUiThreadUnlessDestroyed(() -> item.setEnabled(true));
 	}
 
 	private void showIntroductionOnboarding() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				// find view of overflow icon
-				View target = null;
-				for (int i = 0; i < toolbar.getChildCount(); i++) {
-					if (toolbar.getChildAt(i) instanceof ActionMenuView) {
-						ActionMenuView menu =
-								(ActionMenuView) toolbar.getChildAt(i);
-						target = menu.getChildAt(menu.getChildCount() - 1);
-						break;
-					}
-				}
-				if (target == null) {
-					LOG.warning("No Overflow Icon found!");
-					return;
+		runOnUiThreadUnlessDestroyed(() -> {
+			// find view of overflow icon
+			View target = null;
+			for (int i = 0; i < toolbar.getChildCount(); i++) {
+				if (toolbar.getChildAt(i) instanceof ActionMenuView) {
+					ActionMenuView menu =
+							(ActionMenuView) toolbar.getChildAt(i);
+					target = menu.getChildAt(menu.getChildCount() - 1);
+					break;
 				}
+			}
+			if (target == null) {
+				LOG.warning("No Overflow Icon found!");
+				return;
+			}
 
-				OnHidePromptListener listener = new OnHidePromptListener() {
-					@Override
-					public void onHidePrompt(MotionEvent motionEvent,
-							boolean focalClicked) {
-						introductionOnboardingSeen();
-					}
+			OnHidePromptListener listener = new OnHidePromptListener() {
+				@Override
+				public void onHidePrompt(MotionEvent motionEvent,
+						boolean focalClicked) {
+					introductionOnboardingSeen();
+				}
 
-					@Override
-					public void onHidePromptComplete() {
-					}
-				};
-				new MaterialTapTargetPrompt.Builder(ConversationActivity.this)
-						.setTarget(target)
-						.setPrimaryText(R.string.introduction_onboarding_title)
-						.setSecondaryText(R.string.introduction_onboarding_text)
-						.setBackgroundColourFromRes(R.color.briar_primary)
-						.setIcon(R.drawable.ic_more_vert_accent)
-						.setOnHidePromptListener(listener)
-						.show();
-			}
+				@Override
+				public void onHidePromptComplete() {
+				}
+			};
+			new MaterialTapTargetPrompt.Builder(ConversationActivity.this)
+					.setTarget(target)
+					.setPrimaryText(R.string.introduction_onboarding_title)
+					.setSecondaryText(R.string.introduction_onboarding_text)
+					.setBackgroundColourFromRes(R.color.briar_primary)
+					.setIcon(R.drawable.ic_more_vert_accent)
+					.setOnHidePromptListener(listener)
+					.show();
 		});
 	}
 
 	private void introductionOnboardingSeen() {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Settings settings = new Settings();
-					settings.putBoolean(SHOW_ONBOARDING_INTRODUCTION, false);
-					settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		runOnDbThread(() -> {
+			try {
+				Settings settings = new Settings();
+				settings.putBoolean(SHOW_ONBOARDING_INTRODUCTION, false);
+				settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
@@ -924,63 +817,55 @@ public class ConversationActivity extends BriarActivity
 		if (!item.isRead()) markMessageRead(item.getGroupId(), item.getId());
 	}
 
-	private void markMessageRead(final GroupId g, final MessageId m) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					messagingManager.setReadFlag(g, m, true);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Marking read took " + duration + " ms");
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+	private void markMessageRead(GroupId g, MessageId m) {
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				messagingManager.setReadFlag(g, m, true);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Marking read took " + duration + " ms");
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	@UiThread
 	@Override
-	public void respondToRequest(final ConversationRequestItem item,
-			final boolean accept) {
+	public void respondToRequest(ConversationRequestItem item, boolean accept) {
 		item.setAnswered(true);
 		int position = adapter.findItemPosition(item);
 		if (position != INVALID_POSITION) {
 			adapter.notifyItemChanged(position, item);
 		}
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				long timestamp = System.currentTimeMillis();
-				timestamp = Math.max(timestamp, getMinTimestampForNewMessage());
-				try {
-					switch (item.getRequestType()) {
-						case INTRODUCTION:
-							respondToIntroductionRequest(item.getSessionId(),
-									accept, timestamp);
-							break;
-						case FORUM:
-							respondToForumRequest(item.getSessionId(), accept);
-							break;
-						case BLOG:
-							respondToBlogRequest(item.getSessionId(), accept);
-							break;
-						case GROUP:
-							respondToGroupRequest(item.getSessionId(), accept);
-							break;
-						default:
-							throw new IllegalArgumentException(
-									"Unknown Request Type");
-					}
-					loadMessages();
-				} catch (DbException | FormatException e) {
-					introductionResponseError();
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
+		runOnDbThread(() -> {
+			long timestamp = System.currentTimeMillis();
+			timestamp = Math.max(timestamp, getMinTimestampForNewMessage());
+			try {
+				switch (item.getRequestType()) {
+					case INTRODUCTION:
+						respondToIntroductionRequest(item.getSessionId(),
+								accept, timestamp);
+						break;
+					case FORUM:
+						respondToForumRequest(item.getSessionId(), accept);
+						break;
+					case BLOG:
+						respondToBlogRequest(item.getSessionId(), accept);
+						break;
+					case GROUP:
+						respondToGroupRequest(item.getSessionId(), accept);
+						break;
+					default:
+						throw new IllegalArgumentException(
+								"Unknown Request Type");
 				}
+				loadMessages();
+			} catch (DbException | FormatException e) {
+				introductionResponseError();
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
@@ -1041,14 +926,10 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void introductionResponseError() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
+		runOnUiThreadUnlessDestroyed(() ->
 				Toast.makeText(ConversationActivity.this,
 						R.string.introduction_response_error,
-						Toast.LENGTH_SHORT).show();
-			}
-		});
+						Toast.LENGTH_SHORT).show());
 	}
 
 	private ListenableFutureTask<String> getContactNameTask() {
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationRequestViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationRequestViewHolder.java
index 492324a847f08beb09d3b50e066f8b5097706ebe..f5718c1dc9c97cc80daf55613d512ac5997278d0 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationRequestViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationRequestViewHolder.java
@@ -2,7 +2,6 @@ package org.briarproject.briar.android.contact;
 
 import android.support.annotation.UiThread;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.widget.Button;
 
 import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@@ -26,21 +25,17 @@ class ConversationRequestViewHolder extends ConversationNoticeInViewHolder {
 	}
 
 	void bind(ConversationItem conversationItem,
-			final ConversationListener listener) {
+			ConversationListener listener) {
 		super.bind(conversationItem);
 
-		final ConversationRequestItem item =
+		ConversationRequestItem item =
 				(ConversationRequestItem) conversationItem;
 
 		if (item.wasAnswered() && item.canBeOpened()) {
 			acceptButton.setVisibility(VISIBLE);
 			acceptButton.setText(R.string.open);
-			acceptButton.setOnClickListener(new OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					listener.openRequestedShareable(item);
-				}
-			});
+			acceptButton.setOnClickListener(
+					v -> listener.openRequestedShareable(item));
 			declineButton.setVisibility(GONE);
 		} else if (item.wasAnswered()) {
 			acceptButton.setVisibility(GONE);
@@ -48,22 +43,16 @@ class ConversationRequestViewHolder extends ConversationNoticeInViewHolder {
 		} else {
 			acceptButton.setVisibility(VISIBLE);
 			acceptButton.setText(R.string.accept);
-			acceptButton.setOnClickListener(new OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					acceptButton.setEnabled(false);
-					declineButton.setEnabled(false);
-					listener.respondToRequest(item, true);
-				}
+			acceptButton.setOnClickListener(v -> {
+				acceptButton.setEnabled(false);
+				declineButton.setEnabled(false);
+				listener.respondToRequest(item, true);
 			});
 			declineButton.setVisibility(VISIBLE);
-			declineButton.setOnClickListener(new OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					acceptButton.setEnabled(false);
-					declineButton.setEnabled(false);
-					listener.respondToRequest(item, false);
-				}
+			declineButton.setOnClickListener(v -> {
+				acceptButton.setEnabled(false);
+				declineButton.setEnabled(false);
+				listener.respondToRequest(item, false);
 			});
 		}
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contactselection/BaseContactSelectorFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/contactselection/BaseContactSelectorFragment.java
index c7c10849d7de9ff3c12b7f0ccf65e0dbf891d8b9..7b3f681e90d1775ea7589907cbcabaec4fc7af2f 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contactselection/BaseContactSelectorFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contactselection/BaseContactSelectorFragment.java
@@ -117,7 +117,7 @@ public abstract class BaseContactSelectorFragment<I extends SelectableContactIte
 		onSelectionChanged();
 	}
 
-	private void loadContacts(final Collection<ContactId> selection) {
+	private void loadContacts(Collection<ContactId> selection) {
 		getController().loadContacts(groupId, selection,
 				new UiResultExceptionHandler<Collection<I>, DbException>(
 						this) {
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorActivity.java
index 4cf1a29a7757593809d87ca7b9bb7e496dac02da..a11f3a6fd0b1a431092c6f8f427867be898ff47f 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorActivity.java
@@ -25,7 +25,7 @@ public abstract class ContactSelectorActivity
 		extends BriarActivity
 		implements BaseFragmentListener, ContactSelectorListener {
 
-	final static String CONTACTS = "contacts";
+	protected final static String CONTACTS = "contacts";
 
 	// Subclasses may initialise the group ID in different places
 	protected GroupId groupId;
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorControllerImpl.java
index 3cd744d1545ffc967d46cb92db64760eba72c70a..983918a1ebefc318533ef4119537814ce37a09c7 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorControllerImpl.java
@@ -38,29 +38,23 @@ public abstract class ContactSelectorControllerImpl
 	}
 
 	@Override
-	public void loadContacts(final GroupId g,
-			final Collection<ContactId> selection,
-			final ResultExceptionHandler<Collection<SelectableContactItem>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Collection<SelectableContactItem> contacts =
-							new ArrayList<>();
-					for (Contact c : contactManager.getActiveContacts()) {
-						// was this contact already selected?
-						boolean selected = selection.contains(c.getId());
-						// can this contact be selected?
-						boolean disabled = isDisabled(g, c);
-						contacts.add(new SelectableContactItem(c, selected,
-								disabled));
-					}
-					handler.onResult(contacts);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
+	public void loadContacts(GroupId g, Collection<ContactId> selection,
+			ResultExceptionHandler<Collection<SelectableContactItem>, DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				Collection<SelectableContactItem> contacts = new ArrayList<>();
+				for (Contact c : contactManager.getActiveContacts()) {
+					// was this contact already selected?
+					boolean selected = selection.contains(c.getId());
+					// can this contact be selected?
+					boolean disabled = isDisabled(g, c);
+					contacts.add(new SelectableContactItem(c, selected,
+							disabled));
 				}
+				handler.onResult(contacts);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorFragment.java
index 07908ac8b87662f6bdacbe0c938387e213ddc407..ec6cd389b2542e83acad124b22623969fd292770 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorFragment.java
@@ -36,7 +36,7 @@ public abstract class ContactSelectorFragment extends
 	}
 
 	@Override
-	public boolean onOptionsItemSelected(final MenuItem item) {
+	public boolean onOptionsItemSelected(MenuItem item) {
 		switch (item.getItemId()) {
 			case R.id.action_contacts_selected:
 				selectedContacts = adapter.getSelectedContactIds();
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/BriarControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/BriarControllerImpl.java
index 3d15ff7a2f6bca39d9d81e9ae11ac1ed5485920e..ff010ecac05c76e51fe964a5856020cabf3bb928 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/controller/BriarControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/BriarControllerImpl.java
@@ -66,7 +66,7 @@ public class BriarControllerImpl implements BriarController {
 	}
 
 	@Override
-	public void signOut(final ResultHandler<Void> eventHandler) {
+	public void signOut(ResultHandler<Void> eventHandler) {
 		new Thread() {
 			@Override
 			public void run() {
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/DbControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/DbControllerImpl.java
index 6ae01b8a53ad11cac4857179ccf52f41c9b577b2..5899697ef0a49347f8651179b25fa6c7121035b2 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/controller/DbControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/DbControllerImpl.java
@@ -28,17 +28,14 @@ public class DbControllerImpl implements DbController {
 	}
 
 	@Override
-	public void runOnDbThread(final Runnable task) {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					lifecycleManager.waitForDatabase();
-					task.run();
-				} catch (InterruptedException e) {
-					LOG.warning("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
-				}
+	public void runOnDbThread(Runnable task) {
+		dbExecutor.execute(() -> {
+			try {
+				lifecycleManager.waitForDatabase();
+				task.run();
+			} catch (InterruptedException e) {
+				LOG.warning("Interrupted while waiting for database");
+				Thread.currentThread().interrupt();
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/SharingControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/SharingControllerImpl.java
index 5c83206e504ea690582d6390b2ba45524711acc9..643a073d5b02716452a2487239f6a60901d93677 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/controller/SharingControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/SharingControllerImpl.java
@@ -58,15 +58,12 @@ public class SharingControllerImpl implements SharingController, EventListener {
 		}
 	}
 
-	private void setConnected(final ContactId c) {
+	private void setConnected(ContactId c) {
 		if (listener == null) return;
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (contacts.contains(c)) {
-					int online = getOnlineCount();
-					listener.onSharingInfoUpdated(contacts.size(), online);
-				}
+		listener.runOnUiThreadUnlessDestroyed(() -> {
+			if (contacts.contains(c)) {
+				int online = getOnlineCount();
+				listener.onSharingInfoUpdated(contacts.size(), online);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiExceptionHandler.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiExceptionHandler.java
index 98ea082ee30eba673a791aa0ba39f0fafb540eb6..20859ad97988d74654c3c241cdda8709564fb346 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiExceptionHandler.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiExceptionHandler.java
@@ -19,13 +19,8 @@ public abstract class UiExceptionHandler<E extends Exception>
 	}
 
 	@Override
-	public void onException(final E exception) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				onExceptionUi(exception);
-			}
-		});
+	public void onException(E exception) {
+		listener.runOnUiThreadUnlessDestroyed(() -> onExceptionUi(exception));
 	}
 
 	@UiThread
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiResultExceptionHandler.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiResultExceptionHandler.java
index d3ee2d7c83453c65eade3d0240e20231c1279673..1c9b11b2c104c0b852f4f16249a36c1641f5b7a2 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiResultExceptionHandler.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiResultExceptionHandler.java
@@ -17,13 +17,8 @@ public abstract class UiResultExceptionHandler<R, E extends Exception>
 	}
 
 	@Override
-	public void onResult(final R result) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				onResultUi(result);
-			}
-		});
+	public void onResult(R result) {
+		listener.runOnUiThreadUnlessDestroyed(() -> onResultUi(result));
 	}
 
 	@UiThread
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiResultHandler.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiResultHandler.java
index 89bd919d4d6e85c831d681d3e5cdac692c83df7d..5e0081af61fc2f27e8387464b022e5e10756b7d2 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiResultHandler.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiResultHandler.java
@@ -13,13 +13,8 @@ public abstract class UiResultHandler<R> implements ResultHandler<R> {
 	}
 
 	@Override
-	public void onResult(final R result) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				onResultUi(result);
-			}
-		});
+	public void onResult(R result) {
+		listener.runOnUiThreadUnlessDestroyed(() -> onResultUi(result));
 	}
 
 	@UiThread
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/CreateForumActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/CreateForumActivity.java
index 44087e109ed407c45a0eb4c6d79a737e3a777caa..6a87b3b7120032d6287c796f5ce4c498d10903bd 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/forum/CreateForumActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/CreateForumActivity.java
@@ -5,14 +5,9 @@ import android.os.Bundle;
 import android.support.design.widget.TextInputLayout;
 import android.text.Editable;
 import android.text.TextWatcher;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ProgressBar;
-import android.widget.TextView;
-import android.widget.TextView.OnEditorActionListener;
 import android.widget.Toast;
 
 import org.briarproject.bramble.api.db.DbException;
@@ -79,22 +74,13 @@ public class CreateForumActivity extends BriarActivity {
 			public void afterTextChanged(Editable s) {
 			}
 		});
-		nameEntry.setOnEditorActionListener(new OnEditorActionListener() {
-			@Override
-			public boolean onEditorAction(TextView v, int actionId,
-					KeyEvent e) {
-				createForum();
-				return true;
-			}
+		nameEntry.setOnEditorActionListener((v, actionId, e) -> {
+			createForum();
+			return true;
 		});
 
 		createForumButton = (Button) findViewById(R.id.createForumButton);
-		createForumButton.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				createForum();
-			}
-		});
+		createForumButton.setOnClickListener(v -> createForum());
 
 		progress = (ProgressBar) findViewById(R.id.createForumProgressBar);
 	}
@@ -134,39 +120,32 @@ public class CreateForumActivity extends BriarActivity {
 		storeForum(nameEntry.getText().toString());
 	}
 
-	private void storeForum(final String name) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					Forum f = forumManager.addForum(name);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Storing forum took " + duration + " ms");
-					displayForum(f);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					finishOnUiThread();
-				}
+	private void storeForum(String name) {
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				Forum f = forumManager.addForum(name);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Storing forum took " + duration + " ms");
+				displayForum(f);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				finishOnUiThread();
 			}
 		});
 	}
 
-	private void displayForum(final Forum f) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				Intent i = new Intent(CreateForumActivity.this,
-						ForumActivity.class);
-				i.putExtra(GROUP_ID, f.getId().getBytes());
-				i.putExtra(GROUP_NAME, f.getName());
-				startActivity(i);
-				Toast.makeText(CreateForumActivity.this,
-						R.string.forum_created_toast, LENGTH_LONG).show();
-				supportFinishAfterTransition();
-			}
+	private void displayForum(Forum f) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			Intent i = new Intent(CreateForumActivity.this,
+					ForumActivity.class);
+			i.putExtra(GROUP_ID, f.getId().getBytes());
+			i.putExtra(GROUP_NAME, f.getName());
+			startActivity(i);
+			Toast.makeText(CreateForumActivity.this,
+					R.string.forum_created_toast, LENGTH_LONG).show();
+			supportFinishAfterTransition();
 		});
 	}
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java
index ccff1a6ce3fd1fbfe21638192993bbb5371ec26c..51e6f3937f47376c6d406993116ee1aa8665c854 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java
@@ -1,6 +1,5 @@
 package org.briarproject.briar.android.forum;
 
-import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
 import android.content.Intent;
 import android.os.Bundle;
@@ -11,7 +10,6 @@ import android.support.v7.widget.Toolbar;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
-import android.view.View;
 import android.widget.Toast;
 
 import org.briarproject.bramble.api.contact.ContactId;
@@ -69,16 +67,12 @@ public class ForumActivity extends
 
 		// Open member list on Toolbar click
 		if (toolbar != null) {
-			toolbar.setOnClickListener(
-					new View.OnClickListener() {
-						@Override
-						public void onClick(View v) {
-							Intent i = new Intent(ForumActivity.this,
-									ForumSharingStatusActivity.class);
-							i.putExtra(GROUP_ID, groupId.getBytes());
-							startActivity(i);
-						}
-					});
+			toolbar.setOnClickListener(v -> {
+				Intent i1 = new Intent(ForumActivity.this,
+						ForumSharingStatusActivity.class);
+				i1.putExtra(GROUP_ID, groupId.getBytes());
+				startActivity(i1);
+			});
 		}
 	}
 
@@ -112,7 +106,7 @@ public class ForumActivity extends
 	}
 
 	@Override
-	public boolean onOptionsItemSelected(final MenuItem item) {
+	public boolean onOptionsItemSelected(MenuItem item) {
 		// Handle presses on the action bar items
 		switch (item.getItemId()) {
 			case R.id.action_forum_share:
@@ -147,12 +141,7 @@ public class ForumActivity extends
 	}
 
 	private void showUnsubscribeDialog() {
-		OnClickListener okListener = new OnClickListener() {
-			@Override
-			public void onClick(DialogInterface dialog, int which) {
-				deleteForum();
-			}
-		};
+		OnClickListener okListener = (dialog, which) -> deleteForum();
 		AlertDialog.Builder builder = new AlertDialog.Builder(this,
 				R.style.BriarDialogTheme);
 		builder.setTitle(getString(R.string.dialog_title_leave_forum));
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumControllerImpl.java
index dde424f7b868d7c2fe0c1d30ae15dbe3bf145ee9..5b68f84cb95e6fcc21234625a913bed43d48ad81 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumControllerImpl.java
@@ -120,62 +120,50 @@ class ForumControllerImpl extends
 
 	@Override
 	public void loadSharingContacts(
-			final ResultExceptionHandler<Collection<ContactId>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Collection<Contact> contacts =
-							forumSharingManager.getSharedWith(getGroupId());
-					Collection<ContactId> contactIds =
-							new ArrayList<>(contacts.size());
-					for (Contact c : contacts) contactIds.add(c.getId());
-					handler.onResult(contactIds);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+			ResultExceptionHandler<Collection<ContactId>, DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				Collection<Contact> contacts =
+						forumSharingManager.getSharedWith(getGroupId());
+				Collection<ContactId> contactIds =
+						new ArrayList<>(contacts.size());
+				for (Contact c : contacts) contactIds.add(c.getId());
+				handler.onResult(contactIds);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
 
 	@Override
-	public void createAndStoreMessage(final String body,
-			@Nullable final ForumItem parentItem,
-			final ResultExceptionHandler<ForumItem, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					LocalAuthor author = identityManager.getLocalAuthor();
-					GroupCount count = forumManager.getGroupCount(getGroupId());
-					long timestamp = max(count.getLatestMsgTime() + 1,
-							clock.currentTimeMillis());
-					MessageId parentId = parentItem != null ?
-							parentItem.getId() : null;
-					createMessage(body, timestamp, parentId, author, handler);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+	public void createAndStoreMessage(String body,
+			@Nullable ForumItem parentItem,
+			ResultExceptionHandler<ForumItem, DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				LocalAuthor author = identityManager.getLocalAuthor();
+				GroupCount count = forumManager.getGroupCount(getGroupId());
+				long timestamp = max(count.getLatestMsgTime() + 1,
+						clock.currentTimeMillis());
+				MessageId parentId = parentItem != null ?
+						parentItem.getId() : null;
+				createMessage(body, timestamp, parentId, author, handler);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
 
-	private void createMessage(final String body, final long timestamp,
-			final @Nullable MessageId parentId, final LocalAuthor author,
-			final ResultExceptionHandler<ForumItem, DbException> handler) {
-		cryptoExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				LOG.info("Creating forum post...");
-				ForumPost msg = forumManager
-						.createLocalPost(getGroupId(), body, timestamp,
-								parentId, author);
-				storePost(msg, body, handler);
-			}
+	private void createMessage(String body, long timestamp,
+			@Nullable MessageId parentId, LocalAuthor author,
+			ResultExceptionHandler<ForumItem, DbException> handler) {
+		cryptoExecutor.execute(() -> {
+			LOG.info("Creating forum post...");
+			ForumPost msg = forumManager.createLocalPost(getGroupId(), body,
+					timestamp, parentId, author);
+			storePost(msg, body, handler);
 		});
 	}
 
@@ -196,31 +184,18 @@ class ForumControllerImpl extends
 	}
 
 	private void onForumPostReceived(ForumPostHeader h, String body) {
-		final ForumItem item = buildItem(h, body);
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onItemReceived(item);
-			}
-		});
+		ForumItem item = buildItem(h, body);
+		listener.runOnUiThreadUnlessDestroyed(
+				() -> listener.onItemReceived(item));
 	}
 
-	private void onForumInvitationAccepted(final ContactId c) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onInvitationAccepted(c);
-			}
-		});
+	private void onForumInvitationAccepted(ContactId c) {
+		listener.runOnUiThreadUnlessDestroyed(
+				() -> listener.onInvitationAccepted(c));
 	}
 
-	private void onForumLeft(final ContactId c) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onForumLeft(c);
-			}
-		});
+	private void onForumLeft(ContactId c) {
+		listener.runOnUiThreadUnlessDestroyed(() -> listener.onForumLeft(c));
 	}
 
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListAdapter.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListAdapter.java
index 46d8007fbe6a2868035e067e36c5cf78b2b69582..c46833fe2dd5fcd0de9759785b05c4f7afd15421 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListAdapter.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListAdapter.java
@@ -38,7 +38,7 @@ class ForumListAdapter
 
 	@Override
 	public void onBindViewHolder(ForumViewHolder ui, int position) {
-		final ForumListItem item = getItemAt(position);
+		ForumListItem item = getItemAt(position);
 		if (item == null) return;
 
 		// Avatar
@@ -77,15 +77,12 @@ class ForumListAdapter
 		}
 
 		// Open Forum on Click
-		ui.layout.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				Intent i = new Intent(ctx, ForumActivity.class);
-				Forum f = item.getForum();
-				i.putExtra(GROUP_ID, f.getId().getBytes());
-				i.putExtra(GROUP_NAME, f.getName());
-				ctx.startActivity(i);
-			}
+		ui.layout.setOnClickListener(v -> {
+			Intent i = new Intent(ctx, ForumActivity.class);
+			Forum f = item.getForum();
+			i.putExtra(GROUP_ID, f.getId().getBytes());
+			i.putExtra(GROUP_NAME, f.getName());
+			ctx.startActivity(i);
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListFragment.java
index a1d88d884541bc8a4e43454020e918586fc9a8b4..5fcf22ecf352d69c9bcdf1b405cc77332e2602b6 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListFragment.java
@@ -140,7 +140,7 @@ public class ForumListFragment extends BaseEventFragment implements
 	}
 
 	@Override
-	public boolean onOptionsItemSelected(final MenuItem item) {
+	public boolean onOptionsItemSelected(MenuItem item) {
 		// Handle presses on the action bar items
 		switch (item.getItemId()) {
 			case R.id.action_create_forum:
@@ -154,83 +154,67 @@ public class ForumListFragment extends BaseEventFragment implements
 	}
 
 	private void loadForums() {
-		final int revision = adapter.getRevision();
-		listener.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					Collection<ForumListItem> forums = new ArrayList<>();
-					for (Forum f : forumManager.getForums()) {
-						try {
-							GroupCount count =
-									forumManager.getGroupCount(f.getId());
-							forums.add(new ForumListItem(f, count));
-						} catch (NoSuchGroupException e) {
-							// Continue
-						}
+		int revision = adapter.getRevision();
+		listener.runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				Collection<ForumListItem> forums = new ArrayList<>();
+				for (Forum f : forumManager.getForums()) {
+					try {
+						GroupCount count =
+								forumManager.getGroupCount(f.getId());
+						forums.add(new ForumListItem(f, count));
+					} catch (NoSuchGroupException e) {
+						// Continue
 					}
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Full load took " + duration + " ms");
-					displayForums(revision, forums);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
 				}
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Full load took " + duration + " ms");
+				displayForums(revision, forums);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
-	private void displayForums(final int revision,
-			final Collection<ForumListItem> forums) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (revision == adapter.getRevision()) {
-					adapter.incrementRevision();
-					if (forums.isEmpty()) list.showData();
-					else adapter.addAll(forums);
-				} else {
-					LOG.info("Concurrent update, reloading");
-					loadForums();
-				}
+	private void displayForums(int revision, Collection<ForumListItem> forums) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (revision == adapter.getRevision()) {
+				adapter.incrementRevision();
+				if (forums.isEmpty()) list.showData();
+				else adapter.addAll(forums);
+			} else {
+				LOG.info("Concurrent update, reloading");
+				loadForums();
 			}
 		});
 	}
 
 	private void loadAvailableForums() {
-		listener.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					int available =
-							forumSharingManager.getInvitations().size();
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading available took " + duration + " ms");
-					displayAvailableForums(available);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		listener.runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				int available = forumSharingManager.getInvitations().size();
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading available took " + duration + " ms");
+				displayAvailableForums(available);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
-	private void displayAvailableForums(final int availableCount) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (availableCount == 0) {
-					snackbar.dismiss();
-				} else {
-					snackbar.setText(getResources().getQuantityString(
-							R.plurals.forums_shared, availableCount,
-							availableCount));
-					if (!snackbar.isShownOrQueued()) snackbar.show();
-				}
+	private void displayAvailableForums(int availableCount) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (availableCount == 0) {
+				snackbar.dismiss();
+			} else {
+				snackbar.setText(getResources().getQuantityString(
+						R.plurals.forums_shared, availableCount,
+						availableCount));
+				if (!snackbar.isShownOrQueued()) snackbar.show();
 			}
 		});
 	}
@@ -262,30 +246,24 @@ public class ForumListFragment extends BaseEventFragment implements
 		}
 	}
 
-	private void updateItem(final GroupId g, final ForumPostHeader m) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				adapter.incrementRevision();
-				int position = adapter.findItemPosition(g);
-				ForumListItem item = adapter.getItemAt(position);
-				if (item != null) {
-					item.addHeader(m);
-					adapter.updateItemAt(position, item);
-				}
+	private void updateItem(GroupId g, ForumPostHeader m) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			adapter.incrementRevision();
+			int position = adapter.findItemPosition(g);
+			ForumListItem item = adapter.getItemAt(position);
+			if (item != null) {
+				item.addHeader(m);
+				adapter.updateItemAt(position, item);
 			}
 		});
 	}
 
-	private void removeForum(final GroupId g) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				adapter.incrementRevision();
-				int position = adapter.findItemPosition(g);
-				ForumListItem item = adapter.getItemAt(position);
-				if (item != null) adapter.remove(item);
-			}
+	private void removeForum(GroupId g) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			adapter.incrementRevision();
+			int position = adapter.findItemPosition(g);
+			ForumListItem item = adapter.getItemAt(position);
+			if (item != null) adapter.remove(item);
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/fragment/BaseFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/fragment/BaseFragment.java
index 7273a7f54f1c6eddf19946cd01a7c3cb69c07024..0fa3ee7b6d2fbbc7c113338df30c8e7303306868 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/fragment/BaseFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/fragment/BaseFragment.java
@@ -44,7 +44,7 @@ public abstract class BaseFragment extends Fragment
 	}
 
 	@Override
-	public boolean onOptionsItemSelected(final MenuItem item) {
+	public boolean onOptionsItemSelected(MenuItem item) {
 		switch (item.getItemId()) {
 			case android.R.id.home:
 				listener.onBackPressed();
@@ -79,17 +79,14 @@ public abstract class BaseFragment extends Fragment
 
 	@CallSuper
 	@Override
-	public void runOnUiThreadUnlessDestroyed(final Runnable r) {
-		final Activity activity = getActivity();
+	public void runOnUiThreadUnlessDestroyed(Runnable r) {
+		Activity activity = getActivity();
 		if (activity != null) {
-			activity.runOnUiThread(new Runnable() {
-				@Override
-				public void run() {
-					// Note that we don't have to check if the activity has
-					// been destroyed as the Fragment has not been detached yet
-					if (!isDetached() && !activity.isFinishing()) {
-						r.run();
-					}
+			activity.runOnUiThread(() -> {
+				// Note that we don't have to check if the activity has
+				// been destroyed as the Fragment has not been detached yet
+				if (!isDetached() && !activity.isFinishing()) {
+					r.run();
 				}
 			});
 		}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/fragment/ScreenFilterDialogFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/fragment/ScreenFilterDialogFragment.java
index 242aaed31b22f422c9bbc6d6b38a332c7ad0a016..b1e644e96a35c4cee93f321abd32f3ffcb032474 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/fragment/ScreenFilterDialogFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/fragment/ScreenFilterDialogFragment.java
@@ -1,7 +1,6 @@
 package org.briarproject.briar.android.fragment;
 
 import android.app.Dialog;
-import android.content.DialogInterface;
 import android.os.Bundle;
 import android.support.v4.app.DialogFragment;
 import android.support.v7.app.AlertDialog;
@@ -35,12 +34,7 @@ public class ScreenFilterDialogFragment extends DialogFragment {
 		builder.setMessage(getString(R.string.screen_filter_body,
 				TextUtils.join("\n", apps)));
 		builder.setNeutralButton(R.string.continue_button,
-				new DialogInterface.OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialog, int which) {
-						dialog.dismiss();
-					}
-				});
+				(dialog, which) -> dialog.dismiss());
 		return builder.create();
 	}
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/introduction/ContactChooserFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/introduction/ContactChooserFragment.java
index 7bfa80f969a747cd8ba2f378489bf68c06367833..99ccd1f3bd9ad8fd7f469b844994cc93330da8c2 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/introduction/ContactChooserFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/introduction/ContactChooserFragment.java
@@ -71,13 +71,10 @@ public class ContactChooserFragment extends BaseFragment {
 		View contentView = inflater.inflate(R.layout.list, container, false);
 
 		OnContactClickListener<ContactListItem> onContactClickListener =
-				new OnContactClickListener<ContactListItem>() {
-					@Override
-					public void onItemClick(View view, ContactListItem item) {
-						if (c1 == null) throw new IllegalStateException();
-						Contact c2 = item.getContact();
-						showMessageScreen(c1, c2);
-					}
+				(view, item) -> {
+					if (c1 == null) throw new IllegalStateException();
+					Contact c2 = item.getContact();
+					showMessageScreen(c1, c2);
 				};
 		adapter = new ContactListAdapter(getActivity(), onContactClickListener);
 
@@ -115,40 +112,32 @@ public class ContactChooserFragment extends BaseFragment {
 	}
 
 	private void loadContacts() {
-		listener.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					List<ContactListItem> contacts = new ArrayList<>();
-					for (Contact c : contactManager.getActiveContacts()) {
-						if (c.getId().equals(contactId)) {
-							c1 = c;
-						} else {
-							ContactId id = c.getId();
-							GroupCount count =
-									conversationManager.getGroupCount(id);
-							boolean connected =
-									connectionRegistry.isConnected(c.getId());
-							contacts.add(new ContactListItem(c, connected,
-									count));
-						}
+		listener.runOnDbThread(() -> {
+			try {
+				List<ContactListItem> contacts = new ArrayList<>();
+				for (Contact c : contactManager.getActiveContacts()) {
+					if (c.getId().equals(contactId)) {
+						c1 = c;
+					} else {
+						ContactId id = c.getId();
+						GroupCount count =
+								conversationManager.getGroupCount(id);
+						boolean connected =
+								connectionRegistry.isConnected(c.getId());
+						contacts.add(new ContactListItem(c, connected, count));
 					}
-					displayContacts(contacts);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
 				}
+				displayContacts(contacts);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
-	private void displayContacts(final List<ContactListItem> contacts) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (contacts.isEmpty()) list.showData();
-				else adapter.addAll(contacts);
-			}
+	private void displayContacts(List<ContactListItem> contacts) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (contacts.isEmpty()) list.showData();
+			else adapter.addAll(contacts);
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/introduction/IntroductionMessageFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/introduction/IntroductionMessageFragment.java
index ddf70e4f2a953f945915fa8370c0fa39f26b7706..52fcd30cba4a1916c1479c6873742257b8eda3c5 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/introduction/IntroductionMessageFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/introduction/IntroductionMessageFragment.java
@@ -118,55 +118,47 @@ public class IntroductionMessageFragment extends BaseFragment
 		return TAG;
 	}
 
-	private void prepareToSetUpViews(final int contactId1,
-			final int contactId2) {
-		introductionActivity.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Contact c1 = contactManager.getContact(
-							new ContactId(contactId1));
-					Contact c2 = contactManager.getContact(
-							new ContactId(contactId2));
-					setUpViews(c1, c2);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+	private void prepareToSetUpViews(int contactId1, int contactId2) {
+		introductionActivity.runOnDbThread(() -> {
+			try {
+				Contact c1 = contactManager.getContact(
+						new ContactId(contactId1));
+				Contact c2 = contactManager.getContact(
+						new ContactId(contactId2));
+				setUpViews(c1, c2);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
-	private void setUpViews(final Contact c1, final Contact c2) {
-		introductionActivity.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				contact1 = c1;
-				contact2 = c2;
-
-				// set avatars
-				ui.avatar1.setImageDrawable(new IdenticonDrawable(
-						c1.getAuthor().getId().getBytes()));
-				ui.avatar2.setImageDrawable(new IdenticonDrawable(
-						c2.getAuthor().getId().getBytes()));
-
-				// set contact names
-				ui.contactName1.setText(c1.getAuthor().getName());
-				ui.contactName2.setText(c2.getAuthor().getName());
-
-				// set button action
-				ui.message.setListener(IntroductionMessageFragment.this);
-
-				// hide progress bar and show views
-				ui.progressBar.setVisibility(GONE);
-				ui.message.setSendButtonEnabled(true);
-				ui.message.showSoftKeyboard();
-			}
+	private void setUpViews(Contact c1, Contact c2) {
+		introductionActivity.runOnUiThreadUnlessDestroyed(() -> {
+			contact1 = c1;
+			contact2 = c2;
+
+			// set avatars
+			ui.avatar1.setImageDrawable(new IdenticonDrawable(
+					c1.getAuthor().getId().getBytes()));
+			ui.avatar2.setImageDrawable(new IdenticonDrawable(
+					c2.getAuthor().getId().getBytes()));
+
+			// set contact names
+			ui.contactName1.setText(c1.getAuthor().getName());
+			ui.contactName2.setText(c2.getAuthor().getName());
+
+			// set button action
+			ui.message.setListener(IntroductionMessageFragment.this);
+
+			// hide progress bar and show views
+			ui.progressBar.setVisibility(GONE);
+			ui.message.setSendButtonEnabled(true);
+			ui.message.showSoftKeyboard();
 		});
 	}
 
 	@Override
-	public boolean onOptionsItemSelected(final MenuItem item) {
+	public boolean onOptionsItemSelected(MenuItem item) {
 		switch (item.getItemId()) {
 			case android.R.id.home:
 				introductionActivity.hideSoftKeyboard(ui.message);
@@ -192,33 +184,23 @@ public class IntroductionMessageFragment extends BaseFragment
 		introductionActivity.supportFinishAfterTransition();
 	}
 
-	private void makeIntroduction(final Contact c1, final Contact c2,
-			final String msg) {
-		introductionActivity.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				// actually make the introduction
-				try {
-					long timestamp = System.currentTimeMillis();
-					introductionManager.makeIntroduction(c1, c2, msg,
-							timestamp);
-				} catch (DbException | FormatException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					introductionError();
-				}
+	private void makeIntroduction(Contact c1, Contact c2, String msg) {
+		introductionActivity.runOnDbThread(() -> {
+			// actually make the introduction
+			try {
+				long timestamp = System.currentTimeMillis();
+				introductionManager.makeIntroduction(c1, c2, msg, timestamp);
+			} catch (DbException | FormatException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				introductionError();
 			}
 		});
 	}
 
 	private void introductionError() {
-		introductionActivity.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				Toast.makeText(introductionActivity,
-						R.string.introduction_error, LENGTH_SHORT).show();
-			}
-		});
+		introductionActivity.runOnUiThreadUnlessDestroyed(
+				() -> Toast.makeText(introductionActivity,
+						R.string.introduction_error, LENGTH_SHORT).show());
 	}
 
 	private static class ViewHolder {
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/CameraView.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/CameraView.java
index 4ea6ad246081ed742a6089eb1375098193c3d4e4..b3d1b9345c6b7e21f15cc1860bdb791227d13527 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/CameraView.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/CameraView.java
@@ -352,16 +352,12 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
 	}
 
 	@Override
-	public void surfaceCreated(final SurfaceHolder holder) {
-		post(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					surfaceCreatedUi(holder);
-				} catch (CameraException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+	public void surfaceCreated(SurfaceHolder holder) {
+		post(() -> {
+			try {
+				surfaceCreatedUi(holder);
+			} catch (CameraException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
@@ -379,17 +375,12 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
 	}
 
 	@Override
-	public void surfaceChanged(final SurfaceHolder holder, int format,
-			final int w, final int h) {
-		post(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					surfaceChangedUi(holder, w, h);
-				} catch (CameraException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+	public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+		post(() -> {
+			try {
+				surfaceChangedUi(holder, w, h);
+			} catch (CameraException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
@@ -419,13 +410,8 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
 	}
 
 	@Override
-	public void surfaceDestroyed(final SurfaceHolder holder) {
-		post(new Runnable() {
-			@Override
-			public void run() {
-				surfaceDestroyedUi(holder);
-			}
-		});
+	public void surfaceDestroyed(SurfaceHolder holder) {
+		post(() -> surfaceDestroyedUi(holder));
 	}
 
 	@UiThread
@@ -440,14 +426,9 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
 	}
 
 	@Override
-	public void onAutoFocus(boolean success, final Camera camera) {
+	public void onAutoFocus(boolean success, Camera camera) {
 		LOG.info("Auto focus succeeded: " + success);
-		postDelayed(new Runnable() {
-			@Override
-			public void run() {
-				retryAutoFocus();
-			}
-		}, AUTO_FOCUS_RETRY_DELAY);
+		postDelayed(this::retryAutoFocus, AUTO_FOCUS_RETRY_DELAY);
 	}
 
 	@UiThread
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/IntroFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/IntroFragment.java
index db37ed93306a3484b228769153b8499ddd44f107..f1112729794cee833ada6a697dd44f716c042a7f 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/IntroFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/IntroFragment.java
@@ -4,7 +4,6 @@ import android.content.Context;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.ScrollView;
 
@@ -66,24 +65,14 @@ public class IntroFragment extends BaseFragment {
 				false);
 		scrollView = (ScrollView) v.findViewById(R.id.scrollView);
 		View button = v.findViewById(R.id.continueButton);
-		button.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View view) {
-				screenSeenListener.showNextScreen();
-			}
-		});
+		button.setOnClickListener(view -> screenSeenListener.showNextScreen());
 		return v;
 	}
 
 	@Override
 	public void onStart() {
 		super.onStart();
-		scrollView.post(new Runnable() {
-			@Override
-			public void run() {
-				scrollView.fullScroll(FOCUS_DOWN);
-			}
-		});
+		scrollView.post(() -> scrollView.fullScroll(FOCUS_DOWN));
 	}
 
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java
index 59203041a713711f6b81fa3356f21a0a49a33a6f..e866662dca5e2d4ed38fe66c773e002b2d0f1551 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java
@@ -1,6 +1,5 @@
 package org.briarproject.briar.android.keyagreement;
 
-import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
 import android.os.Bundle;
 import android.support.annotation.UiThread;
@@ -100,7 +99,7 @@ public class KeyAgreementActivity extends BriarActivity implements
 	}
 
 	@Override
-	public boolean onOptionsItemSelected(final MenuItem item) {
+	public boolean onOptionsItemSelected(MenuItem item) {
 		switch (item.getItemId()) {
 			case android.R.id.home:
 				onBackPressed();
@@ -144,12 +143,8 @@ public class KeyAgreementActivity extends BriarActivity implements
 			// Should we show an explanation?
 			if (ActivityCompat.shouldShowRequestPermissionRationale(this,
 					CAMERA)) {
-				OnClickListener continueListener = new OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialog, int which) {
-						requestPermission();
-					}
-				};
+				OnClickListener continueListener =
+						(dialog, which) -> requestPermission();
 				Builder builder = new Builder(this, style.BriarDialogTheme);
 				builder.setTitle(string.permission_camera_title);
 				builder.setMessage(string.permission_camera_request_body);
@@ -183,12 +178,8 @@ public class KeyAgreementActivity extends BriarActivity implements
 				if (!ActivityCompat.shouldShowRequestPermissionRationale(this,
 						CAMERA)) {
 					// The user has permanently denied the request
-					OnClickListener cancelListener = new OnClickListener() {
-						@Override
-						public void onClick(DialogInterface dialog, int which) {
-							supportFinishAfterTransition();
-						}
-					};
+					OnClickListener cancelListener =
+							(dialog, which) -> supportFinishAfterTransition();
 					Builder builder = new Builder(this, style.BriarDialogTheme);
 					builder.setTitle(string.permission_camera_title);
 					builder.setMessage(string.permission_camera_denied_body);
@@ -213,78 +204,58 @@ public class KeyAgreementActivity extends BriarActivity implements
 		}
 	}
 
-	private void keyAgreementFinished(final KeyAgreementResult result) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				startContactExchange(result);
-			}
-		});
+	private void keyAgreementFinished(KeyAgreementResult result) {
+		runOnUiThreadUnlessDestroyed(() -> startContactExchange(result));
 	}
 
-	private void startContactExchange(final KeyAgreementResult result) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				LocalAuthor localAuthor;
-				// Load the local pseudonym
-				try {
-					localAuthor = identityManager.getLocalAuthor();
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					contactExchangeFailed();
-					return;
-				}
-
-				// Exchange contact details
-				contactExchangeTask.startExchange(KeyAgreementActivity.this,
-						localAuthor, result.getMasterKey(),
-						result.getConnection(), result.getTransportId(),
-						result.wasAlice());
+	private void startContactExchange(KeyAgreementResult result) {
+		runOnDbThread(() -> {
+			LocalAuthor localAuthor;
+			// Load the local pseudonym
+			try {
+				localAuthor = identityManager.getLocalAuthor();
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				contactExchangeFailed();
+				return;
 			}
+
+			// Exchange contact details
+			contactExchangeTask.startExchange(KeyAgreementActivity.this,
+					localAuthor, result.getMasterKey(),
+					result.getConnection(), result.getTransportId(),
+					result.wasAlice());
 		});
 	}
 
 	@Override
-	public void contactExchangeSucceeded(final Author remoteAuthor) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				String contactName = remoteAuthor.getName();
-				String format = getString(R.string.contact_added_toast);
-				String text = String.format(format, contactName);
-				Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG)
-						.show();
-				supportFinishAfterTransition();
-			}
+	public void contactExchangeSucceeded(Author remoteAuthor) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			String contactName = remoteAuthor.getName();
+			String format = getString(string.contact_added_toast);
+			String text = String.format(format, contactName);
+			Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG).show();
+			supportFinishAfterTransition();
 		});
 	}
 
 	@Override
-	public void duplicateContact(final Author remoteAuthor) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				String contactName = remoteAuthor.getName();
-				String format = getString(R.string.contact_already_exists);
-				String text = String.format(format, contactName);
-				Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG)
-						.show();
-				finish();
-			}
+	public void duplicateContact(Author remoteAuthor) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			String contactName = remoteAuthor.getName();
+			String format = getString(string.contact_already_exists);
+			String text = String.format(format, contactName);
+			Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG).show();
+			finish();
 		});
 	}
 
 	@Override
 	public void contactExchangeFailed() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				Toast.makeText(KeyAgreementActivity.this,
-						R.string.contact_exchange_failed, LENGTH_LONG).show();
-				finish();
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			Toast.makeText(KeyAgreementActivity.this,
+					string.contact_exchange_failed, LENGTH_LONG).show();
+			finish();
 		});
 	}
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/QrCodeUtils.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/QrCodeUtils.java
index 43286f6fd5ae737daceeec0f21c4212b4a13aa75..a4099c298dd843a920c872559b462a63b58a8541 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/QrCodeUtils.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/QrCodeUtils.java
@@ -30,8 +30,8 @@ class QrCodeUtils {
 		int smallestDimen = Math.min(dm.widthPixels, dm.heightPixels);
 		try {
 			// Generate QR code
-			final BitMatrix encoded = new QRCodeWriter().encode(
-					input, QR_CODE, smallestDimen, smallestDimen);
+			BitMatrix encoded = new QRCodeWriter().encode(input, QR_CODE,
+					smallestDimen, smallestDimen);
 			// Convert QR code to Bitmap
 			int width = encoded.getWidth();
 			int height = encoded.getHeight();
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ShowQrCodeFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ShowQrCodeFragment.java
index fbf6f53e4135513d5cc59466e1939177f0098342..ae01d66c49b5b0f866fd56b91e9a0bd25009b79d 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ShowQrCodeFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ShowQrCodeFragment.java
@@ -157,8 +157,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
 		getActivity().registerReceiver(receiver, filter);
 
 		// Enable BT adapter if it is not already on.
-		final BluetoothAdapter adapter =
-				BluetoothAdapter.getDefaultAdapter();
+		BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
 		if (adapter != null && !adapter.isEnabled()) {
 			waitingForBluetooth = true;
 			eventBus.broadcast(new EnableBluetoothEvent());
@@ -189,26 +188,20 @@ public class ShowQrCodeFragment extends BaseEventFragment
 
 	@UiThread
 	private void startListening() {
-		final KeyAgreementTask oldTask = task;
-		final KeyAgreementTask newTask = keyAgreementTaskFactory.createTask();
+		KeyAgreementTask oldTask = task;
+		KeyAgreementTask newTask = keyAgreementTaskFactory.createTask();
 		task = newTask;
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				if (oldTask != null) oldTask.stopListening();
-				newTask.listen();
-			}
+		ioExecutor.execute(() -> {
+			if (oldTask != null) oldTask.stopListening();
+			newTask.listen();
 		});
 	}
 
 	@UiThread
 	private void stopListening() {
-		final KeyAgreementTask oldTask = task;
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				if (oldTask != null) oldTask.stopListening();
-			}
+		KeyAgreementTask oldTask = task;
+		ioExecutor.execute(() -> {
+			if (oldTask != null) oldTask.stopListening();
 		});
 	}
 
@@ -255,23 +248,19 @@ public class ShowQrCodeFragment extends BaseEventFragment
 			KeyAgreementAbortedEvent event = (KeyAgreementAbortedEvent) e;
 			keyAgreementAborted(event.didRemoteAbort());
 		} else if (e instanceof KeyAgreementFinishedEvent) {
-			runOnUiThreadUnlessDestroyed(new Runnable() {
-				@Override
-				public void run() {
-					mainProgressContainer.setVisibility(VISIBLE);
-					mainProgressTitle.setText(
-							R.string.exchanging_contact_details);
-				}
+			runOnUiThreadUnlessDestroyed(() -> {
+				mainProgressContainer.setVisibility(VISIBLE);
+				mainProgressTitle.setText(R.string.exchanging_contact_details);
 			});
 		}
 	}
 
 	@UiThread
-	private void generateBitmapQR(final Payload payload) {
+	private void generateBitmapQR(Payload payload) {
 		// Get narrowest screen dimension
 		Context context = getContext();
 		if (context == null) return;
-		final DisplayMetrics dm = context.getResources().getDisplayMetrics();
+		DisplayMetrics dm = context.getResources().getDisplayMetrics();
 		new AsyncTask<Void, Void, Bitmap>() {
 
 			@Override
@@ -296,76 +285,55 @@ public class ShowQrCodeFragment extends BaseEventFragment
 		}.execute();
 	}
 
-	private void setQrCode(final Payload localPayload) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				generateBitmapQR(localPayload);
-			}
-		});
+	private void setQrCode(Payload localPayload) {
+		runOnUiThreadUnlessDestroyed(() -> generateBitmapQR(localPayload));
 	}
 
 	private void keyAgreementFailed() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				reset();
-				// TODO show failure somewhere persistent?
-				Toast.makeText(getActivity(), R.string.connection_failed,
-						LENGTH_LONG).show();
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			reset();
+			// TODO show failure somewhere persistent?
+			Toast.makeText(getActivity(), R.string.connection_failed,
+					LENGTH_LONG).show();
 		});
 	}
 
 	private void keyAgreementWaiting() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				status.setText(R.string.waiting_for_contact_to_scan);
-			}
-		});
+		runOnUiThreadUnlessDestroyed(
+				() -> status.setText(R.string.waiting_for_contact_to_scan));
 	}
 
 	private void keyAgreementStarted() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				mainProgressContainer.setVisibility(VISIBLE);
-				mainProgressTitle.setText(R.string.authenticating_with_device);
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			mainProgressContainer.setVisibility(VISIBLE);
+			mainProgressTitle.setText(R.string.authenticating_with_device);
 		});
 	}
 
-	private void keyAgreementAborted(final boolean remoteAborted) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				reset();
-				mainProgressContainer.setVisibility(INVISIBLE);
-				mainProgressTitle.setText("");
-				// TODO show abort somewhere persistent?
-				Toast.makeText(getActivity(),
-						remoteAborted ? R.string.connection_aborted_remote :
-								R.string.connection_aborted_local, LENGTH_LONG)
-						.show();
-			}
+	private void keyAgreementAborted(boolean remoteAborted) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			reset();
+			mainProgressContainer.setVisibility(INVISIBLE);
+			mainProgressTitle.setText("");
+			// TODO show abort somewhere persistent?
+			Toast.makeText(getActivity(),
+					remoteAborted ? R.string.connection_aborted_remote :
+							R.string.connection_aborted_local, LENGTH_LONG)
+					.show();
 		});
 	}
 
 	@Override
-	public void handleResult(final Result result) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				LOG.info("Got result from decoder");
-				// Ignore results until the KeyAgreementTask is ready
-				if (!gotLocalPayload) {
-					return;
-				}
-				if (!gotRemotePayload) {
-					gotRemotePayload = true;
-					qrCodeScanned(result.getText());
-				}
+	public void handleResult(Result result) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			LOG.info("Got result from decoder");
+			// Ignore results until the KeyAgreementTask is ready
+			if (!gotLocalPayload) {
+				return;
+			}
+			if (!gotRemotePayload) {
+				gotRemotePayload = true;
+				qrCodeScanned(result.getText());
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordActivity.java
index 26a5847a0467fa71fba93ab8e32e3b889a9132e4..ec0ccb5721a8d3dabb1ef5fb458888a9a5bf8b29 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordActivity.java
@@ -1,6 +1,5 @@
 package org.briarproject.briar.android.login;
 
-import android.content.DialogInterface;
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
@@ -8,13 +7,10 @@ import android.support.design.widget.TextInputLayout;
 import android.support.v7.app.AlertDialog;
 import android.text.Editable;
 import android.text.TextWatcher;
-import android.view.KeyEvent;
 import android.view.View;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ProgressBar;
-import android.widget.TextView;
-import android.widget.TextView.OnEditorActionListener;
 
 import org.briarproject.briar.R;
 import org.briarproject.briar.android.activity.ActivityComponent;
@@ -61,13 +57,9 @@ public class PasswordActivity extends BaseActivity {
 		progress = (ProgressBar) findViewById(R.id.progress_wheel);
 		input = (TextInputLayout) findViewById(R.id.password_layout);
 		password = (EditText) findViewById(R.id.edit_password);
-		password.setOnEditorActionListener(new OnEditorActionListener() {
-			@Override
-			public boolean onEditorAction(TextView v, int actionId,
-					KeyEvent event) {
-				validatePassword();
-				return true;
-			}
+		password.setOnEditorActionListener((v, actionId, event) -> {
+			validatePassword();
+			return true;
 		});
 		password.addTextChangedListener(new TextWatcher() {
 
@@ -131,12 +123,7 @@ public class PasswordActivity extends BaseActivity {
 		builder.setMessage(R.string.dialog_message_lost_password);
 		builder.setPositiveButton(R.string.cancel, null);
 		builder.setNegativeButton(R.string.delete,
-				new DialogInterface.OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialog, int which) {
-						deleteAccount();
-					}
-				});
+				(dialog, which) -> deleteAccount());
 		AlertDialog dialog = builder.create();
 		dialog.show();
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordControllerImpl.java
index e2a921d30e8747507840f5e5870f8961594bb4e0..d2c2e54f50e1e4048faa8a184efd0ffd0e2c9dec 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordControllerImpl.java
@@ -47,39 +47,33 @@ public class PasswordControllerImpl extends ConfigControllerImpl
 	}
 
 	@Override
-	public void validatePassword(final String password,
-			final ResultHandler<Boolean> resultHandler) {
-		final byte[] encrypted = getEncryptedKey();
-		cryptoExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				byte[] key = crypto.decryptWithPassword(encrypted, password);
-				if (key == null) {
-					resultHandler.onResult(false);
-				} else {
-					databaseConfig.setEncryptionKey(new SecretKey(key));
-					resultHandler.onResult(true);
-				}
+	public void validatePassword(String password,
+			ResultHandler<Boolean> resultHandler) {
+		byte[] encrypted = getEncryptedKey();
+		cryptoExecutor.execute(() -> {
+			byte[] key = crypto.decryptWithPassword(encrypted, password);
+			if (key == null) {
+				resultHandler.onResult(false);
+			} else {
+				databaseConfig.setEncryptionKey(new SecretKey(key));
+				resultHandler.onResult(true);
 			}
 		});
 	}
 
 	@Override
-	public void changePassword(final String password, final String newPassword,
-			final ResultHandler<Boolean> resultHandler) {
-		final byte[] encrypted = getEncryptedKey();
-		cryptoExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				byte[] key = crypto.decryptWithPassword(encrypted, password);
-				if (key == null) {
-					resultHandler.onResult(false);
-				} else {
-					String hex =
-							encryptDatabaseKey(new SecretKey(key), newPassword);
-					storeEncryptedDatabaseKey(hex);
-					resultHandler.onResult(true);
-				}
+	public void changePassword(String password, String newPassword,
+			ResultHandler<Boolean> resultHandler) {
+		byte[] encrypted = getEncryptedKey();
+		cryptoExecutor.execute(() -> {
+			byte[] key = crypto.decryptWithPassword(encrypted, password);
+			if (key == null) {
+				resultHandler.onResult(false);
+			} else {
+				String hex =
+						encryptDatabaseKey(new SecretKey(key), newPassword);
+				storeEncryptedDatabaseKey(hex);
+				resultHandler.onResult(true);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/login/SetupControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/login/SetupControllerImpl.java
index 7fb8a7f7c07a0c9fac2c271fd7df084c13f6eb31..731cae02a73ae471e3ec7b6f00edfcc8b4954242 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/login/SetupControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/login/SetupControllerImpl.java
@@ -86,16 +86,13 @@ public class SetupControllerImpl extends PasswordControllerImpl
 	public void createAccount(final ResultHandler<Void> resultHandler) {
 		if (authorName == null || password == null)
 			throw new IllegalStateException();
-		cryptoExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				databaseConfig.setLocalAuthorName(authorName);
-				SecretKey key = crypto.generateSecretKey();
-				databaseConfig.setEncryptionKey(key);
-				String hex = encryptDatabaseKey(key, password);
-				storeEncryptedDatabaseKey(hex);
-				resultHandler.onResult(null);
-			}
+		cryptoExecutor.execute(() -> {
+			databaseConfig.setLocalAuthorName(authorName);
+			SecretKey key = crypto.generateSecretKey();
+			databaseConfig.setEncryptionKey(key);
+			String hex = encryptDatabaseKey(key, password);
+			storeEncryptedDatabaseKey(hex);
+			resultHandler.onResult(null);
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java
index b6557a693aaa298e8f567021a831cb891ef43dfd..e0ad7d8c9cb03e2c799b850cb01f3eb23071a3ff 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java
@@ -2,7 +2,6 @@ package org.briarproject.briar.android.navdrawer;
 
 import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
-import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.os.Bundle;
@@ -283,8 +282,7 @@ public class NavDrawerActivity extends BriarActivity implements
 		if (daysUntilExpiry < 0) signOut();
 
 		// show expiry warning text
-		final ViewGroup
-				expiryWarning = (ViewGroup) findViewById(R.id.expiryWarning);
+		ViewGroup expiryWarning = (ViewGroup) findViewById(R.id.expiryWarning);
 		TextView expiryWarningText =
 				(TextView) expiryWarning.findViewById(R.id.expiryWarningText);
 		// make close button functional
@@ -307,12 +305,9 @@ public class NavDrawerActivity extends BriarActivity implements
 							daysUntilExpiry, daysUntilExpiry));
 		}
 
-		expiryWarningClose.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				controller.expiryWarningDismissed();
-				expiryWarning.setVisibility(GONE);
-			}
+		expiryWarningClose.setOnClickListener(v -> {
+			controller.expiryWarningDismissed();
+			expiryWarning.setVisibility(GONE);
 		});
 
 		expiryWarning.setVisibility(VISIBLE);
@@ -323,20 +318,16 @@ public class NavDrawerActivity extends BriarActivity implements
 		new AlertDialog.Builder(this, R.style.BriarDialogTheme)
 				.setMessage(R.string.setup_doze_intro)
 				.setPositiveButton(R.string.ok,
-						new DialogInterface.OnClickListener() {
-							@Override
-							public void onClick(DialogInterface dialog,
-									int which) {
-								Intent i = getDozeWhitelistingIntent(
-										NavDrawerActivity.this);
-								startActivityForResult(i,
-										REQUEST_DOZE_WHITELISTING);
-							}
+						(dialog, which) -> {
+							Intent i = getDozeWhitelistingIntent(
+									NavDrawerActivity.this);
+							startActivityForResult(i,
+									REQUEST_DOZE_WHITELISTING);
 						})
 				.show();
 	}
 
-	private void initializeTransports(final LayoutInflater inflater) {
+	private void initializeTransports(LayoutInflater inflater) {
 		transports = new ArrayList<>(3);
 
 		Transport tor = new Transport();
@@ -410,17 +401,14 @@ public class NavDrawerActivity extends BriarActivity implements
 		};
 	}
 
-	private void setTransport(final TransportId id, final boolean enabled) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (transports == null || transportsAdapter == null) return;
-				for (Transport t : transports) {
-					if (t.id.equals(id)) {
-						t.enabled = enabled;
-						transportsAdapter.notifyDataSetChanged();
-						break;
-					}
+	private void setTransport(TransportId id, boolean enabled) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (transports == null || transportsAdapter == null) return;
+			for (Transport t : transports) {
+				if (t.id.equals(id)) {
+					t.enabled = enabled;
+					transportsAdapter.notifyDataSetChanged();
+					break;
 				}
 			}
 		});
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerController.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerController.java
index 79691695b30e5865ab31174f7259002dce509e2a..4b7c5a52ab5a88ad488ec219e408e968b29973a2 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerController.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerController.java
@@ -8,11 +8,11 @@ import org.briarproject.briar.android.controller.handler.ResultHandler;
 @NotNullByDefault
 public interface NavDrawerController extends ActivityLifecycleController {
 
-	enum ExpiryWarning { SHOW, NO, UPDATE };
+	enum ExpiryWarning { SHOW, NO, UPDATE }
 
 	boolean isTransportRunning(TransportId transportId);
 
-	void showExpiryWarning(final ResultHandler<ExpiryWarning> handler);
+	void showExpiryWarning(ResultHandler<ExpiryWarning> handler);
 
 	void expiryWarningDismissed();
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerControllerImpl.java
index a47b158cc97ca53558b1c195eef0c5c5e53be42a..00a62705cf07933bf973e896bb454381702febe8 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerControllerImpl.java
@@ -96,73 +96,60 @@ public class NavDrawerControllerImpl extends DbControllerImpl
 		}
 	}
 
-	private void transportStateUpdate(final TransportId id,
-			final boolean enabled) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.stateUpdate(id, enabled);
-			}
-		});
+	private void transportStateUpdate(TransportId id, boolean enabled) {
+		listener.runOnUiThreadUnlessDestroyed(
+				() -> listener.stateUpdate(id, enabled));
 	}
 
 	@Override
-	public void showExpiryWarning(final ResultHandler<ExpiryWarning> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Settings settings =
-							settingsManager.getSettings(SETTINGS_NAMESPACE);
-					int warningInt = settings.getInt(EXPIRY_DATE_WARNING, 0);
-					boolean showUpdate =
-							settings.getBoolean(EXPIRY_SHOW_UPDATE, true);
-
-					if (warningInt == 0) {
-						// we have not warned before
+	public void showExpiryWarning(ResultHandler<ExpiryWarning> handler) {
+		runOnDbThread(() -> {
+			try {
+				Settings settings =
+						settingsManager.getSettings(SETTINGS_NAMESPACE);
+				int warningInt = settings.getInt(EXPIRY_DATE_WARNING, 0);
+				boolean showUpdate =
+						settings.getBoolean(EXPIRY_SHOW_UPDATE, true);
+
+				if (warningInt == 0) {
+					// we have not warned before
+					handler.onResult(SHOW);
+				} else {
+					long warningLong = warningInt * 1000L;
+					long now = System.currentTimeMillis();
+					long daysSinceLastWarning =
+							(now - warningLong) / 1000 / 60 / 60 / 24;
+					long daysBeforeExpiry =
+							(EXPIRY_DATE - now) / 1000 / 60 / 60 / 24;
+
+					if (showUpdate) {
+						handler.onResult(UPDATE);
+					} else if (daysSinceLastWarning >= 30) {
+						handler.onResult(SHOW);
+					} else if (daysBeforeExpiry <= 3 &&
+							daysSinceLastWarning > 0) {
 						handler.onResult(SHOW);
 					} else {
-						long warningLong = warningInt * 1000L;
-						long now = System.currentTimeMillis();
-						long daysSinceLastWarning =
-								(now - warningLong) / 1000 / 60 / 60 / 24;
-						long daysBeforeExpiry =
-								(EXPIRY_DATE - now) / 1000 / 60 / 60 / 24;
-
-						if (showUpdate) {
-							handler.onResult(UPDATE);
-						} else if (daysSinceLastWarning >= 30) {
-							handler.onResult(SHOW);
-						} else if (daysBeforeExpiry <= 3 &&
-								daysSinceLastWarning > 0) {
-							handler.onResult(SHOW);
-						} else {
-							handler.onResult(NO);
-						}
+						handler.onResult(NO);
 					}
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
 				}
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	@Override
 	public void expiryWarningDismissed() {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Settings settings = new Settings();
-					int date = (int) (System.currentTimeMillis() / 1000L);
-					settings.putInt(EXPIRY_DATE_WARNING, date);
-					settings.putBoolean(EXPIRY_SHOW_UPDATE, false);
-					settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		runOnDbThread(() -> {
+			try {
+				Settings settings = new Settings();
+				int date = (int) (System.currentTimeMillis() / 1000L);
+				settings.putInt(EXPIRY_DATE_WARNING, date);
+				settings.putBoolean(EXPIRY_SHOW_UPDATE, false);
+				settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/panic/PanicPreferencesFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/panic/PanicPreferencesFragment.java
index f5184f5d80af7976c7d8f8d2ba385517c0161338..010f5ecbf2431c86d76da86de050ba646bdfa2f2 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/panic/PanicPreferencesFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/panic/PanicPreferencesFragment.java
@@ -12,7 +12,6 @@ import android.os.Bundle;
 import android.support.v7.app.AlertDialog;
 import android.support.v7.preference.CheckBoxPreference;
 import android.support.v7.preference.ListPreference;
-import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceFragmentCompat;
 import android.text.TextUtils;
 
@@ -92,51 +91,39 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
 				entryValues.toArray(new CharSequence[entryValues.size()]));
 		panicAppPref.setDefaultValue(Panic.PACKAGE_NAME_NONE);
 
-		panicAppPref.setOnPreferenceChangeListener(
-				new Preference.OnPreferenceChangeListener() {
-					@Override
-					public boolean onPreferenceChange(Preference preference,
-							Object newValue) {
-						String packageName = (String) newValue;
-						PanicResponder.setTriggerPackageName(getActivity(),
-								packageName);
-						showPanicApp(packageName);
-
-						if (packageName.equals(Panic.PACKAGE_NAME_NONE)) {
-							lockPref.setEnabled(false);
-							purgePref.setChecked(false);
-							purgePref.setEnabled(false);
-							uninstallPref.setChecked(false);
-							uninstallPref.setEnabled(false);
-							getActivity().setResult(Activity.RESULT_CANCELED);
-						} else {
-							lockPref.setEnabled(true);
-							purgePref.setEnabled(true);
-							uninstallPref.setEnabled(true);
-						}
-
-						return true;
-					}
-				});
+		panicAppPref.setOnPreferenceChangeListener((preference, newValue) -> {
+			String packageName = (String) newValue;
+			PanicResponder.setTriggerPackageName(getActivity(), packageName);
+			showPanicApp(packageName);
+
+			if (packageName.equals(Panic.PACKAGE_NAME_NONE)) {
+				lockPref.setEnabled(false);
+				purgePref.setChecked(false);
+				purgePref.setEnabled(false);
+				uninstallPref.setChecked(false);
+				uninstallPref.setEnabled(false);
+				getActivity().setResult(Activity.RESULT_CANCELED);
+			} else {
+				lockPref.setEnabled(true);
+				purgePref.setEnabled(true);
+				uninstallPref.setEnabled(true);
+			}
+
+			return true;
+		});
 
 		if (entries.size() <= 1) {
-			panicAppPref.setOnPreferenceClickListener(
-					new Preference.OnPreferenceClickListener() {
-						@Override
-						public boolean onPreferenceClick(
-								Preference preference) {
-							Intent intent = new Intent(Intent.ACTION_VIEW);
-							intent.setData(Uri.parse(
-									"market://details?id=info.guardianproject.ripple"));
-							intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-							if (intent.resolveActivity(
-									getActivity().getPackageManager()) !=
-									null) {
-								startActivity(intent);
-							}
-							return true;
-						}
-					});
+			panicAppPref.setOnPreferenceClickListener(preference -> {
+				Intent intent = new Intent(Intent.ACTION_VIEW);
+				intent.setData(Uri.parse(
+						"market://details?id=info.guardianproject.ripple"));
+				intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+				if (intent.resolveActivity(getActivity().getPackageManager())
+						!= null) {
+					startActivity(intent);
+				}
+				return true;
+			});
 		}
 	}
 
@@ -219,26 +206,15 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
 	}
 
 	private void showOptInDialog() {
-		DialogInterface.OnClickListener okListener =
-				new DialogInterface.OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialog,
-							int which) {
-						PanicResponder.setTriggerPackageName(getActivity());
-						showPanicApp(PanicResponder
-								.getTriggerPackageName(getActivity()));
-						getActivity().setResult(Activity.RESULT_OK);
-					}
-				};
-		DialogInterface.OnClickListener cancelListener =
-				new DialogInterface.OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialog,
-							int which) {
-						getActivity().setResult(Activity.RESULT_CANCELED);
-						getActivity().finish();
-					}
-				};
+		DialogInterface.OnClickListener okListener = (dialog, which) -> {
+			PanicResponder.setTriggerPackageName(getActivity());
+			showPanicApp(PanicResponder.getTriggerPackageName(getActivity()));
+			getActivity().setResult(Activity.RESULT_OK);
+		};
+		DialogInterface.OnClickListener cancelListener = (dialog, which) -> {
+			getActivity().setResult(Activity.RESULT_CANCELED);
+			getActivity().finish();
+		};
 
 		AlertDialog.Builder builder = new AlertDialog.Builder(getContext(),
 				R.style.BriarDialogTheme);
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/panic/PanicResponderActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/panic/PanicResponderActivity.java
index 82534f99f7c07d81d8f3c6d34e42c0e37a945499..dd122e1498b958338de9931e462e13f8e90e1d48 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/panic/PanicResponderActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/panic/PanicResponderActivity.java
@@ -93,18 +93,15 @@ public class PanicResponderActivity extends BriarActivity {
 	}
 
 	private void deleteAllData() {
-		androidExecutor.runOnBackgroundThread(new Runnable() {
-			@Override
-			public void run() {
-				configController.deleteAccount(PanicResponderActivity.this);
-				// TODO somehow delete/shred the database more thoroughly
-				PanicResponder.deleteAllAppData(PanicResponderActivity.this);
-
-				// nothing left to do after everything is deleted,
-				// so still sign out
-				LOG.info("Signing out...");
-				signOut(true);
-			}
+		androidExecutor.runOnBackgroundThread(() -> {
+			configController.deleteAccount(PanicResponderActivity.this);
+			// TODO somehow delete/shred the database more thoroughly
+			PanicResponder.deleteAllAppData(PanicResponderActivity.this);
+
+			// nothing left to do after everything is deleted,
+			// so still sign out
+			LOG.info("Signing out...");
+			signOut(true);
 		});
 	}
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupActivity.java
index 4a8d1c83fa9a96757d7c0532d308b94bdc9dca00..fd77da85dc2762a892bc6a4667ba9e8b6b1a6cb8 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupActivity.java
@@ -11,7 +11,6 @@ import android.support.v7.widget.Toolbar;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
-import android.view.View;
 
 import org.briarproject.bramble.api.contact.ContactId;
 import org.briarproject.bramble.api.db.DbException;
@@ -76,16 +75,12 @@ public class GroupActivity extends
 
 		// Open member list on Toolbar click
 		if (toolbar != null) {
-			toolbar.setOnClickListener(
-					new View.OnClickListener() {
-						@Override
-						public void onClick(View v) {
-							Intent i = new Intent(GroupActivity.this,
-									GroupMemberListActivity.class);
-							i.putExtra(GROUP_ID, groupId.getBytes());
-							startActivity(i);
-						}
-					});
+			toolbar.setOnClickListener(v -> {
+				Intent i1 = new Intent(GroupActivity.this,
+						GroupMemberListActivity.class);
+				i1.putExtra(GROUP_ID, groupId.getBytes());
+				startActivity(i1);
+			});
 		}
 
 		setGroupEnabled(false);
@@ -115,7 +110,7 @@ public class GroupActivity extends
 	}
 
 	@Override
-	protected void onNamedGroupLoaded(final PrivateGroup group) {
+	protected void onNamedGroupLoaded(PrivateGroup group) {
 		setTitle(group.getName());
 		controller.loadLocalAuthor(
 				new UiResultExceptionHandler<LocalAuthor, DbException>(this) {
@@ -149,7 +144,7 @@ public class GroupActivity extends
 	}
 
 	@Override
-	public boolean onOptionsItemSelected(final MenuItem item) {
+	public boolean onOptionsItemSelected(MenuItem item) {
 		switch (item.getItemId()) {
 			case R.id.action_group_member_list:
 				Intent i1 = new Intent(this, GroupMemberListActivity.class);
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupControllerImpl.java
index a3e5c60e26882a4a69e77045f0b3bcc9aa2841c0..911a96da230b60f1743314d2c77ade74a6a36b5b 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupControllerImpl.java
@@ -83,49 +83,32 @@ class GroupControllerImpl extends
 			GroupMessageAddedEvent g = (GroupMessageAddedEvent) e;
 			if (!g.isLocal() && g.getGroupId().equals(getGroupId())) {
 				LOG.info("Group message received, adding...");
-				final GroupMessageItem item =
-						buildItem(g.getHeader(), g.getBody());
-				listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						listener.onItemReceived(item);
-					}
-				});
+				GroupMessageItem item = buildItem(g.getHeader(), g.getBody());
+				listener.runOnUiThreadUnlessDestroyed(
+						() -> listener.onItemReceived(item));
 			}
 		} else if (e instanceof ContactRelationshipRevealedEvent) {
-			final ContactRelationshipRevealedEvent c =
+			ContactRelationshipRevealedEvent c =
 					(ContactRelationshipRevealedEvent) e;
 			if (getGroupId().equals(c.getGroupId())) {
-				listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
+				listener.runOnUiThreadUnlessDestroyed(() ->
 						listener.onContactRelationshipRevealed(c.getMemberId(),
-								c.getContactId(), c.getVisibility());
-					}
-				});
+								c.getContactId(), c.getVisibility()));
 			}
 		} else if (e instanceof GroupInvitationResponseReceivedEvent) {
 			GroupInvitationResponseReceivedEvent g =
 					(GroupInvitationResponseReceivedEvent) e;
-			final GroupInvitationResponse r =
+			GroupInvitationResponse r =
 					(GroupInvitationResponse) g.getResponse();
 			if (getGroupId().equals(r.getShareableId()) && r.wasAccepted()) {
-				listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						listener.onInvitationAccepted(r.getContactId());
-					}
-				});
+				listener.runOnUiThreadUnlessDestroyed(
+						() -> listener.onInvitationAccepted(r.getContactId()));
 			}
 		} else if (e instanceof GroupDissolvedEvent) {
 			GroupDissolvedEvent g = (GroupDissolvedEvent) e;
 			if (getGroupId().equals(g.getGroupId())) {
-				listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						listener.onGroupDissolved();
-					}
-				});
+				listener.runOnUiThreadUnlessDestroyed(
+						() -> listener.onGroupDissolved());
 			}
 		}
 	}
@@ -157,69 +140,58 @@ class GroupControllerImpl extends
 
 	@Override
 	public void loadSharingContacts(
-			final ResultExceptionHandler<Collection<ContactId>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Collection<GroupMember> members =
-							privateGroupManager.getMembers(getGroupId());
-					Collection<ContactId> contactIds = new ArrayList<>();
-					for (GroupMember m : members) {
-						if (m.getContactId() != null)
-							contactIds.add(m.getContactId());
-					}
-					handler.onResult(contactIds);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
+			ResultExceptionHandler<Collection<ContactId>, DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				Collection<GroupMember> members =
+						privateGroupManager.getMembers(getGroupId());
+				Collection<ContactId> contactIds = new ArrayList<>();
+				for (GroupMember m : members) {
+					if (m.getContactId() != null)
+						contactIds.add(m.getContactId());
 				}
+				handler.onResult(contactIds);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
 
 	@Override
-	public void createAndStoreMessage(final String body,
-			@Nullable final GroupMessageItem parentItem,
-			final ResultExceptionHandler<GroupMessageItem, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					LocalAuthor author = identityManager.getLocalAuthor();
-					MessageId parentId = null;
-					MessageId previousMsgId =
-							privateGroupManager.getPreviousMsgId(getGroupId());
-					GroupCount count =
-							privateGroupManager.getGroupCount(getGroupId());
-					long timestamp = count.getLatestMsgTime();
-					if (parentItem != null) parentId = parentItem.getId();
-					timestamp = max(clock.currentTimeMillis(), timestamp + 1);
-					createMessage(body, timestamp, parentId, author,
-							previousMsgId, handler);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+	public void createAndStoreMessage(String body,
+			@Nullable GroupMessageItem parentItem,
+			ResultExceptionHandler<GroupMessageItem, DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				LocalAuthor author = identityManager.getLocalAuthor();
+				MessageId parentId = null;
+				MessageId previousMsgId =
+						privateGroupManager.getPreviousMsgId(getGroupId());
+				GroupCount count =
+						privateGroupManager.getGroupCount(getGroupId());
+				long timestamp = count.getLatestMsgTime();
+				if (parentItem != null) parentId = parentItem.getId();
+				timestamp = max(clock.currentTimeMillis(), timestamp + 1);
+				createMessage(body, timestamp, parentId, author, previousMsgId,
+						handler);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
 
-	private void createMessage(final String body, final long timestamp,
-			final @Nullable MessageId parentId, final LocalAuthor author,
-			final MessageId previousMsgId,
-			final ResultExceptionHandler<GroupMessageItem, DbException> handler) {
-		cryptoExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				LOG.info("Creating group message...");
-				GroupMessage msg = groupMessageFactory
-						.createGroupMessage(getGroupId(), timestamp,
-								parentId, author, body, previousMsgId);
-				storePost(msg, body, handler);
-			}
+	private void createMessage(String body, long timestamp,
+			@Nullable MessageId parentId, LocalAuthor author,
+			MessageId previousMsgId,
+			ResultExceptionHandler<GroupMessageItem, DbException> handler) {
+		cryptoExecutor.execute(() -> {
+			LOG.info("Creating group message...");
+			GroupMessage msg = groupMessageFactory
+					.createGroupMessage(getGroupId(), timestamp,
+							parentId, author, body, previousMsgId);
+			storePost(msg, body, handler);
 		});
 	}
 
@@ -245,18 +217,14 @@ class GroupControllerImpl extends
 
 	@Override
 	public void loadLocalAuthor(
-			final ResultExceptionHandler<LocalAuthor, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					LocalAuthor author = identityManager.getLocalAuthor();
-					handler.onResult(author);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+			ResultExceptionHandler<LocalAuthor, DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				LocalAuthor author = identityManager.getLocalAuthor();
+				handler.onResult(author);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -264,18 +232,14 @@ class GroupControllerImpl extends
 	@Override
 	public void isDissolved(final
 	ResultExceptionHandler<Boolean, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					boolean isDissolved =
-							privateGroupManager.isDissolved(getGroupId());
-					handler.onResult(isDissolved);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				boolean isDissolved =
+						privateGroupManager.isDissolved(getGroupId());
+				handler.onResult(isDissolved);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/JoinMessageItemViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/JoinMessageItemViewHolder.java
index f61f964038e701d1dc06e3154c7dd57fe2d71ac0..c14d46ed27d4535389cafdc8215c6c8f5903a6df 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/JoinMessageItemViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/JoinMessageItemViewHolder.java
@@ -32,7 +32,7 @@ class JoinMessageItemViewHolder
 		else bind((JoinMessageItem) item);
 	}
 
-	private void bindForCreator(final JoinMessageItem item) {
+	private void bindForCreator(JoinMessageItem item) {
 		if (item.isInitial()) {
 			textView.setText(R.string.groups_member_created_you);
 		} else {
@@ -42,8 +42,8 @@ class JoinMessageItemViewHolder
 		}
 	}
 
-	private void bind(final JoinMessageItem item) {
-		final Context ctx = getContext();
+	private void bind(JoinMessageItem item) {
+		Context ctx = getContext();
 
 		if (item.isInitial()) {
 			textView.setText(ctx.getString(R.string.groups_member_created,
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupControllerImpl.java
index 2a694c55a21eb29acf2d6a4e0389cad417ef32c5..2c9f50531de25b7a28c3b66cf121efe0a250a0d2 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupControllerImpl.java
@@ -74,56 +74,43 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl
 	}
 
 	@Override
-	public void createGroup(final String name,
-			final ResultExceptionHandler<GroupId, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					LocalAuthor author = identityManager.getLocalAuthor();
-					createGroupAndMessages(author, name, handler);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+	public void createGroup(String name,
+			ResultExceptionHandler<GroupId, DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				LocalAuthor author = identityManager.getLocalAuthor();
+				createGroupAndMessages(author, name, handler);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
 
-	private void createGroupAndMessages(final LocalAuthor author,
-			final String name,
-			final ResultExceptionHandler<GroupId, DbException> handler) {
-		cryptoExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				LOG.info("Creating group...");
-				PrivateGroup group =
-						groupFactory.createPrivateGroup(name, author);
-				LOG.info("Creating new join announcement...");
-				GroupMessage joinMsg = groupMessageFactory
-						.createJoinMessage(group.getId(),
-								clock.currentTimeMillis(), author);
-				storeGroup(group, joinMsg, handler);
-			}
+	private void createGroupAndMessages(LocalAuthor author, String name,
+			ResultExceptionHandler<GroupId, DbException> handler) {
+		cryptoExecutor.execute(() -> {
+			LOG.info("Creating group...");
+			PrivateGroup group =
+					groupFactory.createPrivateGroup(name, author);
+			LOG.info("Creating new join announcement...");
+			GroupMessage joinMsg =
+					groupMessageFactory.createJoinMessage(group.getId(),
+							clock.currentTimeMillis(), author);
+			storeGroup(group, joinMsg, handler);
 		});
 	}
 
-	private void storeGroup(final PrivateGroup group,
-			final GroupMessage joinMsg,
-			final ResultExceptionHandler<GroupId, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				LOG.info("Adding group to database...");
-				try {
-					groupManager.addPrivateGroup(group, joinMsg, true);
-					handler.onResult(group.getId());
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+	private void storeGroup(PrivateGroup group, GroupMessage joinMsg,
+			ResultExceptionHandler<GroupId, DbException> handler) {
+		runOnDbThread(() -> {
+			LOG.info("Adding group to database...");
+			try {
+				groupManager.addPrivateGroup(group, joinMsg, true);
+				handler.onResult(group.getId());
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -134,75 +121,63 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl
 	}
 
 	@Override
-	public void sendInvitation(final GroupId g,
-			final Collection<ContactId> contactIds, final String message,
-			final ResultExceptionHandler<Void, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					LocalAuthor localAuthor = identityManager.getLocalAuthor();
-					List<Contact> contacts = new ArrayList<>();
-					for (ContactId c : contactIds) {
-						try {
-							contacts.add(contactManager.getContact(c));
-						} catch (NoSuchContactException e) {
-							// Continue
-						}
+	public void sendInvitation(GroupId g, Collection<ContactId> contactIds,
+			String message, ResultExceptionHandler<Void, DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				LocalAuthor localAuthor = identityManager.getLocalAuthor();
+				List<Contact> contacts = new ArrayList<>();
+				for (ContactId c : contactIds) {
+					try {
+						contacts.add(contactManager.getContact(c));
+					} catch (NoSuchContactException e) {
+						// Continue
 					}
-					signInvitations(g, localAuthor, contacts, message, handler);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
 				}
+				signInvitations(g, localAuthor, contacts, message, handler);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
 
-	private void signInvitations(final GroupId g, final LocalAuthor localAuthor,
-			final Collection<Contact> contacts, final String message,
-			final ResultExceptionHandler<Void, DbException> handler) {
-		cryptoExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				long timestamp = clock.currentTimeMillis();
-				List<InvitationContext> contexts = new ArrayList<>();
-				for (Contact c : contacts) {
-					byte[] signature = groupInvitationFactory.signInvitation(c,
-							g, timestamp, localAuthor.getPrivateKey());
-					contexts.add(new InvitationContext(c.getId(), timestamp,
-							signature));
-				}
-				sendInvitations(g, contexts, message, handler);
+	private void signInvitations(GroupId g, LocalAuthor localAuthor,
+			Collection<Contact> contacts, String message,
+			ResultExceptionHandler<Void, DbException> handler) {
+		cryptoExecutor.execute(() -> {
+			long timestamp = clock.currentTimeMillis();
+			List<InvitationContext> contexts = new ArrayList<>();
+			for (Contact c : contacts) {
+				byte[] signature = groupInvitationFactory.signInvitation(c, g,
+						timestamp, localAuthor.getPrivateKey());
+				contexts.add(new InvitationContext(c.getId(), timestamp,
+						signature));
 			}
+			sendInvitations(g, contexts, message, handler);
 		});
 	}
 
-	private void sendInvitations(final GroupId g,
-			final Collection<InvitationContext> contexts, final String message,
-			final ResultExceptionHandler<Void, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					String msg = message.isEmpty() ? null : message;
-					for (InvitationContext context : contexts) {
-						try {
-							groupInvitationManager.sendInvitation(g,
-									context.contactId, msg, context.timestamp,
-									context.signature);
-						} catch (NoSuchContactException e) {
-							// Continue
-						}
+	private void sendInvitations(GroupId g,
+			Collection<InvitationContext> contexts, String message,
+			ResultExceptionHandler<Void, DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				String msg = message.isEmpty() ? null : message;
+				for (InvitationContext context : contexts) {
+					try {
+						groupInvitationManager.sendInvitation(g,
+								context.contactId, msg, context.timestamp,
+								context.signature);
+					} catch (NoSuchContactException e) {
+						// Continue
 					}
-					//noinspection ConstantConditions
-					handler.onResult(null);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
 				}
+				//noinspection ConstantConditions
+				handler.onResult(null);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupFragment.java
index f89db336bb6c7c06099a8f1ef9f9b3cf63d8cf28..c8a6bac35d1e6e1ecf6067ccd7f8451c2d6ed10c 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupFragment.java
@@ -5,16 +5,12 @@ import android.os.Bundle;
 import android.support.design.widget.TextInputLayout;
 import android.text.Editable;
 import android.text.TextWatcher;
-import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ProgressBar;
-import android.widget.TextView;
-import android.widget.TextView.OnEditorActionListener;
 
 import org.briarproject.bramble.util.StringUtils;
 import org.briarproject.briar.R;
@@ -65,24 +61,15 @@ public class CreateGroupFragment extends BaseFragment {
 			public void afterTextChanged(Editable s) {
 			}
 		});
-		nameEntry.setOnEditorActionListener(new OnEditorActionListener() {
-			@Override
-			public boolean onEditorAction(TextView v, int actionId,
-					KeyEvent e) {
-				createGroup();
-				return true;
-			}
+		nameEntry.setOnEditorActionListener((v1, actionId, e) -> {
+			createGroup();
+			return true;
 		});
 
 		nameLayout = (TextInputLayout) v.findViewById(R.id.nameLayout);
 
 		createGroupButton = (Button) v.findViewById(R.id.button);
-		createGroupButton.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				createGroup();
-			}
-		});
+		createGroupButton.setOnClickListener(v1 -> createGroup());
 
 		progress = (ProgressBar) v.findViewById(R.id.progressBar);
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/invitation/GroupInvitationControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/invitation/GroupInvitationControllerImpl.java
index b3b3f4c59093aedb38240b2a964ab59bfbedd587..3e8c5a9415385023dc07188a3e93a940ae7d0e59 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/invitation/GroupInvitationControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/invitation/GroupInvitationControllerImpl.java
@@ -64,21 +64,16 @@ class GroupInvitationControllerImpl
 	}
 
 	@Override
-	public void respondToInvitation(final GroupInvitationItem item,
-			final boolean accept,
-			final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					PrivateGroup g = item.getShareable();
-					ContactId c = item.getCreator().getId();
-					groupInvitationManager.respondToInvitation(c, g, accept);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+	public void respondToInvitation(GroupInvitationItem item, boolean accept,
+			ExceptionHandler<DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				PrivateGroup g = item.getShareable();
+				ContactId c = item.getCreator().getId();
+				groupInvitationManager.respondToInvitation(c, g, accept);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/invitation/GroupInvitationViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/invitation/GroupInvitationViewHolder.java
index a270de3690ead6d1e5d36d5bf3b9e4c33aeec38f..fae57b85e4a3dc4aa069fcdc7f7b1699daa285e2 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/invitation/GroupInvitationViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/invitation/GroupInvitationViewHolder.java
@@ -17,8 +17,8 @@ class GroupInvitationViewHolder
 	}
 
 	@Override
-	public void onBind(@Nullable final GroupInvitationItem item,
-			final InvitationClickListener<GroupInvitationItem> listener) {
+	public void onBind(@Nullable GroupInvitationItem item,
+			InvitationClickListener<GroupInvitationItem> listener) {
 		super.onBind(item, listener);
 		if (item == null) return;
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupListControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupListControllerImpl.java
index cbe85631eba1c57ae514aae84b66c7ec0eda04c8..8824923fb10ca92f6d8fda44804cd0010e0798ba 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupListControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupListControllerImpl.java
@@ -119,120 +119,85 @@ class GroupListControllerImpl extends DbControllerImpl
 		}
 	}
 
-	private void onGroupMessageAdded(final GroupMessageHeader h) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onGroupMessageAdded(h);
-			}
-		});
+	private void onGroupMessageAdded(GroupMessageHeader h) {
+		listener.runOnUiThreadUnlessDestroyed(
+				() -> listener.onGroupMessageAdded(h));
 	}
 
 	private void onGroupInvitationReceived() {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onGroupInvitationReceived();
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(
+				() -> listener.onGroupInvitationReceived());
 	}
 
-	private void onGroupAdded(final GroupId g) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onGroupAdded(g);
-			}
-		});
+	private void onGroupAdded(GroupId g) {
+		listener.runOnUiThreadUnlessDestroyed(() -> listener.onGroupAdded(g));
 	}
 
-	private void onGroupRemoved(final GroupId g) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onGroupRemoved(g);
-			}
-		});
+	private void onGroupRemoved(GroupId g) {
+		listener.runOnUiThreadUnlessDestroyed(() -> listener.onGroupRemoved(g));
 	}
 
-	private void onGroupDissolved(final GroupId g) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onGroupDissolved(g);
-			}
-		});
+	private void onGroupDissolved(GroupId g) {
+		listener.runOnUiThreadUnlessDestroyed(
+				() -> listener.onGroupDissolved(g));
 	}
 
 	@Override
 	public void loadGroups(
-			final ResultExceptionHandler<Collection<GroupItem>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					Collection<PrivateGroup> groups =
-							groupManager.getPrivateGroups();
-					List<GroupItem> items = new ArrayList<>(groups.size());
-					for (PrivateGroup g : groups) {
-						try {
-							GroupId id = g.getId();
-							GroupCount count = groupManager.getGroupCount(id);
-							boolean dissolved = groupManager.isDissolved(id);
-							items.add(new GroupItem(g, count, dissolved));
-						} catch (NoSuchGroupException e) {
-							// Continue
-						}
+			ResultExceptionHandler<Collection<GroupItem>, DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				Collection<PrivateGroup> groups =
+						groupManager.getPrivateGroups();
+				List<GroupItem> items = new ArrayList<>(groups.size());
+				for (PrivateGroup g : groups) {
+					try {
+						GroupId id = g.getId();
+						GroupCount count = groupManager.getGroupCount(id);
+						boolean dissolved = groupManager.isDissolved(id);
+						items.add(new GroupItem(g, count, dissolved));
+					} catch (NoSuchGroupException e) {
+						// Continue
 					}
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading groups took " + duration + " ms");
-					handler.onResult(items);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
 				}
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading groups took " + duration + " ms");
+				handler.onResult(items);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
 
 	@Override
-	public void removeGroup(final GroupId g,
-			final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					groupManager.removePrivateGroup(g);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Removing group took " + duration + " ms");
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+	public void removeGroup(GroupId g, ExceptionHandler<DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				groupManager.removePrivateGroup(g);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Removing group took " + duration + " ms");
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
 
 	@Override
 	public void loadAvailableGroups(
-			final ResultExceptionHandler<Integer, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					handler.onResult(
-							groupInvitationManager.getInvitations().size());
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+			ResultExceptionHandler<Integer, DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				handler.onResult(
+						groupInvitationManager.getInvitations().size());
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupListFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupListFragment.java
index 9fbed643c539cc9271ee8c7e0927054243704538..fbcce8cf5a9c8818fe4a93ee169e07a65741e269 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupListFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupListFragment.java
@@ -113,7 +113,7 @@ public class GroupListFragment extends BaseFragment implements
 	}
 
 	@Override
-	public boolean onOptionsItemSelected(final MenuItem item) {
+	public boolean onOptionsItemSelected(MenuItem item) {
 		switch (item.getItemId()) {
 			case R.id.action_add_group:
 				Intent i = new Intent(getContext(), CreateGroupActivity.class);
@@ -184,7 +184,7 @@ public class GroupListFragment extends BaseFragment implements
 	}
 
 	private void loadGroups() {
-		final int revision = adapter.getRevision();
+		int revision = adapter.getRevision();
 		controller.loadGroups(
 				new UiResultExceptionHandler<Collection<GroupItem>, DbException>(
 						this) {
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupViewHolder.java
index c137ad072d2b463ce10e453b0e78fcb0b3d5c495..15219e5859316ad6b2a74cfc659e91178cb4b266 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupViewHolder.java
@@ -4,7 +4,6 @@ import android.content.Context;
 import android.content.Intent;
 import android.support.v7.widget.RecyclerView;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.TextView;
@@ -51,8 +50,8 @@ class GroupViewHolder extends RecyclerView.ViewHolder {
 		remove = (Button) v.findViewById(R.id.removeButton);
 	}
 
-	void bindView(final Context ctx, final GroupItem group,
-			final OnGroupRemoveClickListener listener) {
+	void bindView(Context ctx, GroupItem group,
+			OnGroupRemoveClickListener listener) {
 		// Avatar
 		avatar.setText(group.getName().substring(0, 1));
 		avatar.setBackgroundBytes(group.getId().getBytes());
@@ -107,25 +106,17 @@ class GroupViewHolder extends RecyclerView.ViewHolder {
 			status
 					.setText(ctx.getString(R.string.groups_group_is_dissolved));
 			status.setVisibility(VISIBLE);
-			remove.setOnClickListener(new OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					listener.onGroupRemoveClick(group);
-				}
-			});
+			remove.setOnClickListener(v -> listener.onGroupRemoveClick(group));
 			remove.setVisibility(VISIBLE);
 		}
 
 		// Open Group on Click
-		layout.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				Intent i = new Intent(ctx, GroupActivity.class);
-				GroupId id = group.getId();
-				i.putExtra(GROUP_ID, id.getBytes());
-				i.putExtra(GROUP_NAME, group.getName());
-				ctx.startActivity(i);
-			}
+		layout.setOnClickListener(v -> {
+			Intent i = new Intent(ctx, GroupActivity.class);
+			GroupId id = group.getId();
+			i.putExtra(GROUP_ID, id.getBytes());
+			i.putExtra(GROUP_NAME, group.getName());
+			ctx.startActivity(i);
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/memberlist/GroupMemberListActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/memberlist/GroupMemberListActivity.java
index de7776da6dc7b0d312b28f590c675849f32c59d5..e893ecf888db4a0dc48862c0e62ed22e9a9f4156 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/memberlist/GroupMemberListActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/memberlist/GroupMemberListActivity.java
@@ -38,7 +38,7 @@ public class GroupMemberListActivity extends BriarActivity {
 	}
 
 	@Override
-	public void onCreate(@Nullable final Bundle state) {
+	public void onCreate(@Nullable Bundle state) {
 		super.onCreate(state);
 
 		setContentView(R.layout.activity_sharing_status);
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/memberlist/GroupMemberListControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/memberlist/GroupMemberListControllerImpl.java
index 69bc9ac519d322172b7dd18f5bb3e5eca21e8d8a..5dcf6c5995d8338a5ee5fa36a88e0c3e3f835223 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/memberlist/GroupMemberListControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/memberlist/GroupMemberListControllerImpl.java
@@ -40,28 +40,24 @@ class GroupMemberListControllerImpl extends DbControllerImpl
 	}
 
 	@Override
-	public void loadMembers(final GroupId groupId, final
+	public void loadMembers(GroupId groupId,
 			ResultExceptionHandler<Collection<MemberListItem>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Collection<MemberListItem> items = new ArrayList<>();
-					Collection<GroupMember> members =
-							privateGroupManager.getMembers(groupId);
-					for (GroupMember m : members) {
-						ContactId c = m.getContactId();
-						boolean online = false;
-						if (c != null)
-							online = connectionRegistry.isConnected(c);
-						items.add(new MemberListItem(m, online));
-					}
-					handler.onResult(items);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
+		runOnDbThread(() -> {
+			try {
+				Collection<MemberListItem> items = new ArrayList<>();
+				Collection<GroupMember> members =
+						privateGroupManager.getMembers(groupId);
+				for (GroupMember m : members) {
+					ContactId c = m.getContactId();
+					boolean online = false;
+					if (c != null)
+						online = connectionRegistry.isConnected(c);
+					items.add(new MemberListItem(m, online));
 				}
+				handler.onResult(items);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsActivity.java
index 778802f72616035f0084b0dd118bb998f130b6c8..79a287755bc75f1d33bdd19797c96e2abf60124a 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsActivity.java
@@ -1,6 +1,5 @@
 package org.briarproject.briar.android.privategroup.reveal;
 
-import android.content.DialogInterface;
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.annotation.LayoutRes;
@@ -110,19 +109,8 @@ public class RevealContactsActivity extends ContactSelectorActivity
 		new AlertDialog.Builder(this, R.style.OnboardingDialogTheme)
 				.setMessage(getString(R.string.groups_reveal_dialog_message))
 				.setNeutralButton(R.string.got_it,
-						new DialogInterface.OnClickListener() {
-							@Override
-							public void onClick(DialogInterface dialog,
-									int which) {
-								dialog.cancel();
-							}
-						})
-				.setOnCancelListener(new DialogInterface.OnCancelListener() {
-					@Override
-					public void onCancel(DialogInterface dialog) {
-						onboardingShown();
-					}
-				})
+						(dialog, which) -> dialog.cancel())
+				.setOnCancelListener(dialog -> onboardingShown())
 				.show();
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsControllerImpl.java
index 279b80710a9314f566f176fcd7150f189013a83d..11b65fa437c1cd7f736d2729d9d40d2dd3c673f9 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsControllerImpl.java
@@ -59,21 +59,14 @@ class RevealContactsControllerImpl extends DbControllerImpl
 	}
 
 	@Override
-	public void loadContacts(final GroupId g,
-			final Collection<ContactId> selection,
-			final ResultExceptionHandler<Collection<RevealableContactItem>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Collection<RevealableContactItem> items =
-							getItems(g, selection);
-					handler.onResult(items);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+	public void loadContacts(GroupId g, Collection<ContactId> selection,
+			ResultExceptionHandler<Collection<RevealableContactItem>, DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				handler.onResult(getItems(g, selection));
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -104,62 +97,52 @@ class RevealContactsControllerImpl extends DbControllerImpl
 
 	@Override
 	public void isOnboardingNeeded(
-			final ResultExceptionHandler<Boolean, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Settings settings =
-							settingsManager.getSettings(SETTINGS_NAMESPACE);
-					handler.onResult(
-							settings.getBoolean(SHOW_ONBOARDING_REVEAL_CONTACTS,
-									true));
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
-
+			ResultExceptionHandler<Boolean, DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				Settings settings =
+						settingsManager.getSettings(SETTINGS_NAMESPACE);
+				handler.onResult(
+						settings.getBoolean(SHOW_ONBOARDING_REVEAL_CONTACTS,
+								true));
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
+
 		});
 	}
 
 	@Override
 	public void onboardingShown(ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Settings settings = new Settings();
-					settings.putBoolean(SHOW_ONBOARDING_REVEAL_CONTACTS, false);
-					settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		runOnDbThread(() -> {
+			try {
+				Settings settings = new Settings();
+				settings.putBoolean(SHOW_ONBOARDING_REVEAL_CONTACTS, false);
+				settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	@Override
-	public void reveal(final GroupId g, final Collection<ContactId> contacts,
-			final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				for (ContactId c : contacts) {
-					try {
-						groupInvitationManager.revealRelationship(c, g);
-					} catch (ProtocolStateException e) {
-						// action is outdated, move to next contact
-						if (LOG.isLoggable(INFO))
-							LOG.log(INFO, e.toString(), e);
-					} catch (DbException e) {
-						if (LOG.isLoggable(WARNING))
-							LOG.log(WARNING, e.toString(), e);
-						handler.onException(e);
-						break;
-					}
+	public void reveal(GroupId g, Collection<ContactId> contacts,
+			ExceptionHandler<DbException> handler) {
+		runOnDbThread(() -> {
+			for (ContactId c : contacts) {
+				try {
+					groupInvitationManager.revealRelationship(c, g);
+				} catch (ProtocolStateException e) {
+					// action is outdated, move to next contact
+					if (LOG.isLoggable(INFO))
+						LOG.log(INFO, e.toString(), e);
+				} catch (DbException e) {
+					if (LOG.isLoggable(WARNING))
+						LOG.log(WARNING, e.toString(), e);
+					handler.onException(e);
+					break;
 				}
 			}
 		});
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/reporting/BriarReportPrimer.java b/briar-android/src/main/java/org/briarproject/briar/android/reporting/BriarReportPrimer.java
index 4d08fcb6a665a633d99c8c8c7d48862405d7c107..f74647eba6a1d035bf0aa6da288b57a8e14a077c 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/reporting/BriarReportPrimer.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/reporting/BriarReportPrimer.java
@@ -256,12 +256,9 @@ public class BriarReportPrimer implements ReportPrimer {
 			Looper.prepare();
 			Handler handler = new Handler();
 			handler.post(runnable);
-			handler.post(new Runnable() {
-				@Override
-				public void run() {
-					Looper looper = Looper.myLooper();
-					if (looper != null) looper.quit();
-				}
+			handler.post(() -> {
+				Looper looper = Looper.myLooper();
+				if (looper != null) looper.quit();
 			});
 			Looper.loop();
 		}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/reporting/DevReportActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/reporting/DevReportActivity.java
index 82c21c0891fe84576f8e2104bb8703b84b0e69ea..2091e65b612d6936fe9c10875ed3581c0b3513de 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/reporting/DevReportActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/reporting/DevReportActivity.java
@@ -1,6 +1,5 @@
 package org.briarproject.briar.android.reporting;
 
-import android.content.Context;
 import android.content.res.Configuration;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -37,6 +36,7 @@ import java.util.logging.Logger;
 import static android.view.View.GONE;
 import static android.view.View.INVISIBLE;
 import static android.view.View.VISIBLE;
+import static android.view.inputmethod.InputMethodManager.SHOW_FORCED;
 import static java.util.logging.Level.WARNING;
 import static org.acra.ACRAConstants.EXTRA_REPORT_FILE;
 import static org.acra.ReportField.ANDROID_VERSION;
@@ -93,7 +93,7 @@ public class DevReportActivity extends BaseCrashReportDialog
 		Toolbar tb = (Toolbar) findViewById(R.id.toolbar);
 		getDelegate().setSupportActionBar(tb);
 
-		final View requestReport = findViewById(R.id.request_report);
+		View requestReport = findViewById(R.id.request_report);
 		userCommentView = (EditText) findViewById(R.id.user_comment);
 		userEmailView = (EditText) findViewById(R.id.user_email);
 		includeDebugReport = (CheckBox) findViewById(R.id.include_debug_report);
@@ -115,37 +115,22 @@ public class DevReportActivity extends BaseCrashReportDialog
 			includeDebugReport.setChecked(true);
 		}
 
-		findViewById(R.id.acceptButton).setOnClickListener(
-				new View.OnClickListener() {
-					@Override
-					public void onClick(View v) {
-						reviewing = true;
-						requestReport.setVisibility(GONE);
-						((InputMethodManager) getSystemService(
-								Context.INPUT_METHOD_SERVICE))
-								.showSoftInput(userCommentView,
-										InputMethodManager.SHOW_FORCED);
-					}
-				});
-		findViewById(R.id.declineButton).setOnClickListener(
-				new View.OnClickListener() {
-					@Override
-					public void onClick(View v) {
-						closeReport();
-					}
-				});
-		chevron.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				boolean show =
-						chevron.getText().equals(getString(R.string.show));
-				if (show) {
-					chevron.setText(R.string.hide);
-					refresh();
-				} else {
-					chevron.setText(R.string.show);
-					report.setVisibility(GONE);
-				}
+		findViewById(R.id.acceptButton).setOnClickListener(v -> {
+			reviewing = true;
+			requestReport.setVisibility(GONE);
+			((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE))
+					.showSoftInput(userCommentView, SHOW_FORCED);
+		});
+		findViewById(R.id.declineButton).setOnClickListener(v -> closeReport());
+		chevron.setOnClickListener(v -> {
+			boolean show =
+					chevron.getText().equals(getString(R.string.show));
+			if (show) {
+				chevron.setText(R.string.hide);
+				refresh();
+			} else {
+				chevron.setText(R.string.show);
+				report.setVisibility(GONE);
 			}
 		});
 
@@ -185,7 +170,7 @@ public class DevReportActivity extends BaseCrashReportDialog
 	}
 
 	@Override
-	public boolean onOptionsItemSelected(final MenuItem item) {
+	public boolean onOptionsItemSelected(MenuItem item) {
 		// Handle presses on the action bar items
 		switch (item.getItemId()) {
 			case android.R.id.home:
@@ -258,8 +243,7 @@ public class DevReportActivity extends BaseCrashReportDialog
 			protected CrashReportData doInBackground(Void... args) {
 				File reportFile = (File) getIntent().getSerializableExtra(
 						EXTRA_REPORT_FILE);
-				final CrashReportPersister persister =
-						new CrashReportPersister();
+				CrashReportPersister persister = new CrashReportPersister();
 				try {
 					return persister.load(reportFile);
 				} catch (IOException e) {
@@ -308,8 +292,7 @@ public class DevReportActivity extends BaseCrashReportDialog
 		userEmailView.setEnabled(false);
 		sendReport.setEnabled(false);
 		progress.setVisibility(VISIBLE);
-		final boolean includeReport =
-				!isFeedback() || includeDebugReport.isChecked();
+		boolean includeReport = !isFeedback() || includeDebugReport.isChecked();
 		new AsyncTask<Void, Void, Boolean>() {
 
 			@Override
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java
index cff44bb8a560806031fcffffb329dcc0abcee98b..4c0b80840aa51ee1b54427af08441b4d8f316770 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java
@@ -141,54 +141,39 @@ public class SettingsFragment extends PreferenceFragmentCompat
 			notifyLockscreen.setVisible(true);
 			notifyLockscreen.setOnPreferenceChangeListener(this);
 		}
-		notifySound.setOnPreferenceClickListener(
-				new Preference.OnPreferenceClickListener() {
-					@Override
-					public boolean onPreferenceClick(Preference preference) {
-						String title =
-								getString(R.string.choose_ringtone_title);
-						Intent i = new Intent(ACTION_RINGTONE_PICKER);
-						i.putExtra(EXTRA_RINGTONE_TYPE, TYPE_NOTIFICATION);
-						i.putExtra(EXTRA_RINGTONE_TITLE, title);
-						i.putExtra(EXTRA_RINGTONE_DEFAULT_URI,
-								DEFAULT_NOTIFICATION_URI);
-						i.putExtra(EXTRA_RINGTONE_SHOW_SILENT, true);
-						if (settings.getBoolean(PREF_NOTIFY_SOUND, true)) {
-							Uri uri;
-							String ringtoneUri =
-									settings.get(PREF_NOTIFY_RINGTONE_URI);
-							if (StringUtils.isNullOrEmpty(ringtoneUri))
-								uri = DEFAULT_NOTIFICATION_URI;
-							else uri = Uri.parse(ringtoneUri);
-							i.putExtra(EXTRA_RINGTONE_EXISTING_URI, uri);
-						}
-						startActivityForResult(i, REQUEST_RINGTONE);
-						return true;
-					}
-				});
+		notifySound.setOnPreferenceClickListener(preference -> {
+			String title = getString(R.string.choose_ringtone_title);
+			Intent i = new Intent(ACTION_RINGTONE_PICKER);
+			i.putExtra(EXTRA_RINGTONE_TYPE, TYPE_NOTIFICATION);
+			i.putExtra(EXTRA_RINGTONE_TITLE, title);
+			i.putExtra(EXTRA_RINGTONE_DEFAULT_URI, DEFAULT_NOTIFICATION_URI);
+			i.putExtra(EXTRA_RINGTONE_SHOW_SILENT, true);
+			if (settings.getBoolean(PREF_NOTIFY_SOUND, true)) {
+				Uri uri;
+				String ringtoneUri = settings.get(PREF_NOTIFY_RINGTONE_URI);
+				if (StringUtils.isNullOrEmpty(ringtoneUri))
+					uri = DEFAULT_NOTIFICATION_URI;
+				else uri = Uri.parse(ringtoneUri);
+				i.putExtra(EXTRA_RINGTONE_EXISTING_URI, uri);
+			}
+			startActivityForResult(i, REQUEST_RINGTONE);
+			return true;
+		});
 
 		findPreference("pref_key_send_feedback").setOnPreferenceClickListener(
-				new Preference.OnPreferenceClickListener() {
-					@Override
-					public boolean onPreferenceClick(Preference preference) {
-						triggerFeedback();
-						return true;
-					}
+				preference -> {
+					triggerFeedback();
+					return true;
 				});
 
 		Preference testData = findPreference("pref_key_test_data");
 		if (IS_DEBUG_BUILD) {
-			testData.setOnPreferenceClickListener(
-					new Preference.OnPreferenceClickListener() {
-						@Override
-						public boolean onPreferenceClick(
-								Preference preference) {
-							LOG.info("Creating test data");
-							testDataCreator.createTestData();
-							getActivity().finish();
-							return true;
-						}
-					});
+			testData.setOnPreferenceClickListener(preference -> {
+				LOG.info("Creating test data");
+				testDataCreator.createTestData();
+				getActivity().finish();
+				return true;
+			});
 		} else {
 			testData.setVisible(false);
 		}
@@ -209,83 +194,68 @@ public class SettingsFragment extends PreferenceFragmentCompat
 	}
 
 	private void loadSettings() {
-		listener.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
-					Settings btSettings =
-							settingsManager.getSettings(BT_NAMESPACE);
-					Settings torSettings =
-							settingsManager.getSettings(TOR_NAMESPACE);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading settings took " + duration + " ms");
-					boolean btSetting =
-							btSettings.getBoolean(PREF_BT_ENABLE, false);
-					int torSetting = torSettings.getInt(PREF_TOR_NETWORK,
-							PREF_TOR_NETWORK_ALWAYS);
-					displaySettings(btSetting, torSetting);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		listener.runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
+				Settings btSettings = settingsManager.getSettings(BT_NAMESPACE);
+				Settings torSettings =
+						settingsManager.getSettings(TOR_NAMESPACE);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading settings took " + duration + " ms");
+				boolean btSetting =
+						btSettings.getBoolean(PREF_BT_ENABLE, false);
+				int torSetting = torSettings.getInt(PREF_TOR_NETWORK,
+						PREF_TOR_NETWORK_ALWAYS);
+				displaySettings(btSetting, torSetting);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
-	private void displaySettings(final boolean btSetting,
-			final int torSetting) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				enableBluetooth.setValue(Boolean.toString(btSetting));
-				torNetwork.setValue(Integer.toString(torSetting));
-
-				notifyPrivateMessages.setChecked(settings.getBoolean(
-						PREF_NOTIFY_PRIVATE, true));
-
-				notifyGroupMessages.setChecked(settings.getBoolean(
-						PREF_NOTIFY_GROUP, true));
-
-				notifyForumPosts.setChecked(settings.getBoolean(
-						PREF_NOTIFY_FORUM, true));
-
-				notifyBlogPosts.setChecked(settings.getBoolean(
-						PREF_NOTIFY_BLOG, true));
-
-				notifyVibration.setChecked(settings.getBoolean(
-						PREF_NOTIFY_VIBRATION, true));
-
-				notifyLockscreen.setChecked(settings.getBoolean(
-						PREF_NOTIFY_LOCK_SCREEN, false));
-
-				String text;
-				if (settings.getBoolean(PREF_NOTIFY_SOUND, true)) {
-					String ringtoneName =
-							settings.get(PREF_NOTIFY_RINGTONE_NAME);
-					if (StringUtils.isNullOrEmpty(ringtoneName)) {
-						text = getString(R.string.notify_sound_setting_default);
-					} else {
-						text = ringtoneName;
-					}
+	private void displaySettings(boolean btSetting, int torSetting) {
+		listener.runOnUiThreadUnlessDestroyed(() -> {
+			enableBluetooth.setValue(Boolean.toString(btSetting));
+			torNetwork.setValue(Integer.toString(torSetting));
+
+			notifyPrivateMessages.setChecked(settings.getBoolean(
+					PREF_NOTIFY_PRIVATE, true));
+
+			notifyGroupMessages.setChecked(settings.getBoolean(
+					PREF_NOTIFY_GROUP, true));
+
+			notifyForumPosts.setChecked(settings.getBoolean(
+					PREF_NOTIFY_FORUM, true));
+
+			notifyBlogPosts.setChecked(settings.getBoolean(
+					PREF_NOTIFY_BLOG, true));
+
+			notifyVibration.setChecked(settings.getBoolean(
+					PREF_NOTIFY_VIBRATION, true));
+
+			notifyLockscreen.setChecked(settings.getBoolean(
+					PREF_NOTIFY_LOCK_SCREEN, false));
+
+			String text;
+			if (settings.getBoolean(PREF_NOTIFY_SOUND, true)) {
+				String ringtoneName = settings.get(PREF_NOTIFY_RINGTONE_NAME);
+				if (StringUtils.isNullOrEmpty(ringtoneName)) {
+					text = getString(R.string.notify_sound_setting_default);
 				} else {
-					text = getString(R.string.notify_sound_setting_disabled);
+					text = ringtoneName;
 				}
-				notifySound.setSummary(text);
+			} else {
+				text = getString(R.string.notify_sound_setting_disabled);
 			}
+			notifySound.setSummary(text);
 		});
 	}
 
 	private void triggerFeedback() {
-		androidExecutor.runOnBackgroundThread(new Runnable() {
-			@Override
-			public void run() {
-				ACRA.getErrorReporter().handleException(new UserFeedback(),
-						false);
-			}
-		});
+		androidExecutor.runOnBackgroundThread(() -> ACRA.getErrorReporter()
+				.handleException(new UserFeedback(), false));
 	}
 
 	@Override
@@ -330,60 +300,48 @@ public class SettingsFragment extends PreferenceFragmentCompat
 		else eventBus.broadcast(new DisableBluetoothEvent());
 	}
 
-	private void storeTorSettings(final int torSetting) {
-		listener.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Settings s = new Settings();
-					s.putInt(PREF_TOR_NETWORK, torSetting);
-					long now = System.currentTimeMillis();
-					settingsManager.mergeSettings(s, TOR_NAMESPACE);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Merging settings took " + duration + " ms");
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+	private void storeTorSettings(int torSetting) {
+		listener.runOnDbThread(() -> {
+			try {
+				Settings s = new Settings();
+				s.putInt(PREF_TOR_NETWORK, torSetting);
+				long now = System.currentTimeMillis();
+				settingsManager.mergeSettings(s, TOR_NAMESPACE);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Merging settings took " + duration + " ms");
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
-	private void storeBluetoothSettings(final boolean btSetting) {
-		listener.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Settings s = new Settings();
-					s.putBoolean(PREF_BT_ENABLE, btSetting);
-					long now = System.currentTimeMillis();
-					settingsManager.mergeSettings(s, BT_NAMESPACE);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Merging settings took " + duration + " ms");
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+	private void storeBluetoothSettings(boolean btSetting) {
+		listener.runOnDbThread(() -> {
+			try {
+				Settings s = new Settings();
+				s.putBoolean(PREF_BT_ENABLE, btSetting);
+				long now = System.currentTimeMillis();
+				settingsManager.mergeSettings(s, BT_NAMESPACE);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Merging settings took " + duration + " ms");
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
-	private void storeSettings(final Settings settings) {
-		listener.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Merging settings took " + duration + " ms");
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+	private void storeSettings(Settings settings) {
+		listener.runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Merging settings took " + duration + " ms");
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/BaseMessageFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/BaseMessageFragment.java
index 67532a44a0ba2f854be1add6a49bd937e8c4b25a..026498b12facc43a1aa3e4612972e2db09ff41ee 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/BaseMessageFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/BaseMessageFragment.java
@@ -64,7 +64,7 @@ public abstract class BaseMessageFragment extends BaseFragment
 	}
 
 	@Override
-	public boolean onOptionsItemSelected(final MenuItem item) {
+	public boolean onOptionsItemSelected(MenuItem item) {
 		switch (item.getItemId()) {
 			case android.R.id.home:
 				if (message.isKeyboardOpen()) message.hideSoftKeyboard();
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/BlogInvitationControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/BlogInvitationControllerImpl.java
index 66adb424c4b5ae853740d9c30d1ca81177d1296b..6cacc3c343ce489368a1a50cb447e97a7cde7d81 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/BlogInvitationControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/BlogInvitationControllerImpl.java
@@ -58,23 +58,18 @@ class BlogInvitationControllerImpl
 	}
 
 	@Override
-	public void respondToInvitation(final SharingInvitationItem item,
-			final boolean accept,
-			final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Blog f = (Blog) item.getShareable();
-					for (Contact c : item.getNewSharers()) {
-						// TODO: What happens if a contact has been removed?
-						blogSharingManager.respondToInvitation(f, c, accept);
-					}
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
+	public void respondToInvitation(SharingInvitationItem item, boolean accept,
+			ExceptionHandler<DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				Blog f = (Blog) item.getShareable();
+				for (Contact c : item.getNewSharers()) {
+					// TODO: What happens if a contact has been removed?
+					blogSharingManager.respondToInvitation(f, c, accept);
 				}
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ForumInvitationControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ForumInvitationControllerImpl.java
index 14e669f42435b1d2dc2f2ff240734579dd674d32..4ae8a08a113bd70d6f5058d469d6917eabc73771 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ForumInvitationControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ForumInvitationControllerImpl.java
@@ -59,23 +59,18 @@ class ForumInvitationControllerImpl
 	}
 
 	@Override
-	public void respondToInvitation(final SharingInvitationItem item,
-			final boolean accept,
-			final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Forum f = (Forum) item.getShareable();
-					for (Contact c : item.getNewSharers()) {
-						// TODO: What happens if a contact has been removed?
-						forumSharingManager.respondToInvitation(f, c, accept);
-					}
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
+	public void respondToInvitation(SharingInvitationItem item, boolean accept,
+			ExceptionHandler<DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				Forum f = (Forum) item.getShareable();
+				for (Contact c : item.getNewSharers()) {
+					// TODO: What happens if a contact has been removed?
+					forumSharingManager.respondToInvitation(f, c, accept);
 				}
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationActivity.java
index 6f57eed9fe3c942f1be1f26fdfe4ba1f5b1cc178..bc755d43a32f383adb3f76968cf88bfea428ea2f 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationActivity.java
@@ -85,8 +85,8 @@ public abstract class InvitationActivity<I extends InvitationItem>
 	}
 
 	@Override
-	public void loadInvitations(final boolean clear) {
-		final int revision = adapter.getRevision();
+	public void loadInvitations(boolean clear) {
+		int revision = adapter.getRevision();
 		getController().loadInvitations(clear,
 				new UiResultExceptionHandler<Collection<I>, DbException>(
 						this) {
@@ -104,8 +104,7 @@ public abstract class InvitationActivity<I extends InvitationItem>
 
 	abstract protected InvitationController<I> getController();
 
-	protected void respondToInvitation(final I item,
-			final boolean accept) {
+	protected void respondToInvitation(I item, boolean accept) {
 		getController().respondToInvitation(item, accept,
 				new UiExceptionHandler<DbException>(this) {
 					@Override
@@ -121,22 +120,19 @@ public abstract class InvitationActivity<I extends InvitationItem>
 	@StringRes
 	abstract protected int getDeclineRes();
 
-	protected void displayInvitations(final int revision,
-			final Collection<I> invitations, final boolean clear) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (invitations.isEmpty()) {
-					LOG.info("No more invitations available, finishing");
-					supportFinishAfterTransition();
-				} else if (revision == adapter.getRevision()) {
-					adapter.incrementRevision();
-					if (clear) adapter.setItems(invitations);
-					else adapter.addAll(invitations);
-				} else {
-					LOG.info("Concurrent update, reloading");
-					loadInvitations(clear);
-				}
+	protected void displayInvitations(int revision, Collection<I> invitations,
+			boolean clear) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (invitations.isEmpty()) {
+				LOG.info("No more invitations available, finishing");
+				supportFinishAfterTransition();
+			} else if (revision == adapter.getRevision()) {
+				adapter.incrementRevision();
+				if (clear) adapter.setItems(invitations);
+				else adapter.addAll(invitations);
+			} else {
+				LOG.info("Concurrent update, reloading");
+				loadInvitations(clear);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationAdapter.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationAdapter.java
index 1b3a4fecc64e066e6398469dfc6b95deebdc8228..5db6a1f0ce14c399140ed0fac0945b27e4c31f08 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationAdapter.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationAdapter.java
@@ -27,7 +27,7 @@ public abstract class InvitationAdapter<I extends InvitationItem, VH extends Inv
 
 	@Override
 	public void onBindViewHolder(VH ui, int position) {
-		final I item = getItemAt(position);
+		I item = getItemAt(position);
 		if (item == null) return;
 		ui.onBind(item, listener);
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationControllerImpl.java
index 0c0a9f426d73ada6b586a386edc39f39c8bb5575..ad584b03dab5172ab0623ec97d44b3b3217ff720 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationControllerImpl.java
@@ -91,25 +91,20 @@ public abstract class InvitationControllerImpl<I extends InvitationItem>
 	protected abstract ClientId getShareableClientId();
 
 	@Override
-	public void loadInvitations(final boolean clear,
-			final ResultExceptionHandler<Collection<I>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				Collection<I> invitations = new ArrayList<>();
-				try {
-					long now = System.currentTimeMillis();
-					invitations.addAll(getInvitations());
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info(
-								"Loading invitations took " + duration + " ms");
-					handler.onResult(invitations);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+	public void loadInvitations(boolean clear,
+			ResultExceptionHandler<Collection<I>, DbException> handler) {
+		runOnDbThread(() -> {
+			Collection<I> invitations = new ArrayList<>();
+			try {
+				long now = System.currentTimeMillis();
+				invitations.addAll(getInvitations());
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading invitations took " + duration + " ms");
+				handler.onResult(invitations);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationViewHolder.java
index 80adcfce29bc6bd979aa34e836b92dd8d6eaddb1..ef21497ce1c56832185c44791f5f21c18948ec3d 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationViewHolder.java
@@ -38,8 +38,7 @@ public class InvitationViewHolder<I extends InvitationItem>
 	}
 
 	@CallSuper
-	public void onBind(@Nullable final I item,
-			final InvitationClickListener<I> listener) {
+	public void onBind(@Nullable I item, InvitationClickListener<I> listener) {
 		if (item == null) return;
 
 		avatar.setText(item.getShareable().getName().substring(0, 1));
@@ -53,18 +52,8 @@ public class InvitationViewHolder<I extends InvitationItem>
 			subscribed.setVisibility(GONE);
 		}
 
-		accept.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				listener.onItemClick(item, true);
-			}
-		});
-		decline.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				listener.onItemClick(item, false);
-			}
-		});
+		accept.setOnClickListener(v -> listener.onItemClick(item, true));
+		decline.setOnClickListener(v -> listener.onItemClick(item, false));
 	}
 
 }
\ No newline at end of file
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareBlogControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareBlogControllerImpl.java
index 4f19691f7801dcc3ef2626bef7ee2ed8f1509cab..40bd81d9315bc84bbe2b8ae6e9f9fb9b6512ef0f 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareBlogControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareBlogControllerImpl.java
@@ -55,30 +55,25 @@ class ShareBlogControllerImpl extends ContactSelectorControllerImpl
 	}
 
 	@Override
-	public void share(final GroupId g, final Collection<ContactId> contacts,
-			final String message,
-			final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					String msg = isNullOrEmpty(message) ? null : message;
-					for (ContactId c : contacts) {
-						try {
-							long time = Math.max(clock.currentTimeMillis(),
-									conversationManager.getGroupCount(c)
-											.getLatestMsgTime() + 1);
-							blogSharingManager.sendInvitation(g, c, msg, time);
-						} catch (NoSuchContactException | NoSuchGroupException e) {
-							if (LOG.isLoggable(WARNING))
-								LOG.log(WARNING, e.toString(), e);
-						}
+	public void share(GroupId g, Collection<ContactId> contacts, String message,
+			ExceptionHandler<DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				String msg = isNullOrEmpty(message) ? null : message;
+				for (ContactId c : contacts) {
+					try {
+						long time = Math.max(clock.currentTimeMillis(),
+								conversationManager.getGroupCount(c)
+										.getLatestMsgTime() + 1);
+						blogSharingManager.sendInvitation(g, c, msg, time);
+					} catch (NoSuchContactException | NoSuchGroupException e) {
+						if (LOG.isLoggable(WARNING))
+							LOG.log(WARNING, e.toString(), e);
 					}
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
 				}
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareForumControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareForumControllerImpl.java
index 9770d3bc18d292759fda57bf4a4fe4d87bf84290..7dd7bdf76c20f1e9d86eed59e7ca9f6c989c2328 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareForumControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareForumControllerImpl.java
@@ -55,30 +55,25 @@ class ShareForumControllerImpl extends ContactSelectorControllerImpl
 	}
 
 	@Override
-	public void share(final GroupId g, final Collection<ContactId> contacts,
-			final String message,
-			final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					String msg = isNullOrEmpty(message) ? null : message;
-					for (ContactId c : contacts) {
-						try {
-							long time = Math.max(clock.currentTimeMillis(),
-									conversationManager.getGroupCount(c)
-											.getLatestMsgTime() + 1);
-							forumSharingManager.sendInvitation(g, c, msg, time);
-						} catch (NoSuchContactException | NoSuchGroupException e) {
-							if (LOG.isLoggable(WARNING))
-								LOG.log(WARNING, e.toString(), e);
-						}
+	public void share(GroupId g, Collection<ContactId> contacts,
+			String message, ExceptionHandler<DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				String msg = isNullOrEmpty(message) ? null : message;
+				for (ContactId c : contacts) {
+					try {
+						long time = Math.max(clock.currentTimeMillis(),
+								conversationManager.getGroupCount(c)
+										.getLatestMsgTime() + 1);
+						forumSharingManager.sendInvitation(g, c, msg, time);
+					} catch (NoSuchContactException | NoSuchGroupException e) {
+						if (LOG.isLoggable(WARNING))
+							LOG.log(WARNING, e.toString(), e);
 					}
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
 				}
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingInvitationViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingInvitationViewHolder.java
index 28c03f473ea4ab894d2bb68ce2c6d4d463f1d7bc..6d4eae929244fafcb5e8662d9ecd6a0d5d1d36e8 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingInvitationViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingInvitationViewHolder.java
@@ -5,6 +5,7 @@ import android.view.View;
 import org.briarproject.bramble.api.contact.Contact;
 import org.briarproject.bramble.util.StringUtils;
 import org.briarproject.briar.R;
+import org.briarproject.briar.android.sharing.InvitationAdapter.InvitationClickListener;
 import org.briarproject.briar.api.sharing.SharingInvitationItem;
 
 import java.util.ArrayList;
@@ -20,8 +21,8 @@ class SharingInvitationViewHolder
 	}
 
 	@Override
-	public void onBind(@Nullable final SharingInvitationItem item,
-			final InvitationAdapter.InvitationClickListener<SharingInvitationItem> listener) {
+	public void onBind(@Nullable SharingInvitationItem item,
+			InvitationClickListener<SharingInvitationItem> listener) {
 		super.onBind(item, listener);
 		if (item == null) return;
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java
index b07895d93965ee7d8c03754b0e5edbcb74bfbc5c..efe97420574cf88f27ca2359e53a28202b183a96 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java
@@ -78,7 +78,7 @@ abstract class SharingStatusActivity extends BriarActivity {
 	}
 
 	@Override
-	public boolean onOptionsItemSelected(final MenuItem item) {
+	public boolean onOptionsItemSelected(MenuItem item) {
 		// Handle presses on the action bar items
 		switch (item.getItemId()) {
 			case android.R.id.home:
@@ -100,33 +100,25 @@ abstract class SharingStatusActivity extends BriarActivity {
 	}
 
 	private void loadSharedWith() {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					List<ContactItem> contactItems = new ArrayList<>();
-					for (Contact c : getSharedWith()) {
-						boolean online =
-								connectionRegistry.isConnected(c.getId());
-						ContactItem item = new ContactItem(c, online);
-						contactItems.add(item);
-					}
-					displaySharedWith(contactItems);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
+		runOnDbThread(() -> {
+			try {
+				List<ContactItem> contactItems = new ArrayList<>();
+				for (Contact c : getSharedWith()) {
+					boolean online = connectionRegistry.isConnected(c.getId());
+					ContactItem item = new ContactItem(c, online);
+					contactItems.add(item);
 				}
+				displaySharedWith(contactItems);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
-	private void displaySharedWith(final List<ContactItem> contacts) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (contacts.isEmpty()) list.showData();
-				else adapter.addAll(contacts);
-			}
+	private void displaySharedWith(List<ContactItem> contacts) {
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (contacts.isEmpty()) list.showData();
+			else adapter.addAll(contacts);
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/splash/SplashScreenActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/splash/SplashScreenActivity.java
index 04fffbaf10eb1600fa492d3902aaa435437dbdea..7c19f3c780231ab3d2196a7875ef30e6cda226c7 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/splash/SplashScreenActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/splash/SplashScreenActivity.java
@@ -43,12 +43,9 @@ public class SplashScreenActivity extends BaseActivity {
 
 		setContentView(R.layout.splash);
 
-		new Handler().postDelayed(new Runnable() {
-			@Override
-			public void run() {
-				startNextActivity();
-				supportFinishAfterTransition();
-			}
+		new Handler().postDelayed(() -> {
+			startNextActivity();
+			supportFinishAfterTransition();
 		}, 500);
 	}
 
@@ -72,12 +69,8 @@ public class SplashScreenActivity extends BaseActivity {
 	}
 
 	private void setPreferencesDefaults() {
-		androidExecutor.runOnBackgroundThread(new Runnable() {
-			@Override
-			public void run() {
+		androidExecutor.runOnBackgroundThread(() ->
 				PreferenceManager.setDefaultValues(SplashScreenActivity.this,
-						R.xml.panic_preferences, false);
-			}
-		});
+						R.xml.panic_preferences, false));
 	}
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/BaseThreadItemViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/BaseThreadItemViewHolder.java
index b7fdeff1af4d8b2168c47eb95a63234d7949a4a9..aac9621a2dd2e17ab23f540c5c46f94694c40bed 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/BaseThreadItemViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/BaseThreadItemViewHolder.java
@@ -40,7 +40,7 @@ public abstract class BaseThreadItemViewHolder<I extends ThreadItem>
 	}
 
 	@CallSuper
-	public void bind(final I item, final ThreadItemListener<I> listener) {
+	public void bind(I item, ThreadItemListener<I> listener) {
 		textView.setText(StringUtils.trim(item.getText()));
 
 		author.setAuthor(item.getAuthor());
@@ -85,13 +85,8 @@ public abstract class BaseThreadItemViewHolder<I extends ThreadItem>
 			public void onAnimationRepeat(Animator animation) {
 			}
 		});
-		anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-			@Override
-			public void onAnimationUpdate(ValueAnimator valueAnimator) {
-				layout.setBackgroundColor(
-						(Integer) valueAnimator.getAnimatedValue());
-			}
-		});
+		anim.addUpdateListener(valueAnimator -> layout.setBackgroundColor(
+				(Integer) valueAnimator.getAnimatedValue()));
 		anim.setDuration(ANIMATION_DURATION);
 		anim.start();
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItemAdapter.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItemAdapter.java
index 49140f571cd0bd66aca37749d293b73f07e32490..4cf1f630a25308d0fead31832031847bf352cee3 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItemAdapter.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItemAdapter.java
@@ -140,8 +140,8 @@ public class ThreadItemAdapter<I extends ThreadItem>
 	 *            because then the view port is unknown.
 	 */
 	public UnreadCount getUnreadCount() {
-		final int positionTop = layoutManager.findFirstVisibleItemPosition();
-		final int positionBottom = layoutManager.findLastVisibleItemPosition();
+		int positionTop = layoutManager.findFirstVisibleItemPosition();
+		int positionBottom = layoutManager.findLastVisibleItemPosition();
 		if (positionTop == NO_POSITION && positionBottom == NO_POSITION)
 			return new UnreadCount(0, 0);
 
@@ -161,7 +161,7 @@ public class ThreadItemAdapter<I extends ThreadItem>
 	 * Returns the position of the first unread item below the current viewport
 	 */
 	int getVisibleUnreadPosBottom() {
-		final int positionBottom = layoutManager.findLastVisibleItemPosition();
+		int positionBottom = layoutManager.findLastVisibleItemPosition();
 		if (positionBottom == NO_POSITION) return NO_POSITION;
 		for (int i = positionBottom + 1; i < items.size(); i++) {
 			if (!items.get(i).isRead()) return i;
@@ -173,7 +173,7 @@ public class ThreadItemAdapter<I extends ThreadItem>
 	 * Returns the position of the first unread item above the current viewport
 	 */
 	int getVisibleUnreadPosTop() {
-		final int positionTop = layoutManager.findFirstVisibleItemPosition();
+		int positionTop = layoutManager.findFirstVisibleItemPosition();
 		int position = NO_POSITION;
 		for (int i = 0; i < items.size(); i++) {
 			if (i < positionTop && !items.get(i).isRead()) {
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java
index 829ba292ccec128e6aeb5571efb9496feac77566..2e5d62ac5867ac1e68bcfaf1c45451fe5480220b 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java
@@ -10,7 +10,6 @@ import android.support.v7.app.ActionBar;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
 import android.view.MenuItem;
-import android.view.View;
 
 import org.briarproject.bramble.api.contact.ContactId;
 import org.briarproject.bramble.api.db.DbException;
@@ -117,22 +116,16 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
 				});
 		upButton = (UnreadMessageButton) findViewById(R.id.upButton);
 		downButton = (UnreadMessageButton) findViewById(R.id.downButton);
-		upButton.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				int position = adapter.getVisibleUnreadPosTop();
-				if (position != NO_POSITION) {
-					list.getRecyclerView().scrollToPosition(position);
-				}
+		upButton.setOnClickListener(v -> {
+			int position = adapter.getVisibleUnreadPosTop();
+			if (position != NO_POSITION) {
+				list.getRecyclerView().scrollToPosition(position);
 			}
 		});
-		downButton.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				int position = adapter.getVisibleUnreadPosBottom();
-				if (position != NO_POSITION) {
-					list.getRecyclerView().scrollToPosition(position);
-				}
+		downButton.setOnClickListener(v -> {
+			int position = adapter.getVisibleUnreadPosBottom();
+			if (position != NO_POSITION) {
+				list.getRecyclerView().scrollToPosition(position);
 			}
 		});
 
@@ -178,7 +171,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
 	protected abstract void onNamedGroupLoaded(G groupItem);
 
 	protected void loadItems() {
-		final int revision = adapter.getRevision();
+		int revision = adapter.getRevision();
 		getController().loadItems(
 				new UiResultExceptionHandler<ThreadItemList<I>, DbException>(
 						this) {
@@ -205,7 +198,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
 				});
 	}
 
-	private void displayItems(final ThreadItemList<I> items) {
+	private void displayItems(ThreadItemList<I> items) {
 		adapter.setItems(items);
 		MessageId messageId = items.getFirstVisibleItemId();
 		if (messageId != null)
@@ -288,7 +281,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
 	}
 
 	@Override
-	public void onReplyClick(final I item) {
+	public void onReplyClick(I item) {
 		replyId = item.getId();
 		updateTextInput();
 		if (textInput.isKeyboardOpen()) {
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListControllerImpl.java
index 26bb1aff326db89891bfe6d5e6625a8dc8585147..11929640ed5008a11431051ca25584536221bd6b 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListControllerImpl.java
@@ -99,18 +99,14 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
 
 	@Override
 	public void onActivityDestroy() {
-		final MessageId messageId = listener.getFirstVisibleMessageId();
+		MessageId messageId = listener.getFirstVisibleMessageId();
 		if (messageId != null) {
-			dbExecutor.execute(new Runnable() {
-				@Override
-				public void run() {
-					try {
-						messageTracker
-								.storeMessageId(groupId, messageId);
-					} catch (DbException e) {
-						if (LOG.isLoggable(WARNING))
-							LOG.log(WARNING, e.toString(), e);
-					}
+			dbExecutor.execute(() -> {
+				try {
+					messageTracker.storeMessageId(groupId, messageId);
+				} catch (DbException e) {
+					if (LOG.isLoggable(WARNING))
+						LOG.log(WARNING, e.toString(), e);
 				}
 			});
 		}
@@ -123,35 +119,28 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
 			GroupRemovedEvent s = (GroupRemovedEvent) e;
 			if (s.getGroup().getId().equals(getGroupId())) {
 				LOG.info("Group removed");
-				listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						listener.onGroupRemoved();
-					}
-				});
+				listener.runOnUiThreadUnlessDestroyed(
+						() -> listener.onGroupRemoved());
 			}
 		}
 	}
 
 	@Override
 	public void loadNamedGroup(
-			final ResultExceptionHandler<G, DbException> handler) {
+			ResultExceptionHandler<G, DbException> handler) {
 		checkGroupId();
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					G groupItem = loadNamedGroup();
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading group took " + duration + " ms");
-					handler.onResult(groupItem);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				G groupItem = loadNamedGroup();
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading group took " + duration + " ms");
+				handler.onResult(groupItem);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -161,38 +150,34 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
 
 	@Override
 	public void loadItems(
-			final ResultExceptionHandler<ThreadItemList<I>, DbException> handler) {
+			ResultExceptionHandler<ThreadItemList<I>, DbException> handler) {
 		checkGroupId();
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					// Load headers
-					long now = System.currentTimeMillis();
-					Collection<H> headers = loadHeaders();
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading headers took " + duration + " ms");
-
-					// Load bodies into cache
-					now = System.currentTimeMillis();
-					for (H header : headers) {
-						if (!bodyCache.containsKey(header.getId())) {
-							bodyCache.put(header.getId(),
-									loadMessageBody(header));
-						}
+		runOnDbThread(() -> {
+			try {
+				// Load headers
+				long now = System.currentTimeMillis();
+				Collection<H> headers = loadHeaders();
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading headers took " + duration + " ms");
+
+				// Load bodies into cache
+				now = System.currentTimeMillis();
+				for (H header : headers) {
+					if (!bodyCache.containsKey(header.getId())) {
+						bodyCache.put(header.getId(),
+								loadMessageBody(header));
 					}
-					duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading bodies took " + duration + " ms");
-
-					// Build and hand over items
-					handler.onResult(buildItems(headers));
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
 				}
+				duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading bodies took " + duration + " ms");
+
+				// Build and hand over items
+				handler.onResult(buildItems(headers));
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -209,22 +194,18 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
 	}
 
 	@Override
-	public void markItemsRead(final Collection<I> items) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					for (I i : items) {
-						markRead(i.getId());
-					}
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Marking read took " + duration + " ms");
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
+	public void markItemsRead(Collection<I> items) {
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				for (I i : items) {
+					markRead(i.getId());
 				}
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Marking read took " + duration + " ms");
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
@@ -232,24 +213,20 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
 	@DatabaseExecutor
 	protected abstract void markRead(MessageId id) throws DbException;
 
-	protected void storePost(final M msg, final String body,
-			final ResultExceptionHandler<I, DbException> resultHandler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					H header = addLocalMessage(msg);
-					bodyCache.put(msg.getMessage().getId(), body);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Storing message took " + duration + " ms");
-					resultHandler.onResult(buildItem(header, body));
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					resultHandler.onException(e);
-				}
+	protected void storePost(M msg, String body,
+			ResultExceptionHandler<I, DbException> resultHandler) {
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				H header = addLocalMessage(msg);
+				bodyCache.put(msg.getMessage().getId(), body);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Storing message took " + duration + " ms");
+				resultHandler.onResult(buildItem(header, body));
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				resultHandler.onException(e);
 			}
 		});
 	}
@@ -258,22 +235,18 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
 	protected abstract H addLocalMessage(M message) throws DbException;
 
 	@Override
-	public void deleteNamedGroup(final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					G groupItem = loadNamedGroup();
-					deleteNamedGroup(groupItem);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Removing group took " + duration + " ms");
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+	public void deleteNamedGroup(ExceptionHandler<DbException> handler) {
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				G groupItem = loadNamedGroup();
+				deleteNamedGroup(groupItem);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Removing group took " + duration + " ms");
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadPostViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadPostViewHolder.java
index 5719f9a0e09ace6d61611e5bd19933b45f69971f..dbab681c588445f6953b63a6a34a0687c29e2a3c 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadPostViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadPostViewHolder.java
@@ -37,7 +37,7 @@ public class ThreadPostViewHolder<I extends ThreadItem>
 	}
 
 	@Override
-	public void bind(final I item, final ThreadItemListener<I> listener) {
+	public void bind(I item, ThreadItemListener<I> listener) {
 		super.bind(item, listener);
 
 		for (int i = 0; i < lvls.length; i++) {
@@ -50,12 +50,7 @@ public class ThreadPostViewHolder<I extends ThreadItem>
 			lvlText.setVisibility(GONE);
 		}
 
-		replyButton.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				listener.onReplyClick(item);
-			}
-		});
+		replyButton.setOnClickListener(v -> listener.onReplyClick(item));
 	}
 
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java
index 61991d6e662dd85f718e59ef018b045ff55a54fa..04172d7b021fb0dca767f7fe1d086520ccf32684 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java
@@ -3,7 +3,6 @@ package org.briarproject.briar.android.util;
 import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
 import android.content.Intent;
 import android.net.Uri;
@@ -116,7 +115,7 @@ public class UiUtils {
 		for (URLSpan span : spans) {
 			int start = ssb.getSpanStart(span);
 			int end = ssb.getSpanEnd(span);
-			final String url = span.getURL();
+			String url = span.getURL();
 			ssb.removeSpan(span);
 			ClickableSpan cSpan = new ClickableSpan() {
 				@Override
@@ -141,18 +140,14 @@ public class UiUtils {
 		return "bulb" + c.getInt();
 	}
 
-	public static OnClickListener getGoToSettingsListener(
-			final Context context) {
-		return new OnClickListener() {
-			@Override
-			public void onClick(DialogInterface dialog, int which) {
-				Intent i = new Intent();
-				i.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
-				i.addCategory(CATEGORY_DEFAULT);
-				i.setData(Uri.parse("package:" + APPLICATION_ID));
-				i.addFlags(FLAG_ACTIVITY_NEW_TASK);
-				context.startActivity(i);
-			}
+	public static OnClickListener getGoToSettingsListener(Context context) {
+		return (dialog, which) -> {
+			Intent i = new Intent();
+			i.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
+			i.addCategory(CATEGORY_DEFAULT);
+			i.setData(Uri.parse("package:" + APPLICATION_ID));
+			i.addFlags(FLAG_ACTIVITY_NEW_TASK);
+			context.startActivity(i);
 		};
 	}
 
@@ -160,13 +155,7 @@ public class UiUtils {
 		new AlertDialog.Builder(ctx, R.style.OnboardingDialogTheme)
 				.setMessage(text)
 				.setNeutralButton(R.string.got_it,
-						new DialogInterface.OnClickListener() {
-							@Override
-							public void onClick(DialogInterface dialog,
-									int which) {
-								dialog.cancel();
-							}
-						})
+						(dialog, which) -> dialog.cancel())
 				.show();
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/view/BriarRecyclerView.java b/briar-android/src/main/java/org/briarproject/briar/android/view/BriarRecyclerView.java
index cd3db7420ed41f5b97856d66a22d208a85923e82..d90b7f2c62baeae35ba4d6d41282c8dc802fe62d 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/view/BriarRecyclerView.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/view/BriarRecyclerView.java
@@ -94,24 +94,13 @@ public class BriarRecyclerView extends FrameLayout {
 	}
 
 	private void addLayoutChangeListener() {
-		recyclerView.addOnLayoutChangeListener(
-				new OnLayoutChangeListener() {
-					@Override
-					public void onLayoutChange(View v, int left, int top,
-							int right, int bottom, int oldLeft, int oldTop,
-							int oldRight, int oldBottom) {
-						if (bottom < oldBottom) {
-							recyclerView.postDelayed(new Runnable() {
-								@Override
-								public void run() {
-									scrollToPosition(
-											recyclerView.getAdapter()
-													.getItemCount() - 1);
-								}
-							}, 100);
-						}
-					}
-				});
+		recyclerView.addOnLayoutChangeListener((v, left, top, right, bottom,
+				oldLeft, oldTop, oldRight, oldBottom) -> {
+			if (bottom < oldBottom) {
+				recyclerView.postDelayed(() -> scrollToPosition(
+						recyclerView.getAdapter().getItemCount() - 1), 100);
+			}
+		});
 	}
 
 	public void setLayoutManager(RecyclerView.LayoutManager layout) {
@@ -191,14 +180,11 @@ public class BriarRecyclerView extends FrameLayout {
 		if (recyclerView == null || recyclerView.getAdapter() == null) {
 			throw new IllegalStateException("Need to call setAdapter() first!");
 		}
-		refresher = new Runnable() {
-			@Override
-			public void run() {
-				LOG.info("Updating Content...");
-				Adapter adapter = recyclerView.getAdapter();
-				adapter.notifyItemRangeChanged(0, adapter.getItemCount());
-				handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
-			}
+		refresher = () -> {
+			LOG.info("Updating Content...");
+			Adapter adapter = recyclerView.getAdapter();
+			adapter.notifyItemRangeChanged(0, adapter.getItemCount());
+			handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
 		};
 		LOG.info("Adding Handler Callback");
 		handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/view/TextInputView.java b/briar-android/src/main/java/org/briarproject/briar/android/view/TextInputView.java
index 033747179f3cb19cab9d2936f96cf0d887f83d6a..ce97e11fb85e7fbc8b8995c33914e030bb46d760 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/view/TextInputView.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/view/TextInputView.java
@@ -75,34 +75,18 @@ public class TextInputView extends KeyboardAwareLinearLayout
 		}
 
 		ui.emojiToggle.attach(ui.emojiDrawer);
-		ui.emojiToggle.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				onEmojiToggleClicked();
+		ui.emojiToggle.setOnClickListener(v -> onEmojiToggleClicked());
+		ui.editText.setOnClickListener(v -> showSoftKeyboard());
+		ui.editText.setOnKeyListener((v, keyCode, event) -> {
+			if (keyCode == KEYCODE_BACK && isEmojiDrawerOpen()) {
+				hideEmojiDrawer();
+				return true;
 			}
+			return false;
 		});
-		ui.editText.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				showSoftKeyboard();
-			}
-		});
-		ui.editText.setOnKeyListener(new OnKeyListener() {
-			@Override
-			public boolean onKey(View v, int keyCode, KeyEvent event) {
-				if (keyCode == KEYCODE_BACK && isEmojiDrawerOpen()) {
-					hideEmojiDrawer();
-					return true;
-				}
-				return false;
-			}
-		});
-		ui.sendButton.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				if (listener != null) {
-					listener.onSendClick(ui.editText.getText().toString());
-				}
+		ui.sendButton.setOnClickListener(v -> {
+			if (listener != null) {
+				listener.onSendClick(ui.editText.getText().toString());
 			}
 		});
 		ui.emojiDrawer.setEmojiEventListener(this);
@@ -167,22 +151,13 @@ public class TextInputView extends KeyboardAwareLinearLayout
 		if (isKeyboardOpen()) return;
 
 		if (ui.emojiDrawer.isShowing()) {
-			postOnKeyboardOpen(new Runnable() {
-				@Override
-				public void run() {
-					hideEmojiDrawer();
-				}
-			});
+			postOnKeyboardOpen(this::hideEmojiDrawer);
 		}
-		ui.editText.post(new Runnable() {
-			@Override
-			public void run() {
-				ui.editText.requestFocus();
-				InputMethodManager imm =
-						(InputMethodManager) getContext()
-								.getSystemService(INPUT_METHOD_SERVICE);
-				imm.showSoftInput(ui.editText, SHOW_IMPLICIT);
-			}
+		ui.editText.post(() -> {
+			ui.editText.requestFocus();
+			InputMethodManager imm = (InputMethodManager)
+					getContext().getSystemService(INPUT_METHOD_SERVICE);
+			imm.showSoftInput(ui.editText, SHOW_IMPLICIT);
 		});
 	}
 
@@ -194,11 +169,7 @@ public class TextInputView extends KeyboardAwareLinearLayout
 
 	public void showEmojiDrawer() {
 		if (isKeyboardOpen()) {
-			postOnKeyboardClose(new Runnable() {
-				@Override public void run() {
-					ui.emojiDrawer.show(getKeyboardHeight());
-				}
-			});
+			postOnKeyboardClose(() -> ui.emojiDrawer.show(getKeyboardHeight()));
 			hideSoftKeyboard();
 		} else {
 			ui.emojiDrawer.show(getKeyboardHeight());
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/widget/LinkDialogFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/widget/LinkDialogFragment.java
index 1370574f376ef6530b1f2979750d44cb0da062c1..075daecfc857fd32b9d096d66473f9291b1931f1 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/widget/LinkDialogFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/widget/LinkDialogFragment.java
@@ -8,7 +8,6 @@ import android.os.Bundle;
 import android.support.v4.app.DialogFragment;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.TextView;
@@ -58,25 +57,17 @@ public class LinkDialogFragment extends DialogFragment {
 		List activities = packageManager.queryIntentActivities(i,
 				PackageManager.MATCH_DEFAULT_ONLY);
 		boolean choice = activities.size() > 1;
-		final Intent intent = choice ? Intent.createChooser(i,
+		Intent intent = choice ? Intent.createChooser(i,
 				getString(R.string.link_warning_open_link)) : i;
 
 		Button openButton = (Button) v.findViewById(R.id.openButton);
-		openButton.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				startActivity(intent);
-				getDialog().dismiss();
-			}
+		openButton.setOnClickListener(v1 -> {
+			startActivity(intent);
+			getDialog().dismiss();
 		});
 
 		Button cancelButton = (Button) v.findViewById(R.id.cancelButton);
-		cancelButton.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				getDialog().cancel();
-			}
-		});
+		cancelButton.setOnClickListener(v1 -> getDialog().cancel());
 
 		return v;
 	}
diff --git a/briar-android/src/main/java/org/thoughtcrime/securesms/components/KeyboardAwareLinearLayout.java b/briar-android/src/main/java/org/thoughtcrime/securesms/components/KeyboardAwareLinearLayout.java
index c3e6050c59d59f364364d56efeb8c329c79cfe9f..213bf2a6ea5413f73a4552a60b6126ce74d51466 100644
--- a/briar-android/src/main/java/org/thoughtcrime/securesms/components/KeyboardAwareLinearLayout.java
+++ b/briar-android/src/main/java/org/thoughtcrime/securesms/components/KeyboardAwareLinearLayout.java
@@ -65,7 +65,7 @@ public class KeyboardAwareLinearLayout extends LinearLayout {
 			@Nullable AttributeSet attrs, int defStyle) {
 		super(context, attrs, defStyle);
 		rotation = getDeviceRotation();
-		final int statusBarRes = getResources()
+		int statusBarRes = getResources()
 				.getIdentifier("status_bar_height", "dimen", "android");
 		minKeyboardSize =
 				getResources().getDimensionPixelSize(R.dimen.min_keyboard_size);
@@ -199,7 +199,7 @@ public class KeyboardAwareLinearLayout extends LinearLayout {
 		prefs.edit().putInt("keyboard_height_portrait", height).apply();
 	}
 
-	public void postOnKeyboardClose(final Runnable runnable) {
+	public void postOnKeyboardClose(Runnable runnable) {
 		if (keyboardOpen) {
 			addOnKeyboardHiddenListener(new OnKeyboardHiddenListener() {
 				@Override
@@ -213,7 +213,7 @@ public class KeyboardAwareLinearLayout extends LinearLayout {
 		}
 	}
 
-	public void postOnKeyboardOpen(final Runnable runnable) {
+	public void postOnKeyboardOpen(Runnable runnable) {
 		if (!keyboardOpen) {
 			addOnKeyboardShownListener(new OnKeyboardShownListener() {
 				@Override
diff --git a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiDrawer.java b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiDrawer.java
index 44c959184d24ab0b7f33f9c2562ebf1607459070..43a1340e78889ef09fd2dac50e01e1b00c410538 100644
--- a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiDrawer.java
+++ b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiDrawer.java
@@ -18,7 +18,6 @@ import com.astuetz.PagerSlidingTabStrip.CustomTabProvider;
 
 import org.briarproject.briar.R;
 import org.thoughtcrime.securesms.components.RepeatableImageKey;
-import org.thoughtcrime.securesms.components.RepeatableImageKey.KeyEventListener;
 import org.thoughtcrime.securesms.components.emoji.EmojiPageView.EmojiSelectionListener;
 
 import java.util.LinkedList;
@@ -57,7 +56,7 @@ public class EmojiDrawer extends LinearLayout {
 	}
 
 	private void initView() {
-		final View v = LayoutInflater.from(getContext())
+		View v = LayoutInflater.from(getContext())
 				.inflate(R.layout.emoji_drawer, this, true);
 		initializeResources(v);
 		initializePageModels();
@@ -78,11 +77,8 @@ public class EmojiDrawer extends LinearLayout {
 
 		RepeatableImageKey backspace =
 				(RepeatableImageKey) v.findViewById(R.id.backspace);
-		backspace.setOnKeyEventListener(new KeyEventListener() {
-			@Override
-			public void onKeyEvent() {
-				if (listener != null) listener.onKeyEvent(DELETE_KEY_EVENT);
-			}
+		backspace.setOnKeyEventListener(() -> {
+			if (listener != null) listener.onKeyEvent(DELETE_KEY_EVENT);
 		});
 	}
 
@@ -107,14 +103,10 @@ public class EmojiDrawer extends LinearLayout {
 	}
 
 	private void initializeEmojiGrid() {
-		pager.setAdapter(new EmojiPagerAdapter(getContext(),
-				models,
-				new EmojiSelectionListener() {
-					@Override
-					public void onEmojiSelected(String emoji) {
-						recentModel.onCodePointSelected(emoji);
-						if (listener != null) listener.onEmojiSelected(emoji);
-					}
+		pager.setAdapter(new EmojiPagerAdapter(getContext(), models,
+				emoji -> {
+					recentModel.onCodePointSelected(emoji);
+					if (listener != null) listener.onEmojiSelected(emoji);
 				}));
 
 		if (recentModel.getEmoji().length == 0) {
diff --git a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiEditText.java b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiEditText.java
index 980e29cda61860a46676fcc175922638466b28fe..6e325a9ad3774709d66ebc36b672be3297869289 100644
--- a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiEditText.java
+++ b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiEditText.java
@@ -33,8 +33,8 @@ public class EmojiEditText extends AppCompatEditText {
 	}
 
 	public void insertEmoji(String emoji) {
-		final int start = getSelectionStart();
-		final int end = getSelectionEnd();
+		int start = getSelectionStart();
+		int end = getSelectionEnd();
 
 		getText().replace(Math.min(start, end), Math.max(start, end), emoji);
 		setSelection(start + emoji.length());
diff --git a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPageView.java b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPageView.java
index c006793018ae69cbdd63eb13d8fbef18ebe8226e..4b186e634f056e38ebf864c356d4992db0fe8b45 100644
--- a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPageView.java
+++ b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPageView.java
@@ -7,8 +7,6 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AbsListView;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
 import android.widget.BaseAdapter;
 import android.widget.FrameLayout;
 import android.widget.GridView;
@@ -35,20 +33,16 @@ public class EmojiPageView extends FrameLayout {
 	public EmojiPageView(Context context, @Nullable AttributeSet attrs,
 			int defStyleAttr) {
 		super(context, attrs, defStyleAttr);
-		final View view = LayoutInflater.from(getContext())
+		View view = LayoutInflater.from(getContext())
 				.inflate(R.layout.emoji_grid_layout, this, true);
 		grid = (GridView) view.findViewById(R.id.emoji);
 		grid.setColumnWidth(getResources()
 				.getDimensionPixelSize(R.dimen.emoji_drawer_size) + 2 *
 				getResources().getDimensionPixelSize(
 						R.dimen.emoji_drawer_item_padding));
-		grid.setOnItemClickListener(new OnItemClickListener() {
-			@Override
-			public void onItemClick(AdapterView<?> parent, View view,
-					int position, long id) {
-				if (listener != null)
-					listener.onEmojiSelected(((EmojiView) view).getEmoji());
-			}
+		grid.setOnItemClickListener((parent, view1, position, id) -> {
+			if (listener != null)
+				listener.onEmojiSelected(((EmojiView) view1).getEmoji());
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPages.java b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPages.java
index 1427b5df98f19216acb8f753cbd04dd40afb95e1..6d77f74b90ac15f4852f7bf805fe85ce239be3cb 100644
--- a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPages.java
+++ b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPages.java
@@ -10,7 +10,7 @@ import java.util.List;
 class EmojiPages {
 
 	static List<EmojiPageModel> getPages(Context ctx) {
-		return Arrays.<EmojiPageModel>asList(
+		return Arrays.asList(
 				new StaticEmojiPageModel(ctx, R.drawable.ic_emoji_smiley_people,
 						R.array.emoji_smiley_people,
 						"emoji_smiley_people.png"),
diff --git a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java
index c479ee1685509469741714c9ce94cf88b0440beb..9b6068565bb4ef3da6da72740b849e8db0e74182 100644
--- a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java
+++ b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java
@@ -135,16 +135,11 @@ public class EmojiProvider {
 			return null;
 		}
 
-		final EmojiDrawable drawable = new EmojiDrawable(drawInfo, decodeScale);
+		EmojiDrawable drawable = new EmojiDrawable(drawInfo, decodeScale);
 		drawInfo.page.get().addListener(new FutureTaskListener<Bitmap>() {
 			@Override
-			public void onSuccess(final Bitmap result) {
-				androidExecutor.runOnUiThread(new Runnable() {
-					@Override
-					public void run() {
-						drawable.setBitmap(result);
-					}
-				});
+			public void onSuccess(Bitmap result) {
+				androidExecutor.runOnUiThread(() -> drawable.setBitmap(result));
 			}
 
 			@Override
@@ -260,14 +255,10 @@ public class EmojiProvider {
 				if (bitmap != null) return new ListenableFutureTask<>(bitmap);
 			}
 			if (task != null) return task;
-			Callable<Bitmap> callable = new Callable<Bitmap>() {
-				@Override
-				@Nullable
-				public Bitmap call() throws Exception {
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading page " + model.getSprite());
-					return loadPage();
-				}
+			Callable<Bitmap> callable = () -> {
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading page " + model.getSprite());
+				return loadPage();
 			};
 			task = new ListenableFutureTask<>(callable);
 			new AsyncTask<Void, Void, Void>() {
diff --git a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/RecentEmojiPageModel.java b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/RecentEmojiPageModel.java
index 9b5780b252ec692483791d47c217892d421084f4..56d72e3a813e9961b2bea7efe70b100196aa7128 100644
--- a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/RecentEmojiPageModel.java
+++ b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/RecentEmojiPageModel.java
@@ -109,18 +109,14 @@ public class RecentEmojiPageModel implements EmojiPageModel {
 		return result;
 	}
 
-	private void save(final String serialized) {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				Settings settings = new Settings();
-				settings.put(EMOJI_LRU_PREFERENCE, serialized);
-				try {
-					settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+	private void save(String serialized) {
+		dbExecutor.execute(() -> {
+			Settings settings = new Settings();
+			settings.put(EMOJI_LRU_PREFERENCE, serialized);
+			try {
+				settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/thoughtcrime/securesms/components/util/ListenableFutureTask.java b/briar-android/src/main/java/org/thoughtcrime/securesms/components/util/ListenableFutureTask.java
index d9651770df545155f3958a525e8314ce4549dc50..3d8303f07d7762f4fcb4bcbed61b0406e50cfb72 100644
--- a/briar-android/src/main/java/org/thoughtcrime/securesms/components/util/ListenableFutureTask.java
+++ b/briar-android/src/main/java/org/thoughtcrime/securesms/components/util/ListenableFutureTask.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2014 Open Whisper Systems
  *
  * This program is free software: you can redistribute it and/or modify
@@ -41,17 +41,12 @@ public class ListenableFutureTask<V> extends FutureTask<V> {
 		this.identifier = identifier;
 	}
 
-	public ListenableFutureTask(final V result) {
+	public ListenableFutureTask(V result) {
 		this(result, null);
 	}
 
-	private ListenableFutureTask(final V result, @Nullable Object identifier) {
-		super(new Callable<V>() {
-			@Override
-			public V call() throws Exception {
-				return result;
-			}
-		});
+	private ListenableFutureTask(V result, @Nullable Object identifier) {
+		super(() -> result);
 		this.identifier = identifier;
 		this.run();
 	}
diff --git a/briar-android/src/main/java/org/thoughtcrime/securesms/util/BitmapUtil.java b/briar-android/src/main/java/org/thoughtcrime/securesms/util/BitmapUtil.java
index 0bc0ed00f95d93721f923863bc475303fb086f01..204bedaa4b6988538aade23621986b053440bd87 100644
--- a/briar-android/src/main/java/org/thoughtcrime/securesms/util/BitmapUtil.java
+++ b/briar-android/src/main/java/org/thoughtcrime/securesms/util/BitmapUtil.java
@@ -40,14 +40,14 @@ public class BitmapUtil {
 	private static <T> Bitmap createScaledBitmapInto(Context context, T model,
 			int width, int height)
 			throws BitmapDecodingException {
-		final Bitmap rough = Downsampler.AT_LEAST
+		Bitmap rough = Downsampler.AT_LEAST
 				.decode(getInputStreamForModel(context, model),
 						Glide.get(context).getBitmapPool(),
 						width, height, DecodeFormat.PREFER_RGB_565);
 
-		final Resource<Bitmap> resource = BitmapResource
+		Resource<Bitmap> resource = BitmapResource
 				.obtain(rough, Glide.get(context).getBitmapPool());
-		final Resource<Bitmap> result =
+		Resource<Bitmap> result =
 				new FitCenter(context).transform(resource, width, height);
 
 		if (result == null) {
diff --git a/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionManager.java b/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionManager.java
index 2b707d9f182e81f98cc3f01115c054479fc0f3ff..a9b8660813a247413c3e8f8a6e9b2186cb428382 100644
--- a/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionManager.java
+++ b/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionManager.java
@@ -25,21 +25,19 @@ public interface IntroductionManager extends ConversationClient {
 	 * Sends two initial introduction messages.
 	 */
 	void makeIntroduction(Contact c1, Contact c2, @Nullable String msg,
-			final long timestamp) throws DbException, FormatException;
+			long timestamp) throws DbException, FormatException;
 
 	/**
 	 * Accepts an introduction.
 	 */
-	void acceptIntroduction(final ContactId contactId,
-			final SessionId sessionId, final long timestamp)
-			throws DbException, FormatException;
+	void acceptIntroduction(ContactId contactId, SessionId sessionId,
+			long timestamp) throws DbException, FormatException;
 
 	/**
 	 * Declines an introduction.
 	 */
-	void declineIntroduction(final ContactId contactId,
-			final SessionId sessionId, final long timestamp)
-			throws DbException, FormatException;
+	void declineIntroduction(ContactId contactId, SessionId sessionId,
+			long timestamp) throws DbException, FormatException;
 
 	/**
 	 * Returns all introduction messages for the given contact.
diff --git a/briar-core/src/main/java/org/briarproject/briar/blog/BlogManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/blog/BlogManagerImpl.java
index 11a7c84ebf437eccd8571d25f9b1474daa092ff6..b4ff952a5abea05280c513a3869af47b9593a911 100644
--- a/briar-core/src/main/java/org/briarproject/briar/blog/BlogManagerImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/blog/BlogManagerImpl.java
@@ -86,7 +86,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
 		this.identityManager = identityManager;
 		this.blogFactory = blogFactory;
 		this.blogPostFactory = blogPostFactory;
-		removeHooks = new CopyOnWriteArrayList<RemoveBlogHook>();
+		removeHooks = new CopyOnWriteArrayList<>();
 	}
 
 	@Override
@@ -404,7 +404,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
 			throws DbException {
 
 		Collection<Blog> allBlogs = getBlogs();
-		List<Blog> blogs = new ArrayList<Blog>();
+		List<Blog> blogs = new ArrayList<>();
 		for (Blog b : allBlogs) {
 			if (b.getAuthor().equals(localAuthor)) {
 				blogs.add(b);
@@ -421,7 +421,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
 	@Override
 	public Collection<Blog> getBlogs() throws DbException {
 		try {
-			List<Blog> blogs = new ArrayList<Blog>();
+			List<Blog> blogs = new ArrayList<>();
 			Collection<Group> groups;
 			Transaction txn = db.startTransaction(true);
 			try {
@@ -492,7 +492,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
 				new BdfEntry(KEY_TYPE, COMMENT.getInt())
 		);
 
-		Collection<BlogPostHeader> headers = new ArrayList<BlogPostHeader>();
+		Collection<BlogPostHeader> headers = new ArrayList<>();
 		Transaction txn = db.startTransaction(true);
 		try {
 			Map<MessageId, BdfDictionary> metadata1 =
@@ -500,20 +500,18 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
 			Map<MessageId, BdfDictionary> metadata2 =
 					clientHelper.getMessageMetadataAsDictionary(txn, g, query2);
 			Map<MessageId, BdfDictionary> metadata =
-					new HashMap<MessageId, BdfDictionary>(
-							metadata1.size() + metadata2.size());
+					new HashMap<>(metadata1.size() + metadata2.size());
 			metadata.putAll(metadata1);
 			metadata.putAll(metadata2);
 			// get all authors we need to get the status for
-			Set<AuthorId> authors = new HashSet<AuthorId>();
+			Set<AuthorId> authors = new HashSet<>();
 			for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
 				authors.add(new AuthorId(
 						entry.getValue().getDictionary(KEY_AUTHOR)
 								.getRaw(KEY_AUTHOR_ID)));
 			}
 			// get statuses for all authors
-			Map<AuthorId, Status> authorStatuses =
-					new HashMap<AuthorId, Status>();
+			Map<AuthorId, Status> authorStatuses = new HashMap<>();
 			for (AuthorId authorId : authors) {
 				authorStatuses.put(authorId,
 						identityManager.getAuthorStatus(txn, authorId));
@@ -562,7 +560,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
 			GroupId groupId, MessageId id, BdfDictionary meta)
 			throws DbException, FormatException {
 		return getPostHeaderFromMetadata(txn, groupId, id, meta,
-				Collections.<AuthorId, Status>emptyMap());
+				Collections.emptyMap());
 	}
 
 	private BlogPostHeader getPostHeaderFromMetadata(Transaction txn,
diff --git a/briar-core/src/main/java/org/briarproject/briar/client/MessageQueueManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/client/MessageQueueManagerImpl.java
index 5e68e713c2ff84498e107621546106afcdb37193..47c91bbc2d7edc24ae4b9945a17faed057d0ada3 100644
--- a/briar-core/src/main/java/org/briarproject/briar/client/MessageQueueManagerImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/client/MessageQueueManagerImpl.java
@@ -96,7 +96,7 @@ class MessageQueueManagerImpl implements MessageQueueManager {
 	private QueueState loadQueueState(Transaction txn, GroupId g)
 			throws DbException {
 		try {
-			TreeMap<Long, MessageId> pending = new TreeMap<Long, MessageId>();
+			TreeMap<Long, MessageId> pending = new TreeMap<>();
 			Metadata groupMeta = db.getGroupMetadata(txn, g);
 			byte[] raw = groupMeta.get(QUEUE_STATE_KEY);
 			if (raw == null) return new QueueState(0, 0, pending);
@@ -231,7 +231,7 @@ class MessageQueueManagerImpl implements MessageQueueManager {
 						m.getTimestamp(), queuePosition, m.getRaw());
 				queueState.incomingPosition++;
 				// Collect any consecutive messages
-				List<MessageId> consecutive = new ArrayList<MessageId>();
+				List<MessageId> consecutive = new ArrayList<>();
 				MessageId next;
 				while ((next = queueState.popIncomingMessageId()) != null)
 					consecutive.add(next);
diff --git a/briar-core/src/main/java/org/briarproject/briar/client/MessageTreeImpl.java b/briar-core/src/main/java/org/briarproject/briar/client/MessageTreeImpl.java
index 41b4410d8a00da111833eed68900cfe89648cd7e..05c345dbc3df4de841a7734ca698df619e3e9c87 100644
--- a/briar-core/src/main/java/org/briarproject/briar/client/MessageTreeImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/client/MessageTreeImpl.java
@@ -19,17 +19,12 @@ import javax.annotation.concurrent.ThreadSafe;
 public class MessageTreeImpl<T extends MessageTree.MessageNode>
 		implements MessageTree<T> {
 
-	private final Map<MessageId, List<T>> nodeMap =
-			new HashMap<MessageId, List<T>>();
-	private final List<T> roots = new ArrayList<T>();
-	private final List<List<T>> unsortedLists = new ArrayList<List<T>>();
-
-	private Comparator<T> comparator = new Comparator<T>() {
-		@Override
-		public int compare(T o1, T o2) {
-			return Long.valueOf(o1.getTimestamp()).compareTo(o2.getTimestamp());
-		}
-	};
+	private final Map<MessageId, List<T>> nodeMap = new HashMap<>();
+	private final List<T> roots = new ArrayList<>();
+	private final List<List<T>> unsortedLists = new ArrayList<>();
+
+	private Comparator<T> comparator = (o1, o2) ->
+			Long.valueOf(o1.getTimestamp()).compareTo(o2.getTimestamp());
 
 	@Override
 	public synchronized void clear() {
@@ -41,7 +36,7 @@ public class MessageTreeImpl<T extends MessageTree.MessageNode>
 	public synchronized void add(Collection<T> nodes) {
 		// add all nodes to the node map
 		for (T node : nodes) {
-			nodeMap.put(node.getId(), new ArrayList<T>());
+			nodeMap.put(node.getId(), new ArrayList<>());
 		}
 		// parse the nodes for dependencies
 		for (T node : nodes) {
@@ -100,7 +95,7 @@ public class MessageTreeImpl<T extends MessageTree.MessageNode>
 
 	@Override
 	public synchronized Collection<T> depthFirstOrder() {
-		List<T> orderedList = new ArrayList<T>();
+		List<T> orderedList = new ArrayList<>();
 		for (T root : roots) {
 			traverse(orderedList, root, 0);
 		}
diff --git a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java
index d9c58f8e3d4e6d2391dfcc4a996b7cb164ccb0a4..3857f1fb5572cc5eb78f74474d503ff1603b8e8e 100644
--- a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java
@@ -129,17 +129,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
 	private void startFeedExecutor() {
 		if (fetcherStarted.getAndSet(true)) return;
 		LOG.info("Tor started, scheduling RSS feed fetcher");
-		Runnable fetcher = new Runnable() {
-			@Override
-			public void run() {
-				ioExecutor.execute(new Runnable() {
-					@Override
-					public void run() {
-						fetchFeeds();
-					}
-				});
-			}
-		};
+		Runnable fetcher = () -> ioExecutor.execute(this::fetchFeeds);
 		scheduler.scheduleWithFixedDelay(fetcher, FETCH_DELAY_INITIAL,
 				FETCH_INTERVAL, FETCH_UNIT);
 	}
@@ -154,7 +144,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
 		db.addGroup(txn, g);
 
 		// Add initial metadata
-		List<Feed> feeds = new ArrayList<Feed>(0);
+		List<Feed> feeds = new ArrayList<>(0);
 		storeFeeds(txn, feeds);
 	}
 
@@ -237,7 +227,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
 	}
 
 	private List<Feed> getFeeds(Transaction txn) throws DbException {
-		List<Feed> feeds = new ArrayList<Feed>();
+		List<Feed> feeds = new ArrayList<>();
 		Group g = getLocalGroup();
 		try {
 			BdfDictionary d =
@@ -300,15 +290,11 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
 		}
 
 		// Fetch and update all feeds
-		List<Feed> newFeeds = new ArrayList<Feed>(feeds.size());
+		List<Feed> newFeeds = new ArrayList<>(feeds.size());
 		for (Feed feed : feeds) {
 			try {
 				newFeeds.add(fetchFeed(feed));
-			} catch (IOException e) {
-				if (LOG.isLoggable(WARNING))
-					LOG.log(WARNING, e.toString(), e);
-				newFeeds.add(feed);
-			} catch (DbException e) {
+			} catch (IOException | DbException e) {
 				if (LOG.isLoggable(WARNING))
 					LOG.log(WARNING, e.toString(), e);
 				newFeeds.add(feed);
@@ -391,9 +377,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
 		SyndFeedInput input = new SyndFeedInput();
 		try {
 			return input.build(new XmlReader(stream));
-		} catch (IllegalArgumentException e) {
-			throw new IOException(e);
-		} catch (FeedException e) {
+		} catch (IllegalArgumentException | FeedException e) {
 			throw new IOException(e);
 		}
 	}
@@ -479,13 +463,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
 			BlogPost post = blogPostFactory
 					.createBlogPost(groupId, time, null, localAuthor, body);
 			blogManager.addLocalPost(txn, post);
-		} catch (DbException e) {
-			if (LOG.isLoggable(WARNING))
-				LOG.log(WARNING, e.toString(), e);
-		} catch (GeneralSecurityException e) {
-			if (LOG.isLoggable(WARNING))
-				LOG.log(WARNING, e.toString(), e);
-		} catch (FormatException e) {
+		} catch (DbException | GeneralSecurityException | FormatException e) {
 			if (LOG.isLoggable(WARNING))
 				LOG.log(WARNING, e.toString(), e);
 		} catch (IllegalArgumentException e) {
@@ -502,23 +480,18 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
 	}
 
 	private Comparator<SyndEntry> getEntryComparator() {
-		return new Comparator<SyndEntry>() {
-			@Override
-			public int compare(SyndEntry e1, SyndEntry e2) {
-				Date d1 =
-						e1.getPublishedDate() != null ? e1.getPublishedDate() :
-								e1.getUpdatedDate();
-				Date d2 =
-						e2.getPublishedDate() != null ? e2.getPublishedDate() :
-								e2.getUpdatedDate();
-				if (d1 == null && d2 == null) return 0;
-				if (d1 == null) return -1;
-				if (d2 == null) return 1;
-
-				if (d1.after(d2)) return 1;
-				if (d1.before(d2)) return -1;
-				return 0;
-			}
+		return (e1, e2) -> {
+			Date d1 = e1.getPublishedDate() != null ? e1.getPublishedDate() :
+							e1.getUpdatedDate();
+			Date d2 = e2.getPublishedDate() != null ? e2.getPublishedDate() :
+							e2.getUpdatedDate();
+			if (d1 == null && d2 == null) return 0;
+			if (d1 == null) return -1;
+			if (d2 == null) return 1;
+
+			if (d1.after(d2)) return 1;
+			if (d1.before(d2)) return -1;
+			return 0;
 		};
 	}
 
diff --git a/briar-core/src/main/java/org/briarproject/briar/forum/ForumManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/forum/ForumManagerImpl.java
index f9328d2827af19baa1500172370d1cf523270127..23a7c24bf5402647f63b4a53cfccaa5019d8c7b2 100644
--- a/briar-core/src/main/java/org/briarproject/briar/forum/ForumManagerImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/forum/ForumManagerImpl.java
@@ -75,7 +75,7 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
 		this.forumFactory = forumFactory;
 		this.forumPostFactory = forumPostFactory;
 		this.messageTracker = messageTracker;
-		removeHooks = new CopyOnWriteArrayList<RemoveForumHook>();
+		removeHooks = new CopyOnWriteArrayList<>();
 	}
 
 	@Override
@@ -127,16 +127,13 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
 	}
 
 	@Override
-	public ForumPost createLocalPost(final GroupId groupId, final String body,
-			final long timestamp, final @Nullable MessageId parentId,
-			final LocalAuthor author) {
+	public ForumPost createLocalPost(GroupId groupId, String body,
+			long timestamp, @Nullable MessageId parentId, LocalAuthor author) {
 		ForumPost p;
 		try {
 			p = forumPostFactory.createPost(groupId, timestamp, parentId,
 					author, body);
-		} catch (GeneralSecurityException e) {
-			throw new RuntimeException(e);
-		} catch (FormatException e) {
+		} catch (GeneralSecurityException | FormatException e) {
 			throw new RuntimeException(e);
 		}
 		return p;
@@ -203,7 +200,7 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
 			} finally {
 				db.endTransaction(txn);
 			}
-			List<Forum> forums = new ArrayList<Forum>();
+			List<Forum> forums = new ArrayList<>();
 			for (Group g : groups) forums.add(parseForum(g));
 			return forums;
 		} catch (FormatException e) {
@@ -232,13 +229,13 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
 	public Collection<ForumPostHeader> getPostHeaders(GroupId g)
 			throws DbException {
 
-		Collection<ForumPostHeader> headers = new ArrayList<ForumPostHeader>();
+		Collection<ForumPostHeader> headers = new ArrayList<>();
 		Transaction txn = db.startTransaction(true);
 		try {
 			Map<MessageId, BdfDictionary> metadata =
 					clientHelper.getMessageMetadataAsDictionary(txn, g);
 			// get all authors we need to get the status for
-			Set<AuthorId> authors = new HashSet<AuthorId>();
+			Set<AuthorId> authors = new HashSet<>();
 			for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
 				BdfDictionary d =
 						entry.getValue().getDictionary(KEY_AUTHOR, null);
@@ -246,7 +243,7 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
 					authors.add(new AuthorId(d.getRaw(KEY_ID)));
 			}
 			// get statuses for all authors
-			Map<AuthorId, Status> statuses = new HashMap<AuthorId, Status>();
+			Map<AuthorId, Status> statuses = new HashMap<>();
 			for (AuthorId id : authors) {
 				statuses.put(id, identityManager.getAuthorStatus(txn, id));
 			}
@@ -290,8 +287,7 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
 
 	private ForumPostHeader getForumPostHeader(Transaction txn, MessageId id,
 			BdfDictionary meta) throws DbException, FormatException {
-		return getForumPostHeader(txn, id, meta,
-				Collections.<AuthorId, Status>emptyMap());
+		return getForumPostHeader(txn, id, meta, Collections.emptyMap());
 	}
 
 	private ForumPostHeader getForumPostHeader(Transaction txn, MessageId id,
diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeEngine.java b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeEngine.java
index 74ecc946a3215c373be52709912319e393e76222..2d5bb95c3ad591c57b5aabb0889f48c4803d93ab 100644
--- a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeEngine.java
+++ b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeEngine.java
@@ -106,7 +106,7 @@ class IntroduceeEngine
 				else return abortSession(currentState, localState);
 			}
 
-			List<BdfDictionary> messages = new ArrayList<BdfDictionary>(1);
+			List<BdfDictionary> messages = new ArrayList<>(1);
 			if (action == LOCAL_ACCEPT || action == LOCAL_DECLINE) {
 				localState.put(STATE, nextState.getValue());
 				localState.put(ANSWERED, true);
@@ -136,8 +136,7 @@ class IntroduceeEngine
 				throw new IllegalArgumentException();
 			}
 			List<Event> events = Collections.emptyList();
-			return new StateUpdate<BdfDictionary, BdfDictionary>(false,
-					false,
+			return new StateUpdate<>(false, false,
 					localState, messages, events);
 		} catch (FormatException e) {
 			throw new IllegalArgumentException(e);
@@ -204,16 +203,15 @@ class IntroduceeEngine
 			}
 			// we are done (probably declined response), ignore & delete message
 			else if (currentState == FINISHED) {
-				return new StateUpdate<BdfDictionary, BdfDictionary>(true,
-						false, localState,
+				return new StateUpdate<>(true, false, localState,
 						Collections.<BdfDictionary>emptyList(),
-						Collections.<Event>emptyList());
+						Collections.emptyList());
 			}
 			// this should not happen
 			else {
 				throw new IllegalArgumentException();
 			}
-			return new StateUpdate<BdfDictionary, BdfDictionary>(false, false,
+			return new StateUpdate<>(false, false,
 					localState, messages, events);
 		} catch (FormatException e) {
 			throw new IllegalArgumentException(e);
@@ -361,15 +359,14 @@ class IntroduceeEngine
 		Event event = new IntroductionAbortedEvent(contactId, sessionId);
 		List<Event> events = Collections.singletonList(event);
 
-		return new StateUpdate<BdfDictionary, BdfDictionary>(false, false,
-				localState, messages, events);
+		return new StateUpdate<>(false, false, localState, messages, events);
 	}
 
 	private StateUpdate<BdfDictionary, BdfDictionary> noUpdate(
 			BdfDictionary localState) throws FormatException {
 
-		return new StateUpdate<BdfDictionary, BdfDictionary>(false, false,
-				localState, Collections.<BdfDictionary>emptyList(),
-				Collections.<Event>emptyList());
+		return new StateUpdate<>(false, false, localState,
+				Collections.<BdfDictionary>emptyList(),
+				Collections.emptyList());
 	}
 }
diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeManager.java b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeManager.java
index 588f5396537cf6ab810c510c466680ab226f6fbb..f074700aef3c1ec7c9093e9155068852bf82cb64 100644
--- a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeManager.java
+++ b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeManager.java
@@ -519,9 +519,7 @@ class IntroduceeManager {
 		try {
 			processStateUpdate(txn, null,
 					engine.onLocalAction(state, localAction));
-		} catch (DbException e) {
-			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-		} catch (IOException e) {
+		} catch (DbException | IOException e) {
 			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 		}
 	}
@@ -539,8 +537,7 @@ class IntroduceeManager {
 	private Map<TransportId, TransportProperties> parseTransportProperties(
 			BdfDictionary d) throws FormatException {
 
-		Map<TransportId, TransportProperties> tpMap =
-				new HashMap<TransportId, TransportProperties>();
+		Map<TransportId, TransportProperties> tpMap = new HashMap<>();
 		BdfDictionary tpMapDict = d.getDictionary(TRANSPORT);
 		for (String key : tpMapDict.keySet()) {
 			TransportId transportId = new TransportId(key);
diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroducerEngine.java b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroducerEngine.java
index b0cffd95ba3596378b4b7fa32892be21554b14e2..df364b34ff0f7cdc39e4c607678ae6cdb1e64398 100644
--- a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroducerEngine.java
+++ b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroducerEngine.java
@@ -102,7 +102,7 @@ class IntroducerEngine
 			localState.put(STATE, nextState.getValue());
 			if (action == LOCAL_REQUEST) {
 				// create the introduction requests for both contacts
-				List<BdfDictionary> messages = new ArrayList<BdfDictionary>(2);
+				List<BdfDictionary> messages = new ArrayList<>(2);
 				BdfDictionary msg1 = new BdfDictionary();
 				msg1.put(TYPE, TYPE_REQUEST);
 				msg1.put(SESSION_ID, localState.getRaw(SESSION_ID));
@@ -129,8 +129,7 @@ class IntroducerEngine
 				logLocalAction(currentState, localState);
 
 				List<Event> events = Collections.emptyList();
-				return new StateUpdate<BdfDictionary, BdfDictionary>(false,
-						false,
+				return new StateUpdate<>(false, false,
 						localState, messages, events);
 			} else {
 				throw new IllegalArgumentException("Unknown Local Action");
@@ -206,7 +205,7 @@ class IntroducerEngine
 			} else {
 				throw new IllegalArgumentException("Bad state");
 			}
-			return new StateUpdate<BdfDictionary, BdfDictionary>(false, false,
+			return new StateUpdate<>(false, false,
 					localState, messages, events);
 		} catch (FormatException e) {
 			throw new IllegalArgumentException(e);
@@ -334,7 +333,7 @@ class IntroducerEngine
 					currentState.name());
 
 		localState.put(STATE, ERROR.getValue());
-		List<BdfDictionary> messages = new ArrayList<BdfDictionary>(2);
+		List<BdfDictionary> messages = new ArrayList<>(2);
 		BdfDictionary msg1 = new BdfDictionary();
 		msg1.put(TYPE, TYPE_ABORT);
 		msg1.put(SESSION_ID, localState.getRaw(SESSION_ID));
@@ -347,7 +346,7 @@ class IntroducerEngine
 		messages.add(msg2);
 
 		// send one abort event per contact
-		List<Event> events = new ArrayList<Event>(2);
+		List<Event> events = new ArrayList<>(2);
 		SessionId sessionId = new SessionId(localState.getRaw(SESSION_ID));
 		ContactId contactId1 =
 				new ContactId(localState.getLong(CONTACT_ID_1).intValue());
@@ -358,15 +357,14 @@ class IntroducerEngine
 		Event event2 = new IntroductionAbortedEvent(contactId2, sessionId);
 		events.add(event2);
 
-		return new StateUpdate<BdfDictionary, BdfDictionary>(false, false,
-				localState, messages, events);
+		return new StateUpdate<>(false, false, localState, messages, events);
 	}
 
 	private StateUpdate<BdfDictionary, BdfDictionary> noUpdate(
 			BdfDictionary localState) throws FormatException {
 
-		return new StateUpdate<BdfDictionary, BdfDictionary>(false, false,
-				localState, Collections.<BdfDictionary>emptyList(),
-				Collections.<Event>emptyList());
+		return new StateUpdate<>(false, false, localState,
+				Collections.<BdfDictionary>emptyList(),
+				Collections.emptyList());
 	}
 }
diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroducerManager.java b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroducerManager.java
index 09b6975adb02edebe9e843ab94a77444e46d2506..b24109396c7f634c8668ff9aea64dca16750cca8 100644
--- a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroducerManager.java
+++ b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroducerManager.java
@@ -173,9 +173,7 @@ class IntroducerManager {
 		try {
 			processStateUpdate(txn,
 					engine.onLocalAction(state, localAction));
-		} catch (DbException e) {
-			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-		} catch (IOException e) {
+		} catch (DbException | IOException e) {
 			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 		}
 	}
diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionManagerImpl.java
index 6ed619249ce6d9845b7328b54a16cf348a0c65f1..053c0760581769477c57cc5c107192a16a9142e2 100644
--- a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionManagerImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionManagerImpl.java
@@ -251,12 +251,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
 						LOG.warning("Unknown role '" + role + "'");
 					throw new DbException();
 				}
-			} catch (DbException e) {
-				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
-				if (role == ROLE_INTRODUCER) introducerManager.abort(txn, state);
-				else introduceeManager.abort(txn, state);
-			} catch (FormatException e) {
-				// FIXME necessary?
+			} catch (DbException | FormatException e) {
 				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 				if (role == ROLE_INTRODUCER) introducerManager.abort(txn, state);
 				else introduceeManager.abort(txn, state);
@@ -277,7 +272,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
 
 	@Override
 	public void makeIntroduction(Contact c1, Contact c2, @Nullable String msg,
-			final long timestamp) throws DbException, FormatException {
+			long timestamp) throws DbException, FormatException {
 
 		Transaction txn = db.startTransaction(false);
 		try {
@@ -293,9 +288,8 @@ class IntroductionManagerImpl extends ConversationClientImpl
 	}
 
 	@Override
-	public void acceptIntroduction(final ContactId contactId,
-			final SessionId sessionId, final long timestamp)
-			throws DbException, FormatException {
+	public void acceptIntroduction(ContactId contactId, SessionId sessionId,
+			long timestamp) throws DbException, FormatException {
 
 		Transaction txn = db.startTransaction(false);
 		try {
@@ -313,9 +307,8 @@ class IntroductionManagerImpl extends ConversationClientImpl
 	}
 
 	@Override
-	public void declineIntroduction(final ContactId contactId,
-			final SessionId sessionId, final long timestamp)
-			throws DbException, FormatException {
+	public void declineIntroduction(ContactId contactId, SessionId sessionId,
+			long timestamp) throws DbException, FormatException {
 
 		Transaction txn = db.startTransaction(false);
 		try {
@@ -336,8 +329,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
 	public Collection<IntroductionMessage> getIntroductionMessages(
 			ContactId contactId) throws DbException {
 
-		Collection<IntroductionMessage> list =
-				new ArrayList<IntroductionMessage>();
+		Collection<IntroductionMessage> list = new ArrayList<>();
 
 		Map<MessageId, BdfDictionary> metadata;
 		Collection<MessageStatus> statuses;
diff --git a/briar-core/src/main/java/org/briarproject/briar/messaging/ConversationManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/messaging/ConversationManagerImpl.java
index 6d310756ca98a286095c41b4642de1aa1541de91..95aef43c6c2772168125a654184b8d1b77375b0b 100644
--- a/briar-core/src/main/java/org/briarproject/briar/messaging/ConversationManagerImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/messaging/ConversationManagerImpl.java
@@ -24,7 +24,7 @@ class ConversationManagerImpl implements ConversationManager {
 	@Inject
 	ConversationManagerImpl(DatabaseComponent db) {
 		this.db = db;
-		clients = new CopyOnWriteArraySet<ConversationClient>();
+		clients = new CopyOnWriteArraySet<>();
 	}
 
 	@Override
diff --git a/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java
index 28a4726b064db48e73c506c83e09a5c7f6d7ff91..2305dd47bed4b5c0e251add9fad57a5fd7acb519 100644
--- a/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java
@@ -176,8 +176,7 @@ class MessagingManagerImpl extends ConversationClientImpl
 		} finally {
 			db.endTransaction(txn);
 		}
-		Collection<PrivateMessageHeader> headers =
-				new ArrayList<PrivateMessageHeader>();
+		Collection<PrivateMessageHeader> headers = new ArrayList<>();
 		for (MessageStatus s : statuses) {
 			MessageId id = s.getMessageId();
 			BdfDictionary meta = metadata.get(id);
diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/GroupMessageFactoryImpl.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/GroupMessageFactoryImpl.java
index 5c2b9fc8de590c42e3b495400fa93619921afca6..7f0404872a1440886232d914a78b65dafd1bde76 100644
--- a/briar-core/src/main/java/org/briarproject/briar/privategroup/GroupMessageFactoryImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/GroupMessageFactoryImpl.java
@@ -63,9 +63,7 @@ class GroupMessageFactoryImpl implements GroupMessageFactory {
 			Message m = clientHelper.createMessage(groupId, timestamp, body);
 
 			return new GroupMessage(m, null, member);
-		} catch (GeneralSecurityException e) {
-			throw new RuntimeException(e);
-		} catch (FormatException e) {
+		} catch (GeneralSecurityException | FormatException e) {
 			throw new RuntimeException(e);
 		}
 	}
@@ -91,9 +89,7 @@ class GroupMessageFactoryImpl implements GroupMessageFactory {
 			Message m = clientHelper.createMessage(groupId, timestamp, body);
 
 			return new GroupMessage(m, parentId, author);
-		} catch (GeneralSecurityException e) {
-			throw new RuntimeException(e);
-		} catch (FormatException e) {
+		} catch (GeneralSecurityException | FormatException e) {
 			throw new RuntimeException(e);
 		}
 	}
diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/GroupMessageValidator.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/GroupMessageValidator.java
index 94089cdb5e601ad6e3d0799ad661f42bdbc0776d..872da6fb969612e347fa1af93dd782fa1d481158 100644
--- a/briar-core/src/main/java/org/briarproject/briar/privategroup/GroupMessageValidator.java
+++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/GroupMessageValidator.java
@@ -202,7 +202,7 @@ class GroupMessageValidator extends BdfMessageValidator {
 
 		// The parent post, if any,
 		// and the member's previous message are dependencies
-		Collection<MessageId> dependencies = new ArrayList<MessageId>();
+		Collection<MessageId> dependencies = new ArrayList<>();
 		if (parentId != null) dependencies.add(new MessageId(parentId));
 		dependencies.add(new MessageId(previousMessageId));
 
diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/PrivateGroupManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/PrivateGroupManagerImpl.java
index d0becaecd710a91a6c2f15cca60707930abab7f9..28c547a5da4b1a67d713dbd4ed63a17c631908e7 100644
--- a/briar-core/src/main/java/org/briarproject/briar/privategroup/PrivateGroupManagerImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/PrivateGroupManagerImpl.java
@@ -100,7 +100,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
 		this.contactManager = contactManager;
 		this.identityManager = identityManager;
 		this.messageTracker = messageTracker;
-		hooks = new CopyOnWriteArrayList<PrivateGroupHook>();
+		hooks = new CopyOnWriteArrayList<>();
 	}
 
 	@Override
@@ -284,7 +284,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
 		}
 		try {
 			Collection<PrivateGroup> privateGroups =
-					new ArrayList<PrivateGroup>(groups.size());
+					new ArrayList<>(groups.size());
 			for (Group g : groups) {
 				privateGroups.add(privateGroupFactory.parsePrivateGroup(g));
 			}
@@ -324,20 +324,19 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
 	@Override
 	public Collection<GroupMessageHeader> getHeaders(GroupId g)
 			throws DbException {
-		Collection<GroupMessageHeader> headers =
-				new ArrayList<GroupMessageHeader>();
+		Collection<GroupMessageHeader> headers = new ArrayList<>();
 		Transaction txn = db.startTransaction(true);
 		try {
 			Map<MessageId, BdfDictionary> metadata =
 					clientHelper.getMessageMetadataAsDictionary(txn, g);
 			// get all authors we need to get the status for
-			Set<AuthorId> authors = new HashSet<AuthorId>();
+			Set<AuthorId> authors = new HashSet<>();
 			for (BdfDictionary meta : metadata.values()) {
 				byte[] idBytes = meta.getRaw(KEY_MEMBER_ID);
 				authors.add(new AuthorId(idBytes));
 			}
 			// get statuses for all authors
-			Map<AuthorId, Status> statuses = new HashMap<AuthorId, Status>();
+			Map<AuthorId, Status> statuses = new HashMap<>();
 			for (AuthorId id : authors) {
 				statuses.put(id, identityManager.getAuthorStatus(txn, id));
 			}
@@ -404,7 +403,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
 	public Collection<GroupMember> getMembers(GroupId g) throws DbException {
 		Transaction txn = db.startTransaction(true);
 		try {
-			Collection<GroupMember> members = new ArrayList<GroupMember>();
+			Collection<GroupMember> members = new ArrayList<>();
 			Map<Author, Visibility> authors = getMembers(txn, g);
 			LocalAuthor la = identityManager.getLocalAuthor(txn);
 			PrivateGroup privateGroup = getPrivateGroup(txn, g);
@@ -434,8 +433,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
 			BdfDictionary meta =
 					clientHelper.getGroupMetadataAsDictionary(txn, g);
 			BdfList list = meta.getList(GROUP_KEY_MEMBERS);
-			Map<Author, Visibility> members =
-					new HashMap<Author, Visibility>(list.size());
+			Map<Author, Visibility> members = new HashMap<>(list.size());
 			for (int i = 0; i < list.size(); i++) {
 				BdfDictionary d = list.getDictionary(i);
 				Author member = getAuthor(d);
@@ -584,7 +582,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
 			BdfDictionary meta, boolean local)
 			throws DbException, FormatException {
 		GroupMessageHeader header = getGroupMessageHeader(txn, m.getGroupId(),
-				m.getId(), meta, Collections.<AuthorId, Status>emptyMap());
+				m.getId(), meta, Collections.emptyMap());
 		String body = getMessageBody(clientHelper.toList(m));
 		txn.attach(new GroupMessageAddedEvent(m.getGroupId(), header, body,
 				local));
@@ -594,7 +592,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
 			BdfDictionary meta, boolean local, Visibility v)
 			throws DbException, FormatException {
 		JoinMessageHeader header = getJoinMessageHeader(txn, m.getGroupId(),
-				m.getId(), meta, Collections.<AuthorId, Status>emptyMap(), v);
+				m.getId(), meta, Collections.emptyMap(), v);
 		txn.attach(new GroupMessageAddedEvent(m.getGroupId(), header, "",
 				local));
 	}
diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java
index cbc26bb4a66f81efc710796c4d1bc4affbb86d7a..1ae598c837aa6796dde6257e50a8baa561f33a48 100644
--- a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java
@@ -366,7 +366,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
 			BdfDictionary query = messageParser.getMessagesVisibleInUiQuery();
 			Map<MessageId, BdfDictionary> results = clientHelper
 					.getMessageMetadataAsDictionary(txn, contactGroupId, query);
-			messages = new ArrayList<InvitationMessage>(results.size());
+			messages = new ArrayList<>(results.size());
 			for (Entry<MessageId, BdfDictionary> e : results.entrySet()) {
 				MessageId m = e.getKey();
 				MessageMetadata meta =
@@ -427,7 +427,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
 
 	@Override
 	public Collection<GroupInvitationItem> getInvitations() throws DbException {
-		List<GroupInvitationItem> items = new ArrayList<GroupInvitationItem>();
+		List<GroupInvitationItem> items = new ArrayList<>();
 		BdfDictionary query = messageParser.getInvitesAvailableToAnswerQuery();
 		Transaction txn = db.startTransaction(true);
 		try {
diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParserImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParserImpl.java
index d09055626e8cb84f54681151623b27f7fd2af916..eb294975acfd578d6e9dd12cf4b5c0aca453aa7d 100644
--- a/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParserImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParserImpl.java
@@ -17,10 +17,10 @@ import javax.annotation.concurrent.Immutable;
 
 import static org.briarproject.briar.sharing.MessageType.INVITE;
 import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_AVAILABLE_TO_ANSWER;
+import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_INVITATION_ACCEPTED;
 import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_LOCAL;
 import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_MESSAGE_TYPE;
 import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_READ;
-import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_INVITATION_ACCEPTED;
 import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_SHAREABLE_ID;
 import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_TIMESTAMP;
 import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_VISIBLE_IN_UI;
@@ -91,7 +91,7 @@ abstract class MessageParserImpl<S extends Shareable>
 		BdfList descriptor = body.getList(2);
 		S shareable = createShareable(descriptor);
 		String message = body.getOptionalString(3);
-		return new InviteMessage<S>(m.getId(), previousMessageId,
+		return new InviteMessage<>(m.getId(), previousMessageId,
 				m.getGroupId(), shareable, message, m.getTimestamp());
 	}
 
diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java
index c03ee5eb538154a6ff636e47d4ec607dd1b0cbd1..75ab728ff85b16f00b0a8989b6ef58f611c674b8 100644
--- a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java
@@ -311,7 +311,7 @@ abstract class SharingManagerImpl<S extends Shareable>
 			BdfDictionary query = messageParser.getMessagesVisibleInUiQuery();
 			Map<MessageId, BdfDictionary> results = clientHelper
 					.getMessageMetadataAsDictionary(txn, contactGroupId, query);
-			messages = new ArrayList<InvitationMessage>(results.size());
+			messages = new ArrayList<>(results.size());
 			for (Entry<MessageId, BdfDictionary> e : results.entrySet()) {
 				MessageId m = e.getKey();
 				MessageMetadata meta =
@@ -367,11 +367,9 @@ abstract class SharingManagerImpl<S extends Shareable>
 	@Override
 	public Collection<SharingInvitationItem> getInvitations()
 			throws DbException {
-		List<SharingInvitationItem> items =
-				new ArrayList<SharingInvitationItem>();
+		List<SharingInvitationItem> items = new ArrayList<>();
 		BdfDictionary query = messageParser.getInvitesAvailableToAnswerQuery();
-		Map<S, Collection<Contact>> sharers =
-				new HashMap<S, Collection<Contact>>();
+		Map<S, Collection<Contact>> sharers = new HashMap<>();
 		Transaction txn = db.startTransaction(true);
 		try {
 			// get invitations from each contact
@@ -387,7 +385,7 @@ abstract class SharingManagerImpl<S extends Shareable>
 					if (sharers.containsKey(s)) {
 						sharers.get(s).add(c);
 					} else {
-						Collection<Contact> contacts = new ArrayList<Contact>();
+						Collection<Contact> contacts = new ArrayList<>();
 						contacts.add(c);
 						sharers.put(s, contacts);
 					}
@@ -414,7 +412,7 @@ abstract class SharingManagerImpl<S extends Shareable>
 	@Override
 	public Collection<Contact> getSharedWith(GroupId g) throws DbException {
 		// TODO report also pending invitations
-		Collection<Contact> contacts = new ArrayList<Contact>();
+		Collection<Contact> contacts = new ArrayList<>();
 		Transaction txn = db.startTransaction(true);
 		try {
 			for (Contact c : db.getContacts(txn)) {
diff --git a/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java b/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java
index bbc5e4c120e6b940709cc76ad500ecf1c94234a6..b9a91694f46cb4ad95c6b35d9dbfce49a27d1e81 100644
--- a/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java
@@ -88,8 +88,7 @@ public class TestDataCreatorImpl implements TestDataCreator {
 	private final Executor ioExecutor;
 
 	private final Random random = new Random();
-	private final Map<Contact, LocalAuthor> localAuthors =
-			new HashMap<Contact, LocalAuthor>();
+	private final Map<Contact, LocalAuthor> localAuthors = new HashMap<>();
 
 	@Inject
 	TestDataCreatorImpl(AuthorFactory authorFactory, Clock clock,
@@ -119,16 +118,12 @@ public class TestDataCreatorImpl implements TestDataCreator {
 	}
 
 	public void createTestData() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					createTestDataOnDbExecutor();
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING)) {
-						LOG.log(WARNING, "Creating test data failed", e);
-					}
-				}
+		ioExecutor.execute(() -> {
+			try {
+				createTestDataOnDbExecutor();
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, "Creating test data failed", e);
 			}
 		});
 	}
@@ -146,7 +141,7 @@ public class TestDataCreatorImpl implements TestDataCreator {
 	}
 
 	private List<Contact> createContacts() throws DbException {
-		List<Contact> contacts = new ArrayList<Contact>(NUM_CONTACTS);
+		List<Contact> contacts = new ArrayList<>(NUM_CONTACTS);
 		LocalAuthor localAuthor = identityManager.getLocalAuthor();
 		for (int i = 0; i < NUM_CONTACTS; i++) {
 			Contact contact = addRandomContact(localAuthor);
@@ -206,8 +201,7 @@ public class TestDataCreatorImpl implements TestDataCreator {
 	}
 
 	private Map<TransportId, TransportProperties> getRandomTransportProperties() {
-		Map<TransportId, TransportProperties> props =
-				new HashMap<TransportId, TransportProperties>();
+		Map<TransportId, TransportProperties> props = new HashMap<>();
 
 		// Bluetooth
 		TransportProperties bt = new TransportProperties();
@@ -330,16 +324,14 @@ public class TestDataCreatorImpl implements TestDataCreator {
 					.createBlogPost(blog.getId(), timestamp, null, author,
 							body);
 			blogManager.addLocalPost(blogPost);
-		} catch (FormatException e) {
-			throw new RuntimeException(e);
-		} catch (GeneralSecurityException e) {
+		} catch (FormatException | GeneralSecurityException e) {
 			throw new RuntimeException(e);
 		}
 	}
 
 	private List<Forum> createForums(List<Contact> contacts)
 			throws DbException {
-		List<Forum> forums = new ArrayList<Forum>(NUM_FORUMS);
+		List<Forum> forums = new ArrayList<>(NUM_FORUMS);
 		for (int i = 0; i < NUM_FORUMS; i++) {
 			// create forum
 			String name = GROUP_NAMES[random.nextInt(GROUP_NAMES.length)];
@@ -367,7 +359,7 @@ public class TestDataCreatorImpl implements TestDataCreator {
 
 	private void createRandomForumPosts(Forum forum, List<Contact> contacts)
 			throws DbException {
-		List<ForumPost> posts = new ArrayList<ForumPost>();
+		List<ForumPost> posts = new ArrayList<>();
 		for (int i = 0; i < NUM_FORUM_POSTS; i++) {
 			Contact contact = contacts.get(random.nextInt(contacts.size()));
 			LocalAuthor author = localAuthors.get(contact);
diff --git a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerImplTest.java
index f34f37a8eca8878b56a6df7daa1f288fd1713193..49a50a219fb752fa1f347a14f9856ac969e19cc3 100644
--- a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerImplTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerImplTest.java
@@ -111,7 +111,7 @@ public class BlogManagerImplTest extends BriarTestCase {
 
 	@Test
 	public void testCreateLocalState() throws DbException {
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			oneOf(identityManager).getLocalAuthor(txn);
@@ -127,9 +127,9 @@ public class BlogManagerImplTest extends BriarTestCase {
 
 	@Test
 	public void testRemovingContact() throws DbException {
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 
-		final ContactId contactId = new ContactId(0);
+		ContactId contactId = new ContactId(0);
 		Contact contact = new Contact(contactId, blog2.getAuthor(),
 				blog1.getAuthor().getId(), true, true);
 
@@ -149,9 +149,9 @@ public class BlogManagerImplTest extends BriarTestCase {
 
 	@Test
 	public void testRemovingContactAfterRemovingBlog() throws DbException {
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 
-		final ContactId contactId = new ContactId(0);
+		ContactId contactId = new ContactId(0);
 		Contact contact = new Contact(contactId, blog2.getAuthor(),
 				blog1.getAuthor().getId(), true, true);
 
@@ -168,7 +168,7 @@ public class BlogManagerImplTest extends BriarTestCase {
 
 	@Test
 	public void testIncomingMessage() throws DbException, FormatException {
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 		BdfList body = BdfList.of("body");
 		BdfDictionary meta = BdfDictionary.of(
 				new BdfEntry(KEY_TYPE, POST.getInt()),
@@ -207,7 +207,7 @@ public class BlogManagerImplTest extends BriarTestCase {
 
 	@Test
 	public void testIncomingRssMessage() throws DbException, FormatException {
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 		BdfList body = BdfList.of("body");
 		BdfDictionary meta = BdfDictionary.of(
 				new BdfEntry(KEY_TYPE, POST.getInt()),
@@ -241,7 +241,7 @@ public class BlogManagerImplTest extends BriarTestCase {
 
 	@Test
 	public void testRemoveBlog() throws Exception {
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(false);
@@ -259,9 +259,9 @@ public class BlogManagerImplTest extends BriarTestCase {
 
 	@Test
 	public void testAddLocalPost() throws DbException, FormatException {
-		final Transaction txn = new Transaction(null, false);
-		final BlogPost post = new BlogPost(message, null, localAuthor1);
-		final BdfDictionary meta = BdfDictionary.of(
+		Transaction txn = new Transaction(null, false);
+		BlogPost post = new BlogPost(message, null, localAuthor1);
+		BdfDictionary meta = BdfDictionary.of(
 				new BdfEntry(KEY_TYPE, POST.getInt()),
 				new BdfEntry(KEY_TIMESTAMP, timestamp),
 				new BdfEntry(KEY_AUTHOR, authorDict1),
@@ -305,9 +305,9 @@ public class BlogManagerImplTest extends BriarTestCase {
 
 	@Test
 	public void testAddLocalRssPost() throws DbException, FormatException {
-		final Transaction txn = new Transaction(null, false);
-		final BlogPost post = new BlogPost(rssMessage, null, rssLocalAuthor);
-		final BdfDictionary meta = BdfDictionary.of(
+		Transaction txn = new Transaction(null, false);
+		BlogPost post = new BlogPost(rssMessage, null, rssLocalAuthor);
+		BdfDictionary meta = BdfDictionary.of(
 				new BdfEntry(KEY_TYPE, POST.getInt()),
 				new BdfEntry(KEY_TIMESTAMP, timestamp),
 				new BdfEntry(KEY_AUTHOR, rssAuthorDict),
@@ -350,10 +350,10 @@ public class BlogManagerImplTest extends BriarTestCase {
 
 	@Test
 	public void testAddLocalCommentToLocalPost() throws Exception {
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 		// The post was originally posted to blog 1, then reblogged to the
 		// same blog (commenting on own post)
-		final BdfDictionary postMeta = BdfDictionary.of(
+		BdfDictionary postMeta = BdfDictionary.of(
 				new BdfEntry(KEY_TYPE, POST.getInt()),
 				new BdfEntry(KEY_RSS_FEED, false),
 				new BdfEntry(KEY_ORIGINAL_MSG_ID, messageId),
@@ -361,10 +361,10 @@ public class BlogManagerImplTest extends BriarTestCase {
 				new BdfEntry(KEY_TIMESTAMP, timestamp),
 				new BdfEntry(KEY_TIME_RECEIVED, timeReceived)
 		);
-		final MessageId commentId = new MessageId(getRandomId());
-		final Message commentMsg = new Message(commentId, blog1.getId(),
+		MessageId commentId = new MessageId(getRandomId());
+		Message commentMsg = new Message(commentId, blog1.getId(),
 				timestamp, getRandomBytes(MAX_MESSAGE_LENGTH));
-		final BdfDictionary commentMeta = BdfDictionary.of(
+		BdfDictionary commentMeta = BdfDictionary.of(
 				new BdfEntry(KEY_TYPE, COMMENT.getInt()),
 				new BdfEntry(KEY_COMMENT, comment),
 				new BdfEntry(KEY_TIMESTAMP, timestamp),
@@ -436,14 +436,14 @@ public class BlogManagerImplTest extends BriarTestCase {
 
 	@Test
 	public void testAddLocalCommentToRemotePost() throws Exception {
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 		// The post was originally posted to blog 1, then reblogged to
 		// blog 2 with a comment
-		final BdfList originalPostBody = BdfList.of("originalPostBody");
-		final MessageId wrappedPostId = new MessageId(getRandomId());
-		final Message wrappedPostMsg = new Message(wrappedPostId, blog2.getId(),
+		BdfList originalPostBody = BdfList.of("originalPostBody");
+		MessageId wrappedPostId = new MessageId(getRandomId());
+		Message wrappedPostMsg = new Message(wrappedPostId, blog2.getId(),
 				timestamp, getRandomBytes(MAX_MESSAGE_LENGTH));
-		final BdfDictionary wrappedPostMeta = BdfDictionary.of(
+		BdfDictionary wrappedPostMeta = BdfDictionary.of(
 				new BdfEntry(KEY_TYPE, WRAPPED_POST.getInt()),
 				new BdfEntry(KEY_RSS_FEED, false),
 				new BdfEntry(KEY_ORIGINAL_MSG_ID, messageId),
@@ -451,10 +451,10 @@ public class BlogManagerImplTest extends BriarTestCase {
 				new BdfEntry(KEY_TIMESTAMP, timestamp),
 				new BdfEntry(KEY_TIME_RECEIVED, timeReceived)
 		);
-		final MessageId commentId = new MessageId(getRandomId());
-		final Message commentMsg = new Message(commentId, blog2.getId(),
+		MessageId commentId = new MessageId(getRandomId());
+		Message commentMsg = new Message(commentId, blog2.getId(),
 				timestamp, getRandomBytes(MAX_MESSAGE_LENGTH));
-		final BdfDictionary commentMeta = BdfDictionary.of(
+		BdfDictionary commentMeta = BdfDictionary.of(
 				new BdfEntry(KEY_TYPE, COMMENT.getInt()),
 				new BdfEntry(KEY_COMMENT, comment),
 				new BdfEntry(KEY_TIMESTAMP, timestamp),
@@ -539,14 +539,14 @@ public class BlogManagerImplTest extends BriarTestCase {
 
 	@Test
 	public void testAddLocalCommentToRemoteRssPost() throws Exception {
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 		// The post was originally posted to the RSS blog, then reblogged to
 		// blog 1 with a comment
-		final BdfList originalPostBody = BdfList.of("originalPostBody");
-		final MessageId wrappedPostId = new MessageId(getRandomId());
-		final Message wrappedPostMsg = new Message(wrappedPostId, blog1.getId(),
+		BdfList originalPostBody = BdfList.of("originalPostBody");
+		MessageId wrappedPostId = new MessageId(getRandomId());
+		Message wrappedPostMsg = new Message(wrappedPostId, blog1.getId(),
 				timestamp, getRandomBytes(MAX_MESSAGE_LENGTH));
-		final BdfDictionary wrappedPostMeta = BdfDictionary.of(
+		BdfDictionary wrappedPostMeta = BdfDictionary.of(
 				new BdfEntry(KEY_TYPE, WRAPPED_POST.getInt()),
 				new BdfEntry(KEY_RSS_FEED, true),
 				new BdfEntry(KEY_ORIGINAL_MSG_ID, rssMessageId),
@@ -554,10 +554,10 @@ public class BlogManagerImplTest extends BriarTestCase {
 				new BdfEntry(KEY_TIMESTAMP, timestamp),
 				new BdfEntry(KEY_TIME_RECEIVED, timeReceived)
 		);
-		final MessageId commentId = new MessageId(getRandomId());
-		final Message commentMsg = new Message(commentId, blog1.getId(),
+		MessageId commentId = new MessageId(getRandomId());
+		Message commentMsg = new Message(commentId, blog1.getId(),
 				timestamp, getRandomBytes(MAX_MESSAGE_LENGTH));
-		final BdfDictionary commentMeta = BdfDictionary.of(
+		BdfDictionary commentMeta = BdfDictionary.of(
 				new BdfEntry(KEY_TYPE, COMMENT.getInt()),
 				new BdfEntry(KEY_COMMENT, comment),
 				new BdfEntry(KEY_TIMESTAMP, timestamp),
@@ -640,18 +640,18 @@ public class BlogManagerImplTest extends BriarTestCase {
 
 	@Test
 	public void testAddLocalCommentToRebloggedRemoteRssPost() throws Exception {
-		final Transaction txn = new Transaction(null, false);
+		Transaction txn = new Transaction(null, false);
 		// The post was originally posted to the RSS blog, then reblogged to
 		// blog 1 with a comment
-		final MessageId wrappedPostId = new MessageId(getRandomId());
-		final BdfList wrappedPostBody = BdfList.of("wrappedPostBody");
-		final MessageId originalCommentId = new MessageId(getRandomId());
-		final BdfList originalCommentBody = BdfList.of("originalCommentBody");
+		MessageId wrappedPostId = new MessageId(getRandomId());
+		BdfList wrappedPostBody = BdfList.of("wrappedPostBody");
+		MessageId originalCommentId = new MessageId(getRandomId());
+		BdfList originalCommentBody = BdfList.of("originalCommentBody");
 		// The post and comment were reblogged to blog 2 with another comment
-		final MessageId rewrappedPostId = new MessageId(getRandomId());
-		final Message rewrappedPostMsg = new Message(rewrappedPostId,
+		MessageId rewrappedPostId = new MessageId(getRandomId());
+		Message rewrappedPostMsg = new Message(rewrappedPostId,
 				blog2.getId(), timestamp, getRandomBytes(MAX_MESSAGE_LENGTH));
-		final BdfDictionary rewrappedPostMeta = BdfDictionary.of(
+		BdfDictionary rewrappedPostMeta = BdfDictionary.of(
 				new BdfEntry(KEY_TYPE, WRAPPED_POST.getInt()),
 				new BdfEntry(KEY_RSS_FEED, true),
 				new BdfEntry(KEY_ORIGINAL_MSG_ID, messageId),
@@ -659,10 +659,10 @@ public class BlogManagerImplTest extends BriarTestCase {
 				new BdfEntry(KEY_TIMESTAMP, timestamp),
 				new BdfEntry(KEY_TIME_RECEIVED, timeReceived)
 		);
-		final MessageId wrappedCommentId = new MessageId(getRandomId());
-		final Message wrappedCommentMsg = new Message(wrappedCommentId,
+		MessageId wrappedCommentId = new MessageId(getRandomId());
+		Message wrappedCommentMsg = new Message(wrappedCommentId,
 				blog2.getId(), timestamp, getRandomBytes(MAX_MESSAGE_LENGTH));
-		final BdfDictionary wrappedCommentMeta = BdfDictionary.of(
+		BdfDictionary wrappedCommentMeta = BdfDictionary.of(
 				new BdfEntry(KEY_TYPE, WRAPPED_COMMENT.getInt()),
 				new BdfEntry(KEY_COMMENT, comment),
 				new BdfEntry(KEY_PARENT_MSG_ID, rewrappedPostId),
@@ -671,11 +671,11 @@ public class BlogManagerImplTest extends BriarTestCase {
 				new BdfEntry(KEY_TIMESTAMP, timestamp),
 				new BdfEntry(KEY_TIME_RECEIVED, timeReceived)
 		);
-		final String localComment = getRandomString(MAX_BLOG_COMMENT_LENGTH);
-		final MessageId localCommentId = new MessageId(getRandomId());
-		final Message localCommentMsg = new Message(localCommentId,
+		String localComment = getRandomString(MAX_BLOG_COMMENT_LENGTH);
+		MessageId localCommentId = new MessageId(getRandomId());
+		Message localCommentMsg = new Message(localCommentId,
 				blog2.getId(), timestamp, getRandomBytes(MAX_MESSAGE_LENGTH));
-		final BdfDictionary localCommentMeta = BdfDictionary.of(
+		BdfDictionary localCommentMeta = BdfDictionary.of(
 				new BdfEntry(KEY_TYPE, COMMENT.getInt()),
 				new BdfEntry(KEY_COMMENT, localComment),
 				new BdfEntry(KEY_TIMESTAMP, timestamp),
@@ -796,7 +796,7 @@ public class BlogManagerImplTest extends BriarTestCase {
 	@Test
 	public void testBlogCanBeRemoved() throws Exception {
 		// check that own personal blogs can not be removed
-		final Transaction txn = new Transaction(null, true);
+		Transaction txn = new Transaction(null, true);
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn));
@@ -809,7 +809,7 @@ public class BlogManagerImplTest extends BriarTestCase {
 		context.assertIsSatisfied();
 
 		// check that blogs of contacts can be removed
-		final Transaction txn2 = new Transaction(null, true);
+		Transaction txn2 = new Transaction(null, true);
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn2));
diff --git a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java
index 867db3df9e229ffab0b01f03bbde9cffa5ad510e..a089eb0e06e61af209ae4d22d27d83a7ac650c58 100644
--- a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java
@@ -126,7 +126,7 @@ public class BlogManagerIntegrationTest
 	@Test
 	public void testBlogPost() throws Exception {
 		// check that blog0 has no posts
-		final String body = getRandomString(42);
+		String body = getRandomString(42);
 		Collection<BlogPostHeader> headers0 =
 				blogManager0.getPostHeaders(blog0.getId());
 		assertEquals(0, headers0.size());
@@ -164,7 +164,7 @@ public class BlogManagerIntegrationTest
 	@Test
 	public void testBlogPostInWrongBlog() throws Exception {
 		// add a post to blog1
-		final String body = getRandomString(42);
+		String body = getRandomString(42);
 		BlogPost p = blogPostFactory
 				.createBlogPost(blog1.getId(), clock.currentTimeMillis(), null,
 						author0, body);
@@ -203,7 +203,7 @@ public class BlogManagerIntegrationTest
 	@Test
 	public void testBlogComment() throws Exception {
 		// add a post to blog0
-		final String body = getRandomString(42);
+		String body = getRandomString(42);
 		BlogPost p = blogPostFactory
 				.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
 						author0, body);
@@ -248,7 +248,7 @@ public class BlogManagerIntegrationTest
 	@Test
 	public void testBlogCommentOnOwnPost() throws Exception {
 		// add a post to blog0
-		final String body = getRandomString(42);
+		String body = getRandomString(42);
 		BlogPost p = blogPostFactory
 				.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
 						author0, body);
@@ -284,7 +284,7 @@ public class BlogManagerIntegrationTest
 	@Test
 	public void testCommentOnComment() throws Exception {
 		// add a post to blog0
-		final String body = getRandomString(42);
+		String body = getRandomString(42);
 		BlogPost p = blogPostFactory
 				.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
 						author0, body);
@@ -372,7 +372,7 @@ public class BlogManagerIntegrationTest
 	@Test
 	public void testCommentOnOwnComment() throws Exception {
 		// add a post to blog0
-		final String body = getRandomString(42);
+		String body = getRandomString(42);
 		BlogPost p = blogPostFactory
 				.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
 						author0, body);
@@ -417,7 +417,7 @@ public class BlogManagerIntegrationTest
 		assertTrue(rssBlog.isRssFeed());
 
 		// add a feed post to rssBlog
-		final String body = getRandomString(42);
+		String body = getRandomString(42);
 		BlogPost p = blogPostFactory
 				.createBlogPost(rssBlog.getId(), clock.currentTimeMillis(),
 						null, author0, body);
@@ -436,7 +436,7 @@ public class BlogManagerIntegrationTest
 	@Test
 	public void testFeedReblog() throws Exception {
 		// add a feed post to rssBlog
-		final String body = getRandomString(42);
+		String body = getRandomString(42);
 		BlogPost p = blogPostFactory
 				.createBlogPost(rssBlog.getId(), clock.currentTimeMillis(),
 						null, author0, body);
diff --git a/briar-core/src/test/java/org/briarproject/briar/blog/BlogPostValidatorTest.java b/briar-core/src/test/java/org/briarproject/briar/blog/BlogPostValidatorTest.java
index 923bd4c4a5394840641c167eb9b1cde50c556e06..988e3d48b932b19f8aa14ac7e9f17902e1531b64 100644
--- a/briar-core/src/test/java/org/briarproject/briar/blog/BlogPostValidatorTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/blog/BlogPostValidatorTest.java
@@ -111,12 +111,12 @@ public class BlogPostValidatorTest extends BriarTestCase {
 
 	private void testValidateProperBlogPost(Blog b, boolean rssFeed)
 			throws IOException, GeneralSecurityException {
-		final byte[] sigBytes = TestUtils.getRandomBytes(42);
+		byte[] sigBytes = TestUtils.getRandomBytes(42);
 		BdfList m = BdfList.of(POST.getInt(), body, sigBytes);
 
 		BdfList signed = BdfList.of(b.getId(), message.getTimestamp(), body);
 		expectCrypto(b, SIGNING_LABEL_POST, signed, sigBytes);
-		final BdfDictionary result =
+		BdfDictionary result =
 				validator.validateMessage(message, group, m).getDictionary();
 
 		assertEquals(authorDict, result.getDictionary(KEY_AUTHOR));
@@ -150,14 +150,14 @@ public class BlogPostValidatorTest extends BriarTestCase {
 		String comment = "This is a blog comment";
 		MessageId pOriginalId = new MessageId(TestUtils.getRandomId());
 		MessageId currentId = new MessageId(TestUtils.getRandomId());
-		final byte[] sigBytes = TestUtils.getRandomBytes(42);
+		byte[] sigBytes = TestUtils.getRandomBytes(42);
 		BdfList m = BdfList.of(COMMENT.getInt(), comment, pOriginalId,
 				currentId, sigBytes);
 
 		BdfList signed = BdfList.of(blog.getId(), message.getTimestamp(),
 				comment, pOriginalId, currentId);
 		expectCrypto(blog, SIGNING_LABEL_COMMENT, signed, sigBytes);
-		final BdfDictionary result =
+		BdfDictionary result =
 				validator.validateMessage(message, group, m).getDictionary();
 
 		assertEquals(comment, result.getString(KEY_COMMENT));
@@ -175,14 +175,14 @@ public class BlogPostValidatorTest extends BriarTestCase {
 		// comment, parent_original_id, signature, parent_current_id
 		MessageId originalId = new MessageId(TestUtils.getRandomId());
 		MessageId currentId = new MessageId(TestUtils.getRandomId());
-		final byte[] sigBytes = TestUtils.getRandomBytes(42);
+		byte[] sigBytes = TestUtils.getRandomBytes(42);
 		BdfList m = BdfList.of(COMMENT.getInt(), null, originalId, currentId,
 				sigBytes);
 
 		BdfList signed = BdfList.of(blog.getId(), message.getTimestamp(), null,
 				originalId, currentId);
 		expectCrypto(blog, SIGNING_LABEL_COMMENT, signed, sigBytes);
-		final BdfDictionary result =
+		BdfDictionary result =
 				validator.validateMessage(message, group, m).getDictionary();
 
 		assertFalse(result.containsKey(KEY_COMMENT));
@@ -201,18 +201,18 @@ public class BlogPostValidatorTest extends BriarTestCase {
 		testValidateProperWrappedPost(rssBlog, true);
 	}
 
-	private void testValidateProperWrappedPost(final Blog b, boolean rssFeed)
+	private void testValidateProperWrappedPost(Blog b, boolean rssFeed)
 			throws IOException, GeneralSecurityException {
 		// group descriptor, timestamp, content, signature
-		final byte[] sigBytes = TestUtils.getRandomBytes(42);
+		byte[] sigBytes = TestUtils.getRandomBytes(42);
 		BdfList m = BdfList.of(WRAPPED_POST.getInt(), descriptor,
 				message.getTimestamp(), body, sigBytes);
 
 		BdfList signed = BdfList.of(b.getId(), message.getTimestamp(), body);
 		expectCrypto(b, SIGNING_LABEL_POST, signed, sigBytes);
 
-		final BdfList originalList = BdfList.of(POST.getInt(), body, sigBytes);
-		final byte[] originalBody = TestUtils.getRandomBytes(42);
+		BdfList originalList = BdfList.of(POST.getInt(), body, sigBytes);
+		byte[] originalBody = TestUtils.getRandomBytes(42);
 
 		context.checking(new Expectations() {{
 			oneOf(groupFactory).createGroup(clientId, descriptor);
@@ -227,7 +227,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
 			will(returnValue(message));
 		}});
 
-		final BdfDictionary result =
+		BdfDictionary result =
 				validator.validateMessage(message, group, m).getDictionary();
 
 		assertEquals(authorDict, result.getDictionary(KEY_AUTHOR));
@@ -243,7 +243,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
 		String comment = "This is another comment";
 		MessageId originalId = new MessageId(TestUtils.getRandomId());
 		MessageId oldId = new MessageId(TestUtils.getRandomId());
-		final byte[] sigBytes = TestUtils.getRandomBytes(42);
+		byte[] sigBytes = TestUtils.getRandomBytes(42);
 		MessageId currentId = new MessageId(TestUtils.getRandomId());
 		BdfList m = BdfList.of(WRAPPED_COMMENT.getInt(), descriptor,
 				message.getTimestamp(), comment, originalId, oldId, sigBytes,
@@ -253,9 +253,9 @@ public class BlogPostValidatorTest extends BriarTestCase {
 				comment, originalId, oldId);
 		expectCrypto(blog, SIGNING_LABEL_COMMENT, signed, sigBytes);
 
-		final BdfList originalList = BdfList.of(COMMENT.getInt(), comment,
+		BdfList originalList = BdfList.of(COMMENT.getInt(), comment,
 				originalId, oldId, sigBytes);
-		final byte[] originalBody = TestUtils.getRandomBytes(42);
+		byte[] originalBody = TestUtils.getRandomBytes(42);
 
 		context.checking(new Expectations() {{
 			oneOf(groupFactory).createGroup(clientId, descriptor);
@@ -268,7 +268,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
 			will(returnValue(message));
 		}});
 
-		final BdfDictionary result =
+		BdfDictionary result =
 				validator.validateMessage(message, group, m).getDictionary();
 
 		assertEquals(comment, result.getString(KEY_COMMENT));
@@ -279,8 +279,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
 		context.assertIsSatisfied();
 	}
 
-	private void expectCrypto(final Blog b, final String label,
-			final BdfList signed, final byte[] sig)
+	private void expectCrypto(Blog b, String label, BdfList signed, byte[] sig)
 			throws IOException, GeneralSecurityException {
 		context.checking(new Expectations() {{
 			oneOf(blogFactory).parseBlog(group);
diff --git a/briar-core/src/test/java/org/briarproject/briar/client/MessageQueueManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/client/MessageQueueManagerImplTest.java
index 9e14fdc4c7780cf697900149be826dccb59694e1..5c540c13b16dc4ddc9950378f2ec9663f80d9bb9 100644
--- a/briar-core/src/test/java/org/briarproject/briar/client/MessageQueueManagerImplTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/client/MessageQueueManagerImplTest.java
@@ -54,19 +54,19 @@ public class MessageQueueManagerImplTest extends BriarTestCase {
 	@Test
 	public void testSendingMessages() throws Exception {
 		Mockery context = new Mockery();
-		final DatabaseComponent db = context.mock(DatabaseComponent.class);
-		final ClientHelper clientHelper = context.mock(ClientHelper.class);
-		final QueueMessageFactory queueMessageFactory =
+		DatabaseComponent db = context.mock(DatabaseComponent.class);
+		ClientHelper clientHelper = context.mock(ClientHelper.class);
+		QueueMessageFactory queueMessageFactory =
 				context.mock(QueueMessageFactory.class);
-		final ValidationManager validationManager =
+		ValidationManager validationManager =
 				context.mock(ValidationManager.class);
 
-		final Transaction txn = new Transaction(null, false);
-		final byte[] body = new byte[123];
-		final Metadata groupMetadata = new Metadata();
-		final Metadata messageMetadata = new Metadata();
-		final Metadata groupMetadata1 = new Metadata();
-		final byte[] queueState = new byte[123];
+		Transaction txn = new Transaction(null, false);
+		byte[] body = new byte[123];
+		Metadata groupMetadata = new Metadata();
+		Metadata messageMetadata = new Metadata();
+		Metadata groupMetadata1 = new Metadata();
+		byte[] queueState = new byte[123];
 		groupMetadata1.put(QUEUE_STATE_KEY, queueState);
 
 		context.checking(new Expectations() {{
@@ -123,26 +123,25 @@ public class MessageQueueManagerImplTest extends BriarTestCase {
 	@Test
 	public void testValidatorRejectsShortMessage() throws Exception {
 		Mockery context = new Mockery();
-		final DatabaseComponent db = context.mock(DatabaseComponent.class);
-		final ClientHelper clientHelper = context.mock(ClientHelper.class);
-		final QueueMessageFactory queueMessageFactory =
+		DatabaseComponent db = context.mock(DatabaseComponent.class);
+		ClientHelper clientHelper = context.mock(ClientHelper.class);
+		QueueMessageFactory queueMessageFactory =
 				context.mock(QueueMessageFactory.class);
-		final ValidationManager validationManager =
+		ValidationManager validationManager =
 				context.mock(ValidationManager.class);
 
-		final AtomicReference<MessageValidator> captured =
-				new AtomicReference<MessageValidator>();
-		final QueueMessageValidator queueMessageValidator =
+		AtomicReference<MessageValidator> captured = new AtomicReference<>();
+		QueueMessageValidator queueMessageValidator =
 				context.mock(QueueMessageValidator.class);
 		// The message is too short to be a valid queue message
-		final MessageId messageId = new MessageId(TestUtils.getRandomId());
-		final byte[] raw = new byte[QUEUE_MESSAGE_HEADER_LENGTH - 1];
-		final Message message = new Message(messageId, groupId, timestamp, raw);
+		MessageId messageId = new MessageId(TestUtils.getRandomId());
+		byte[] raw = new byte[QUEUE_MESSAGE_HEADER_LENGTH - 1];
+		Message message = new Message(messageId, groupId, timestamp, raw);
 
 		context.checking(new Expectations() {{
 			oneOf(validationManager).registerMessageValidator(with(clientId),
 					with(any(MessageValidator.class)));
-			will(new CaptureArgumentAction<MessageValidator>(captured,
+			will(new CaptureArgumentAction<>(captured,
 					MessageValidator.class, 1));
 		}});
 
@@ -167,28 +166,27 @@ public class MessageQueueManagerImplTest extends BriarTestCase {
 	@Test
 	public void testValidatorRejectsNegativeQueuePosition() throws Exception {
 		Mockery context = new Mockery();
-		final DatabaseComponent db = context.mock(DatabaseComponent.class);
-		final ClientHelper clientHelper = context.mock(ClientHelper.class);
-		final QueueMessageFactory queueMessageFactory =
+		DatabaseComponent db = context.mock(DatabaseComponent.class);
+		ClientHelper clientHelper = context.mock(ClientHelper.class);
+		QueueMessageFactory queueMessageFactory =
 				context.mock(QueueMessageFactory.class);
-		final ValidationManager validationManager =
+		ValidationManager validationManager =
 				context.mock(ValidationManager.class);
 
-		final AtomicReference<MessageValidator> captured =
-				new AtomicReference<MessageValidator>();
-		final QueueMessageValidator queueMessageValidator =
+		AtomicReference<MessageValidator> captured = new AtomicReference<>();
+		QueueMessageValidator queueMessageValidator =
 				context.mock(QueueMessageValidator.class);
 		// The message has a negative queue position
-		final MessageId messageId = new MessageId(TestUtils.getRandomId());
-		final byte[] raw = new byte[QUEUE_MESSAGE_HEADER_LENGTH];
+		MessageId messageId = new MessageId(TestUtils.getRandomId());
+		byte[] raw = new byte[QUEUE_MESSAGE_HEADER_LENGTH];
 		for (int i = 0; i < 8; i++)
 			raw[MESSAGE_HEADER_LENGTH + i] = (byte) 0xFF;
-		final Message message = new Message(messageId, groupId, timestamp, raw);
+		Message message = new Message(messageId, groupId, timestamp, raw);
 
 		context.checking(new Expectations() {{
 			oneOf(validationManager).registerMessageValidator(with(clientId),
 					with(any(MessageValidator.class)));
-			will(new CaptureArgumentAction<MessageValidator>(captured,
+			will(new CaptureArgumentAction<>(captured,
 					MessageValidator.class, 1));
 		}});
 
@@ -213,29 +211,28 @@ public class MessageQueueManagerImplTest extends BriarTestCase {
 	@Test
 	public void testValidatorDelegatesValidMessage() throws Exception {
 		Mockery context = new Mockery();
-		final DatabaseComponent db = context.mock(DatabaseComponent.class);
-		final ClientHelper clientHelper = context.mock(ClientHelper.class);
-		final QueueMessageFactory queueMessageFactory =
+		DatabaseComponent db = context.mock(DatabaseComponent.class);
+		ClientHelper clientHelper = context.mock(ClientHelper.class);
+		QueueMessageFactory queueMessageFactory =
 				context.mock(QueueMessageFactory.class);
-		final ValidationManager validationManager =
+		ValidationManager validationManager =
 				context.mock(ValidationManager.class);
 
-		final AtomicReference<MessageValidator> captured =
-				new AtomicReference<MessageValidator>();
-		final QueueMessageValidator queueMessageValidator =
+		AtomicReference<MessageValidator> captured = new AtomicReference<>();
+		QueueMessageValidator queueMessageValidator =
 				context.mock(QueueMessageValidator.class);
-		final Metadata metadata = new Metadata();
-		final MessageContext messageContext =
+		Metadata metadata = new Metadata();
+		MessageContext messageContext =
 				new MessageContext(metadata);
 		// The message is valid, with a queue position of zero
-		final MessageId messageId = new MessageId(TestUtils.getRandomId());
-		final byte[] raw = new byte[QUEUE_MESSAGE_HEADER_LENGTH];
-		final Message message = new Message(messageId, groupId, timestamp, raw);
+		MessageId messageId = new MessageId(TestUtils.getRandomId());
+		byte[] raw = new byte[QUEUE_MESSAGE_HEADER_LENGTH];
+		Message message = new Message(messageId, groupId, timestamp, raw);
 
 		context.checking(new Expectations() {{
 			oneOf(validationManager).registerMessageValidator(with(clientId),
 					with(any(MessageValidator.class)));
-			will(new CaptureArgumentAction<MessageValidator>(captured,
+			will(new CaptureArgumentAction<>(captured,
 					MessageValidator.class, 1));
 			// The message should be delegated
 			oneOf(queueMessageValidator).validateMessage(
@@ -261,30 +258,29 @@ public class MessageQueueManagerImplTest extends BriarTestCase {
 	public void testIncomingMessageHookDeletesDuplicateMessage()
 			throws Exception {
 		Mockery context = new Mockery();
-		final DatabaseComponent db = context.mock(DatabaseComponent.class);
-		final ClientHelper clientHelper = context.mock(ClientHelper.class);
-		final QueueMessageFactory queueMessageFactory =
+		DatabaseComponent db = context.mock(DatabaseComponent.class);
+		ClientHelper clientHelper = context.mock(ClientHelper.class);
+		QueueMessageFactory queueMessageFactory =
 				context.mock(QueueMessageFactory.class);
-		final ValidationManager validationManager =
+		ValidationManager validationManager =
 				context.mock(ValidationManager.class);
-		final AtomicReference<IncomingMessageHook> captured =
-				new AtomicReference<IncomingMessageHook>();
-		final IncomingQueueMessageHook incomingQueueMessageHook =
+		AtomicReference<IncomingMessageHook> captured = new AtomicReference<>();
+		IncomingQueueMessageHook incomingQueueMessageHook =
 				context.mock(IncomingQueueMessageHook.class);
 
-		final Transaction txn = new Transaction(null, false);
-		final Metadata groupMetadata = new Metadata();
-		final byte[] queueState = new byte[123];
+		Transaction txn = new Transaction(null, false);
+		Metadata groupMetadata = new Metadata();
+		byte[] queueState = new byte[123];
 		groupMetadata.put(QUEUE_STATE_KEY, queueState);
 		// The message has queue position 0
-		final MessageId messageId = new MessageId(TestUtils.getRandomId());
-		final byte[] raw = new byte[QUEUE_MESSAGE_HEADER_LENGTH];
-		final Message message = new Message(messageId, groupId, timestamp, raw);
+		MessageId messageId = new MessageId(TestUtils.getRandomId());
+		byte[] raw = new byte[QUEUE_MESSAGE_HEADER_LENGTH];
+		Message message = new Message(messageId, groupId, timestamp, raw);
 
 		context.checking(new Expectations() {{
 			oneOf(validationManager).registerIncomingMessageHook(with(clientId),
 					with(any(IncomingMessageHook.class)));
-			will(new CaptureArgumentAction<IncomingMessageHook>(captured,
+			will(new CaptureArgumentAction<>(captured,
 					IncomingMessageHook.class, 1));
 			oneOf(db).getGroupMetadata(txn, groupId);
 			will(returnValue(groupMetadata));
@@ -313,32 +309,31 @@ public class MessageQueueManagerImplTest extends BriarTestCase {
 	public void testIncomingMessageHookAddsOutOfOrderMessageToPendingList()
 			throws Exception {
 		Mockery context = new Mockery();
-		final DatabaseComponent db = context.mock(DatabaseComponent.class);
-		final ClientHelper clientHelper = context.mock(ClientHelper.class);
-		final QueueMessageFactory queueMessageFactory =
+		DatabaseComponent db = context.mock(DatabaseComponent.class);
+		ClientHelper clientHelper = context.mock(ClientHelper.class);
+		QueueMessageFactory queueMessageFactory =
 				context.mock(QueueMessageFactory.class);
-		final ValidationManager validationManager =
+		ValidationManager validationManager =
 				context.mock(ValidationManager.class);
-		final AtomicReference<IncomingMessageHook> captured =
-				new AtomicReference<IncomingMessageHook>();
-		final IncomingQueueMessageHook incomingQueueMessageHook =
+		AtomicReference<IncomingMessageHook> captured = new AtomicReference<>();
+		IncomingQueueMessageHook incomingQueueMessageHook =
 				context.mock(IncomingQueueMessageHook.class);
 
-		final Transaction txn = new Transaction(null, false);
-		final Metadata groupMetadata = new Metadata();
-		final byte[] queueState = new byte[123];
+		Transaction txn = new Transaction(null, false);
+		Metadata groupMetadata = new Metadata();
+		byte[] queueState = new byte[123];
 		groupMetadata.put(QUEUE_STATE_KEY, queueState);
 		// The message has queue position 1
-		final MessageId messageId = new MessageId(TestUtils.getRandomId());
-		final byte[] raw = new byte[QUEUE_MESSAGE_HEADER_LENGTH];
+		MessageId messageId = new MessageId(TestUtils.getRandomId());
+		byte[] raw = new byte[QUEUE_MESSAGE_HEADER_LENGTH];
 		ByteUtils.writeUint64(1L, raw, MESSAGE_HEADER_LENGTH);
-		final Message message = new Message(messageId, groupId, timestamp, raw);
-		final BdfList pending = BdfList.of(BdfList.of(1L, messageId));
+		Message message = new Message(messageId, groupId, timestamp, raw);
+		BdfList pending = BdfList.of(BdfList.of(1L, messageId));
 
 		context.checking(new Expectations() {{
 			oneOf(validationManager).registerIncomingMessageHook(with(clientId),
 					with(any(IncomingMessageHook.class)));
-			will(new CaptureArgumentAction<IncomingMessageHook>(captured,
+			will(new CaptureArgumentAction<>(captured,
 					IncomingMessageHook.class, 1));
 			oneOf(db).getGroupMetadata(txn, groupId);
 			will(returnValue(groupMetadata));
@@ -369,31 +364,30 @@ public class MessageQueueManagerImplTest extends BriarTestCase {
 	public void testIncomingMessageHookDelegatesInOrderMessage()
 			throws Exception {
 		Mockery context = new Mockery();
-		final DatabaseComponent db = context.mock(DatabaseComponent.class);
-		final ClientHelper clientHelper = context.mock(ClientHelper.class);
-		final QueueMessageFactory queueMessageFactory =
+		DatabaseComponent db = context.mock(DatabaseComponent.class);
+		ClientHelper clientHelper = context.mock(ClientHelper.class);
+		QueueMessageFactory queueMessageFactory =
 				context.mock(QueueMessageFactory.class);
-		final ValidationManager validationManager =
+		ValidationManager validationManager =
 				context.mock(ValidationManager.class);
-		final AtomicReference<IncomingMessageHook> captured =
-				new AtomicReference<IncomingMessageHook>();
-		final IncomingQueueMessageHook incomingQueueMessageHook =
+		AtomicReference<IncomingMessageHook> captured = new AtomicReference<>();
+		IncomingQueueMessageHook incomingQueueMessageHook =
 				context.mock(IncomingQueueMessageHook.class);
 
-		final Transaction txn = new Transaction(null, false);
-		final Metadata groupMetadata = new Metadata();
-		final byte[] queueState = new byte[123];
+		Transaction txn = new Transaction(null, false);
+		Metadata groupMetadata = new Metadata();
+		byte[] queueState = new byte[123];
 		groupMetadata.put(QUEUE_STATE_KEY, queueState);
 		// The message has queue position 0
-		final MessageId messageId = new MessageId(TestUtils.getRandomId());
-		final byte[] raw = new byte[QUEUE_MESSAGE_HEADER_LENGTH];
-		final Message message = new Message(messageId, groupId, timestamp, raw);
-		final Metadata messageMetadata = new Metadata();
+		MessageId messageId = new MessageId(TestUtils.getRandomId());
+		byte[] raw = new byte[QUEUE_MESSAGE_HEADER_LENGTH];
+		Message message = new Message(messageId, groupId, timestamp, raw);
+		Metadata messageMetadata = new Metadata();
 
 		context.checking(new Expectations() {{
 			oneOf(validationManager).registerIncomingMessageHook(with(clientId),
 					with(any(IncomingMessageHook.class)));
-			will(new CaptureArgumentAction<IncomingMessageHook>(captured,
+			will(new CaptureArgumentAction<>(captured,
 					IncomingMessageHook.class, 1));
 			oneOf(db).getGroupMetadata(txn, groupId);
 			will(returnValue(groupMetadata));
@@ -427,38 +421,37 @@ public class MessageQueueManagerImplTest extends BriarTestCase {
 	public void testIncomingMessageHookRetrievesPendingMessage()
 			throws Exception {
 		Mockery context = new Mockery();
-		final DatabaseComponent db = context.mock(DatabaseComponent.class);
-		final ClientHelper clientHelper = context.mock(ClientHelper.class);
-		final QueueMessageFactory queueMessageFactory =
+		DatabaseComponent db = context.mock(DatabaseComponent.class);
+		ClientHelper clientHelper = context.mock(ClientHelper.class);
+		QueueMessageFactory queueMessageFactory =
 				context.mock(QueueMessageFactory.class);
-		final ValidationManager validationManager =
+		ValidationManager validationManager =
 				context.mock(ValidationManager.class);
-		final AtomicReference<IncomingMessageHook> captured =
-				new AtomicReference<IncomingMessageHook>();
-		final IncomingQueueMessageHook incomingQueueMessageHook =
+		AtomicReference<IncomingMessageHook> captured = new AtomicReference<>();
+		IncomingQueueMessageHook incomingQueueMessageHook =
 				context.mock(IncomingQueueMessageHook.class);
 
-		final Transaction txn = new Transaction(null, false);
-		final Metadata groupMetadata = new Metadata();
-		final byte[] queueState = new byte[123];
+		Transaction txn = new Transaction(null, false);
+		Metadata groupMetadata = new Metadata();
+		byte[] queueState = new byte[123];
 		groupMetadata.put(QUEUE_STATE_KEY, queueState);
 		// The message has queue position 0
-		final MessageId messageId = new MessageId(TestUtils.getRandomId());
-		final byte[] raw = new byte[QUEUE_MESSAGE_HEADER_LENGTH];
-		final Message message = new Message(messageId, groupId, timestamp, raw);
-		final Metadata messageMetadata = new Metadata();
+		MessageId messageId = new MessageId(TestUtils.getRandomId());
+		byte[] raw = new byte[QUEUE_MESSAGE_HEADER_LENGTH];
+		Message message = new Message(messageId, groupId, timestamp, raw);
+		Metadata messageMetadata = new Metadata();
 		// Queue position 1 is pending
-		final MessageId messageId1 = new MessageId(TestUtils.getRandomId());
-		final byte[] raw1 = new byte[QUEUE_MESSAGE_HEADER_LENGTH];
-		final QueueMessage message1 = new QueueMessage(messageId1, groupId,
+		MessageId messageId1 = new MessageId(TestUtils.getRandomId());
+		byte[] raw1 = new byte[QUEUE_MESSAGE_HEADER_LENGTH];
+		QueueMessage message1 = new QueueMessage(messageId1, groupId,
 				timestamp, 1L, raw1);
-		final Metadata messageMetadata1 = new Metadata();
-		final BdfList pending = BdfList.of(BdfList.of(1L, messageId1));
+		Metadata messageMetadata1 = new Metadata();
+		BdfList pending = BdfList.of(BdfList.of(1L, messageId1));
 
 		context.checking(new Expectations() {{
 			oneOf(validationManager).registerIncomingMessageHook(with(clientId),
 					with(any(IncomingMessageHook.class)));
-			will(new CaptureArgumentAction<IncomingMessageHook>(captured,
+			will(new CaptureArgumentAction<>(captured,
 					IncomingMessageHook.class, 1));
 			oneOf(db).getGroupMetadata(txn, groupId);
 			will(returnValue(groupMetadata));
diff --git a/briar-core/src/test/java/org/briarproject/briar/client/MessageTreeImplTest.java b/briar-core/src/test/java/org/briarproject/briar/client/MessageTreeImplTest.java
index d2c825cc664531f2c8ec5d244f14f2aca97003a9..f324990ac053a29617ed36b8b7fb2a824a9bc610 100644
--- a/briar-core/src/test/java/org/briarproject/briar/client/MessageTreeImplTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/client/MessageTreeImplTest.java
@@ -19,7 +19,7 @@ public class MessageTreeImplTest {
 
 	@Test
 	public void testMessageTree() {
-		tree = new MessageTreeImpl<TestNode>();
+		tree = new MessageTreeImpl<>();
 		testSimpleTree();
 		tree.clear();
 		testSimpleTree();
diff --git a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java
index 7dafcd48e52b9bc32b0dfb0fbc90a4e4cd7a5dba..e8e914dc88924ec6af7936ac70af442dcf88c5ac 100644
--- a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java
@@ -89,7 +89,7 @@ public class FeedManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testFetchFeedIoException() throws Exception {
-		final BdfDictionary feedDict= new BdfDictionary();
+		BdfDictionary feedDict= new BdfDictionary();
 		BdfList feedList = BdfList.of(feedDict);
 
 		expectGetFeeds(feedList);
@@ -104,17 +104,16 @@ public class FeedManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testPostFeedEntriesEmptyDate() throws Exception {
-		final Transaction txn = new Transaction(null, false);
-		List<SyndEntry> entries = new ArrayList<SyndEntry>();
+		Transaction txn = new Transaction(null, false);
+		List<SyndEntry> entries = new ArrayList<>();
 		entries.add(new SyndEntryImpl());
-		final SyndEntry entry = new SyndEntryImpl();
+		SyndEntry entry = new SyndEntryImpl();
 		entry.setUpdatedDate(new Date());
 		entries.add(entry);
-		final String body =
-				"<p> (" + entry.getUpdatedDate().toString() + ")</p>";
+		String body = "<p> (" + entry.getUpdatedDate().toString() + ")</p>";
 		Message msg = new Message(new MessageId(getRandomId()), blogGroupId, 0,
 				getRandomBytes(42));
-		final BlogPost post = new BlogPost(msg, null, localAuthor);
+		BlogPost post = new BlogPost(msg, null, localAuthor);
 
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(false);
@@ -139,9 +138,9 @@ public class FeedManagerImplTest extends BrambleMockTestCase {
 		}});
 	}
 
-	private void expectGetFeeds(final BdfList feedList) throws Exception {
-		final Transaction txn = new Transaction(null, true);
-		final BdfDictionary feedsDict =
+	private void expectGetFeeds(BdfList feedList) throws Exception {
+		Transaction txn = new Transaction(null, true);
+		BdfDictionary feedsDict =
 				BdfDictionary.of(new BdfEntry(KEY_FEEDS, feedList));
 		expectGetLocalGroup();
 		context.checking(new Expectations() {{
@@ -158,8 +157,8 @@ public class FeedManagerImplTest extends BrambleMockTestCase {
 		}});
 	}
 
-	private void expectStoreFeed(final BdfList feedList) throws Exception {
-		final BdfDictionary feedDict =
+	private void expectStoreFeed(BdfList feedList) throws Exception {
+		BdfDictionary feedDict =
 				BdfDictionary.of(new BdfEntry(KEY_FEEDS, feedList));
 		expectGetLocalGroup();
 		context.checking(new Expectations() {{
diff --git a/briar-core/src/test/java/org/briarproject/briar/forum/ForumManagerTest.java b/briar-core/src/test/java/org/briarproject/briar/forum/ForumManagerTest.java
index 30567fdf225431c37ef54d27fc1908c2d2e7c9e1..d53af17304866bd6444963bd1830982ff6e96049 100644
--- a/briar-core/src/test/java/org/briarproject/briar/forum/ForumManagerTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/forum/ForumManagerTest.java
@@ -81,10 +81,10 @@ public class ForumManagerTest
 	@Test
 	public void testForumPost() throws Exception {
 		assertEquals(1, forumManager0.getForums().size());
-		final long ms1 = clock.currentTimeMillis() - 1000L;
-		final String body1 = "some forum text";
-		final long ms2 = clock.currentTimeMillis();
-		final String body2 = "some other forum text";
+		long ms1 = clock.currentTimeMillis() - 1000L;
+		String body1 = "some forum text";
+		long ms2 = clock.currentTimeMillis();
+		String body2 = "some other forum text";
 		ForumPost post1 =
 				createForumPost(forum0.getGroup().getId(), null, body1, ms1);
 		assertEquals(ms1, post1.getMessage().getTimestamp());
@@ -109,7 +109,7 @@ public class ForumManagerTest
 				forumManager0.getPostHeaders(forum0.getGroup().getId());
 		assertEquals(2, headers.size());
 		for (ForumPostHeader h : headers) {
-			final String hBody = forumManager0.getPostBody(h.getId());
+			String hBody = forumManager0.getPostBody(h.getId());
 
 			boolean isPost1 = h.getId().equals(post1.getMessage().getId());
 			boolean isPost2 = h.getId().equals(post2.getMessage().getId());
diff --git a/briar-core/src/test/java/org/briarproject/briar/forum/ForumPostValidatorTest.java b/briar-core/src/test/java/org/briarproject/briar/forum/ForumPostValidatorTest.java
index 2051635da42cca6a13c15678475d449ba6648b6f..51e29b23a02a4e83811607b1b71f2d8a0d4de09f 100644
--- a/briar-core/src/test/java/org/briarproject/briar/forum/ForumPostValidatorTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/forum/ForumPostValidatorTest.java
@@ -166,12 +166,12 @@ public class ForumPostValidatorTest extends ValidatorTestCase {
 
 	@Test
 	public void testAcceptsMinLengthAuthorName() throws Exception {
-		final String shortAuthorName = StringUtils.getRandomString(1);
+		String shortAuthorName = StringUtils.getRandomString(1);
 		BdfList shortNameAuthorList =
 				BdfList.of(shortAuthorName, authorPublicKey);
-		final Author shortNameAuthor =
+		Author shortNameAuthor =
 				new Author(authorId, shortAuthorName, authorPublicKey);
-		final BdfList signedWithShortNameAuthor = BdfList.of(groupId, timestamp,
+		BdfList signedWithShortNameAuthor = BdfList.of(groupId, timestamp,
 				parentId.getBytes(), shortNameAuthorList, content);
 
 		context.checking(new Expectations() {{
@@ -259,7 +259,7 @@ public class ForumPostValidatorTest extends ValidatorTestCase {
 	@Test
 	public void testAcceptsMinLengthContent() throws Exception {
 		String shortContent = "";
-		final BdfList signedWithShortContent = BdfList.of(groupId, timestamp,
+		BdfList signedWithShortContent = BdfList.of(groupId, timestamp,
 				parentId.getBytes(), authorList, shortContent);
 
 		context.checking(new Expectations() {{
diff --git a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroduceeManagerTest.java b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroduceeManagerTest.java
index 30b58d5871f52003a751d926d442cc23c60e40b4..0453530c9a42833d23958ddfd22b91b4cd12fb86 100644
--- a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroduceeManagerTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroduceeManagerTest.java
@@ -174,7 +174,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
 	public void testIncomingRequestMessage()
 			throws DbException, FormatException {
 
-		final BdfDictionary msg = new BdfDictionary();
+		BdfDictionary msg = new BdfDictionary();
 		msg.put(TYPE, TYPE_REQUEST);
 		msg.put(GROUP_ID, introductionGroup1.getId());
 		msg.put(SESSION_ID, sessionId);
@@ -183,7 +183,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
 		msg.put(NAME, introducee2.getAuthor().getName());
 		msg.put(PUBLIC_KEY, introducee2.getAuthor().getPublicKey());
 
-		final BdfDictionary state =
+		BdfDictionary state =
 				initializeSessionState(txn, introductionGroup1.getId(), msg);
 
 		context.checking(new Expectations() {{
@@ -201,7 +201,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
 	public void testIncomingResponseMessage()
 			throws DbException, FormatException {
 
-		final BdfDictionary msg = new BdfDictionary();
+		BdfDictionary msg = new BdfDictionary();
 		msg.put(TYPE, TYPE_RESPONSE);
 		msg.put(GROUP_ID, introductionGroup1.getId());
 		msg.put(SESSION_ID, sessionId);
@@ -210,7 +210,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
 		msg.put(NAME, introducee2.getAuthor().getName());
 		msg.put(PUBLIC_KEY, introducee2.getAuthor().getPublicKey());
 
-		final BdfDictionary state =
+		BdfDictionary state =
 				initializeSessionState(txn, introductionGroup1.getId(), msg);
 		state.put(STATE, IntroduceeProtocolState.AWAIT_RESPONSES.ordinal());
 
@@ -236,7 +236,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
 			throws DbException, FormatException, GeneralSecurityException {
 
 		// TODO MR !237 should use its new default initialization method here
-		final BdfDictionary msg = new BdfDictionary();
+		BdfDictionary msg = new BdfDictionary();
 		msg.put(TYPE, TYPE_RESPONSE);
 		msg.put(GROUP_ID, introductionGroup1.getId());
 		msg.put(SESSION_ID, sessionId);
@@ -244,19 +244,19 @@ public class IntroduceeManagerTest extends BriarTestCase {
 		msg.put(MESSAGE_TIME, time);
 		msg.put(NAME, introducee2.getAuthor().getName());
 		msg.put(PUBLIC_KEY, introducee2.getAuthor().getPublicKey());
-		final BdfDictionary state =
+		BdfDictionary state =
 				initializeSessionState(txn, introductionGroup1.getId(), msg);
 
 		// prepare state for incoming ACK
 		state.put(STATE, IntroduceeProtocolState.AWAIT_ACK.ordinal());
 		state.put(ADDED_CONTACT_ID, 2);
-		final byte[] nonce = TestUtils.getRandomBytes(42);
+		byte[] nonce = TestUtils.getRandomBytes(42);
 		state.put(NONCE, nonce);
 		state.put(PUBLIC_KEY, introducee2.getAuthor().getPublicKey());
 
 		// create incoming ACK message
-		final byte[] mac = TestUtils.getRandomBytes(MAC_LENGTH);
-		final byte[] sig = TestUtils.getRandomBytes(MAX_SIGNATURE_LENGTH);
+		byte[] mac = TestUtils.getRandomBytes(MAC_LENGTH);
+		byte[] sig = TestUtils.getRandomBytes(MAX_SIGNATURE_LENGTH);
 		BdfDictionary ack = BdfDictionary.of(
 				new BdfEntry(TYPE, TYPE_ACK),
 				new BdfEntry(SESSION_ID, sessionId),
@@ -286,9 +286,9 @@ public class IntroduceeManagerTest extends BriarTestCase {
 	public void testSignatureVerification()
 			throws FormatException, DbException, GeneralSecurityException {
 
-		final byte[] publicKeyBytes = introducee2.getAuthor().getPublicKey();
-		final byte[] nonce = TestUtils.getRandomBytes(MAC_LENGTH);
-		final byte[] sig = TestUtils.getRandomBytes(MAC_LENGTH);
+		byte[] publicKeyBytes = introducee2.getAuthor().getPublicKey();
+		byte[] nonce = TestUtils.getRandomBytes(MAC_LENGTH);
+		byte[] sig = TestUtils.getRandomBytes(MAC_LENGTH);
 
 		BdfDictionary state = new BdfDictionary();
 		state.put(PUBLIC_KEY, publicKeyBytes);
@@ -308,12 +308,12 @@ public class IntroduceeManagerTest extends BriarTestCase {
 	public void testMacVerification()
 			throws FormatException, DbException, GeneralSecurityException {
 
-		final byte[] publicKeyBytes = introducee2.getAuthor().getPublicKey();
-		final BdfDictionary tp = BdfDictionary.of(new BdfEntry("fake", "fake"));
-		final byte[] ePublicKeyBytes =
+		byte[] publicKeyBytes = introducee2.getAuthor().getPublicKey();
+		BdfDictionary tp = BdfDictionary.of(new BdfEntry("fake", "fake"));
+		byte[] ePublicKeyBytes =
 				TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
-		final byte[] mac = TestUtils.getRandomBytes(MAC_LENGTH);
-		final SecretKey macKey = TestUtils.getSecretKey();
+		byte[] mac = TestUtils.getRandomBytes(MAC_LENGTH);
+		SecretKey macKey = TestUtils.getSecretKey();
 
 		// move state to where it would be after an ACK arrived
 		BdfDictionary state = new BdfDictionary();
@@ -324,7 +324,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
 		state.put(MAC, mac);
 		state.put(MAC_KEY, macKey.getBytes());
 
-		final byte[] signBytes = TestUtils.getRandomBytes(42);
+		byte[] signBytes = TestUtils.getRandomBytes(42);
 		context.checking(new Expectations() {{
 			oneOf(clientHelper).toByteArray(
 					BdfList.of(publicKeyBytes, ePublicKeyBytes, tp, time));
@@ -356,17 +356,17 @@ public class IntroduceeManagerTest extends BriarTestCase {
 		context.assertIsSatisfied();
 	}
 
-	private BdfDictionary initializeSessionState(final Transaction txn,
-			final GroupId groupId, final BdfDictionary msg)
+	private BdfDictionary initializeSessionState(Transaction txn,
+			GroupId groupId, BdfDictionary msg)
 			throws DbException, FormatException {
 
-		final SecureRandom secureRandom = context.mock(SecureRandom.class);
-		final Bytes salt = new Bytes(new byte[64]);
-		final BdfDictionary groupMetadata = BdfDictionary.of(
+		SecureRandom secureRandom = context.mock(SecureRandom.class);
+		Bytes salt = new Bytes(new byte[64]);
+		BdfDictionary groupMetadata = BdfDictionary.of(
 				new BdfEntry(CONTACT, introducee1.getId().getInt())
 		);
-		final boolean contactExists = false;
-		final BdfDictionary state = new BdfDictionary();
+		boolean contactExists = false;
+		BdfDictionary state = new BdfDictionary();
 		state.put(STORAGE_ID, localStateMessage.getId());
 		state.put(STATE, AWAIT_REQUEST.getValue());
 		state.put(ROLE, ROLE_INTRODUCEE);
diff --git a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroducerManagerTest.java b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroducerManagerTest.java
index 1eb26692f53b1b6d2f4e88e0c9e3d202048522ac..93b584ae7cf8b8867b7b697e82d316df7f4973ee 100644
--- a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroducerManagerTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroducerManagerTest.java
@@ -108,14 +108,14 @@ public class IntroducerManagerTest extends BriarTestCase {
 
 	@Test
 	public void testMakeIntroduction() throws DbException, FormatException {
-		final Transaction txn = new Transaction(null, false);
-		final long time = 42L;
+		Transaction txn = new Transaction(null, false);
+		long time = 42L;
 		context.setImposteriser(ClassImposteriser.INSTANCE);
-		final SecureRandom secureRandom = context.mock(SecureRandom.class);
-		final Bytes salt = new Bytes(new byte[64]);
-		final Message msg = new Message(new MessageId(TestUtils.getRandomId()),
+		SecureRandom secureRandom = context.mock(SecureRandom.class);
+		Bytes salt = new Bytes(new byte[64]);
+		Message msg = new Message(new MessageId(TestUtils.getRandomId()),
 				localGroup0.getId(), time, TestUtils.getRandomBytes(64));
-		final BdfDictionary state = new BdfDictionary();
+		BdfDictionary state = new BdfDictionary();
 		state.put(SESSION_ID, msg.getId());
 		state.put(STORAGE_ID, msg.getId());
 		state.put(STATE, PREPARE_REQUESTS.getValue());
@@ -128,25 +128,25 @@ public class IntroducerManagerTest extends BriarTestCase {
 		state.put(CONTACT_ID_2, introducee2.getId().getInt());
 		state.put(AUTHOR_ID_1, introducee1.getAuthor().getId());
 		state.put(AUTHOR_ID_2, introducee2.getAuthor().getId());
-		final BdfDictionary state2 = (BdfDictionary) state.clone();
+		BdfDictionary state2 = (BdfDictionary) state.clone();
 		state2.put(STATE, AWAIT_RESPONSES.getValue());
 
-		final BdfDictionary msg1 = new BdfDictionary();
+		BdfDictionary msg1 = new BdfDictionary();
 		msg1.put(TYPE, TYPE_REQUEST);
 		msg1.put(SESSION_ID, state.getRaw(SESSION_ID));
 		msg1.put(GROUP_ID, state.getRaw(GROUP_ID_1));
 		msg1.put(NAME, state.getString(CONTACT_2));
 		msg1.put(PUBLIC_KEY, introducee2.getAuthor().getPublicKey());
-		final BdfDictionary msg1send = (BdfDictionary) msg1.clone();
+		BdfDictionary msg1send = (BdfDictionary) msg1.clone();
 		msg1send.put(MESSAGE_TIME, time);
 
-		final BdfDictionary msg2 = new BdfDictionary();
+		BdfDictionary msg2 = new BdfDictionary();
 		msg2.put(TYPE, TYPE_REQUEST);
 		msg2.put(SESSION_ID, state.getRaw(SESSION_ID));
 		msg2.put(GROUP_ID, state.getRaw(GROUP_ID_2));
 		msg2.put(NAME, state.getString(CONTACT_1));
 		msg2.put(PUBLIC_KEY, introducee1.getAuthor().getPublicKey());
-		final BdfDictionary msg2send = (BdfDictionary) msg2.clone();
+		BdfDictionary msg2send = (BdfDictionary) msg2.clone();
 		msg2send.put(MESSAGE_TIME, time);
 
 		context.checking(new Expectations() {{
diff --git a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java
index 0db1a2b69ce3e502283b53c40caa747337554394..4902f58c1fc216312e7f84ab9e84668073f74504 100644
--- a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java
@@ -464,7 +464,7 @@ public class IntroductionIntegrationTest
 		assertTrue(listener1.requestReceived);
 
 		// get SessionId
-		List<IntroductionMessage> list = new ArrayList<IntroductionMessage>(
+		List<IntroductionMessage> list = new ArrayList<>(
 				introductionManager1.getIntroductionMessages(contactId0From1));
 		assertEquals(2, list.size());
 		assertTrue(list.get(0) instanceof IntroductionRequest);
@@ -706,39 +706,29 @@ public class IntroductionIntegrationTest
 
 	@Test
 	public void testModifiedTransportProperties() throws Exception {
-		testModifiedResponse(new StateVisitor() {
-			@Override
-			public boolean visit(BdfDictionary response) {
-				BdfDictionary tp = response.getDictionary(TRANSPORT, null);
-				tp.put("fakeId",
-						BdfDictionary.of(new BdfEntry("fake", "fake")));
-				response.put(TRANSPORT, tp);
-				return false;
-			}
+		testModifiedResponse(response -> {
+			BdfDictionary tp = response.getDictionary(TRANSPORT, null);
+			tp.put("fakeId", BdfDictionary.of(new BdfEntry("fake", "fake")));
+			response.put(TRANSPORT, tp);
+			return false;
 		});
 	}
 
 	@Test
 	public void testModifiedTimestamp() throws Exception {
-		testModifiedResponse(new StateVisitor() {
-			@Override
-			public boolean visit(BdfDictionary response) {
-				long timestamp = response.getLong(TIME, 0L);
-				response.put(TIME, timestamp + 1);
-				return false;
-			}
+		testModifiedResponse(response -> {
+			long timestamp = response.getLong(TIME, 0L);
+			response.put(TIME, timestamp + 1);
+			return false;
 		});
 	}
 
 	@Test
 	public void testModifiedEphemeralPublicKey() throws Exception {
-		testModifiedResponse(new StateVisitor() {
-			@Override
-			public boolean visit(BdfDictionary response) {
-				KeyPair keyPair = crypto.generateSignatureKeyPair();
-				response.put(E_PUBLIC_KEY, keyPair.getPublic().getEncoded());
-				return true;
-			}
+		testModifiedResponse(response -> {
+			KeyPair keyPair = crypto.generateSignatureKeyPair();
+			response.put(E_PUBLIC_KEY, keyPair.getPublic().getEncoded());
+			return true;
 		});
 	}
 
@@ -934,9 +924,7 @@ public class IntroductionIntegrationTest
 											time);
 						}
 					}
-				} catch (DbException exception) {
-					eventWaiter.rethrow(exception);
-				} catch (FormatException exception) {
+				} catch (DbException | FormatException exception) {
 					eventWaiter.rethrow(exception);
 				} finally {
 					eventWaiter.resume();
diff --git a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionManagerImplTest.java
index 019787882828f9565f86e0d5bead355ebee02959..7d06c94d0f7471bd8051341af406e82a9cd11ac3 100644
--- a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionManagerImplTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionManagerImplTest.java
@@ -146,7 +146,7 @@ public class IntroductionManagerImplTest extends BriarTestCase {
 
 	@Test
 	public void testAcceptIntroduction() throws DbException, FormatException {
-		final BdfDictionary state = BdfDictionary.of(
+		BdfDictionary state = BdfDictionary.of(
 				new BdfEntry(GROUP_ID_1, introductionGroup1.getId()),
 				new BdfEntry(GROUP_ID_2, introductionGroup2.getId())
 		);
@@ -177,7 +177,7 @@ public class IntroductionManagerImplTest extends BriarTestCase {
 
 	@Test
 	public void testDeclineIntroduction() throws DbException, FormatException {
-		final BdfDictionary state = BdfDictionary.of(
+		BdfDictionary state = BdfDictionary.of(
 				new BdfEntry(GROUP_ID_1, introductionGroup1.getId()),
 				new BdfEntry(GROUP_ID_2, introductionGroup2.getId())
 		);
@@ -210,8 +210,8 @@ public class IntroductionManagerImplTest extends BriarTestCase {
 	public void testGetIntroductionMessages()
 			throws DbException, FormatException {
 
-		final Map<MessageId, BdfDictionary> metadata = Collections.emptyMap();
-		final Collection<MessageStatus> statuses = Collections.emptyList();
+		Map<MessageId, BdfDictionary> metadata = Collections.emptyMap();
+		Collection<MessageStatus> statuses = Collections.emptyList();
 		txn = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
@@ -240,10 +240,10 @@ public class IntroductionManagerImplTest extends BriarTestCase {
 	public void testIncomingRequestMessage()
 			throws DbException, FormatException {
 
-		final BdfDictionary msg = new BdfDictionary();
+		BdfDictionary msg = new BdfDictionary();
 		msg.put(TYPE, TYPE_REQUEST);
 
-		final BdfDictionary state = new BdfDictionary();
+		BdfDictionary state = new BdfDictionary();
 		txn = new Transaction(null, false);
 
 		context.checking(new Expectations() {{
@@ -267,12 +267,12 @@ public class IntroductionManagerImplTest extends BriarTestCase {
 	public void testIncomingResponseMessage()
 			throws DbException, FormatException {
 
-		final BdfDictionary msg = BdfDictionary.of(
+		BdfDictionary msg = BdfDictionary.of(
 				new BdfEntry(TYPE, TYPE_RESPONSE),
 				new BdfEntry(SESSION_ID, sessionId)
 		);
 
-		final BdfDictionary state = new BdfDictionary();
+		BdfDictionary state = new BdfDictionary();
 		state.put(ROLE, ROLE_INTRODUCER);
 		state.put(GROUP_ID_1, introductionGroup1.getId());
 		state.put(GROUP_ID_2, introductionGroup2.getId());
diff --git a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionValidatorTest.java b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionValidatorTest.java
index 5c3af3a9efedc6ff0d9cd34f223434cc263ea0a3..b37f975f267b216547e0159a2c2d50b86f41fac9 100644
--- a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionValidatorTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionValidatorTest.java
@@ -83,17 +83,17 @@ public class IntroductionValidatorTest extends BriarTestCase {
 
 	@Test
 	public void testValidateProperIntroductionRequest() throws IOException {
-		final byte[] sessionId = TestUtils.getRandomId();
-		final String name = StringUtils.getRandomString(MAX_AUTHOR_NAME_LENGTH);
-		final byte[] publicKey =
+		byte[] sessionId = TestUtils.getRandomId();
+		String name = StringUtils.getRandomString(MAX_AUTHOR_NAME_LENGTH);
+		byte[] publicKey =
 				TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
-		final String text =
+		String text =
 				StringUtils.getRandomString(MAX_INTRODUCTION_MESSAGE_LENGTH);
 
 		BdfList body = BdfList.of(TYPE_REQUEST, sessionId,
 				name, publicKey, text);
 
-		final BdfDictionary result =
+		BdfDictionary result =
 				validator.validateMessage(message, group, body)
 						.getDictionary();
 
@@ -192,7 +192,7 @@ public class IntroductionValidatorTest extends BriarTestCase {
 				msg.getBoolean(ACCEPT), msg.getLong(TIME),
 				msg.getRaw(E_PUBLIC_KEY), msg.getDictionary(TRANSPORT));
 
-		final BdfDictionary result =
+		BdfDictionary result =
 				validator.validateMessage(message, group, body).getDictionary();
 
 		assertEquals(Long.valueOf(TYPE_RESPONSE), result.getLong(TYPE));
diff --git a/briar-core/src/test/java/org/briarproject/briar/introduction/MessageSenderTest.java b/briar-core/src/test/java/org/briarproject/briar/introduction/MessageSenderTest.java
index 71079dbadbd6e2e689bc248b79919844270505f2..ed47f104e03283435240829144574876f0402128 100644
--- a/briar-core/src/test/java/org/briarproject/briar/introduction/MessageSenderTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/introduction/MessageSenderTest.java
@@ -58,26 +58,26 @@ public class MessageSenderTest extends BriarTestCase {
 
 	@Test
 	public void testSendMessage() throws DbException, FormatException {
-		final Transaction txn = new Transaction(null, false);
-		final Group privateGroup =
+		Transaction txn = new Transaction(null, false);
+		Group privateGroup =
 				new Group(new GroupId(TestUtils.getRandomId()),
 						new ClientId(StringUtils.getRandomString(5)),
 						new byte[0]);
-		final SessionId sessionId = new SessionId(TestUtils.getRandomId());
+		SessionId sessionId = new SessionId(TestUtils.getRandomId());
 		byte[] mac = TestUtils.getRandomBytes(42);
 		byte[] sig = TestUtils.getRandomBytes(MAX_SIGNATURE_LENGTH);
-		final long time = 42L;
-		final BdfDictionary msg = BdfDictionary.of(
+		long time = 42L;
+		BdfDictionary msg = BdfDictionary.of(
 				new BdfEntry(TYPE, TYPE_ACK),
 				new BdfEntry(GROUP_ID, privateGroup.getId()),
 				new BdfEntry(SESSION_ID, sessionId),
 				new BdfEntry(MAC, mac),
 				new BdfEntry(SIGNATURE, sig)
 		);
-		final BdfList bodyList =
+		BdfList bodyList =
 				BdfList.of(TYPE_ACK, sessionId.getBytes(), mac, sig);
-		final byte[] body = TestUtils.getRandomBytes(8);
-		final Metadata metadata = new Metadata();
+		byte[] body = TestUtils.getRandomBytes(8);
+		Metadata metadata = new Metadata();
 
 		context.checking(new Expectations() {{
 			oneOf(clientHelper).toByteArray(bodyList);
diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/GroupMessageValidatorTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/GroupMessageValidatorTest.java
index c0253840f2eb1cd1dc2b38dd1c422531db16c506..03ea9b1ba1b144f46578581358788bc737013bc7 100644
--- a/briar-core/src/test/java/org/briarproject/briar/privategroup/GroupMessageValidatorTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/GroupMessageValidatorTest.java
@@ -172,7 +172,7 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
 		BdfMessageContext messageContext =
 				validator.validateMessage(message, group, body);
 		assertExpectedMessageContext(messageContext, JOIN, creator,
-				Collections.<MessageId>emptyList());
+				Collections.emptyList());
 		assertTrue(messageContext.getDictionary()
 				.getBoolean(KEY_INITIAL_JOIN_MSG));
 	}
@@ -325,12 +325,12 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
 		BdfMessageContext messageContext =
 				validator.validateMessage(message, group, body);
 		assertExpectedMessageContext(messageContext, JOIN, member,
-				Collections.<MessageId>emptyList());
+				Collections.emptyList());
 		assertFalse(messageContext.getDictionary()
 				.getBoolean(KEY_INITIAL_JOIN_MSG));
 	}
 
-	private void expectCreateAuthor(final Author member) {
+	private void expectCreateAuthor(Author member) {
 		context.checking(new Expectations() {{
 			oneOf(authorFactory).createAuthor(member.getName(),
 					member.getPublicKey());
@@ -345,10 +345,9 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
 		}});
 	}
 
-	private void expectJoinMessage(final Author member, final BdfList invite,
-			final boolean creatorSigValid, final boolean memberSigValid)
-			throws Exception {
-		final BdfList signed = BdfList.of(group.getId(), message.getTimestamp(),
+	private void expectJoinMessage(Author member, BdfList invite,
+			boolean creatorSigValid, boolean memberSigValid) throws Exception {
+		BdfList signed = BdfList.of(group.getId(), message.getTimestamp(),
 				JOIN.getInt(), member.getName(), member.getPublicKey(), invite);
 		expectCreateAuthor(member);
 		expectParsePrivateGroup();
@@ -610,9 +609,9 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
 				messageContext.getDictionary().containsKey(KEY_PARENT_MSG_ID));
 	}
 
-	private void expectPostMessage(final Author member,
-			final MessageId parentId, final boolean sigValid) throws Exception {
-		final BdfList signed = BdfList.of(group.getId(), message.getTimestamp(),
+	private void expectPostMessage(Author member, MessageId parentId,
+			boolean sigValid) throws Exception {
+		BdfList signed = BdfList.of(group.getId(), message.getTimestamp(),
 				POST.getInt(), member.getName(), member.getPublicKey(),
 				parentId == null ? null : parentId.getBytes(),
 				previousMsgId.getBytes(), postContent);
diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/AbstractProtocolEngineTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/AbstractProtocolEngineTest.java
index aafa34f116d5bc0a2c9a704695324ef2377fa080..b1c3fba815a45835bfda6bfd0397adf76362c1eb 100644
--- a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/AbstractProtocolEngineTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/AbstractProtocolEngineTest.java
@@ -112,14 +112,14 @@ public abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
 		assertEquals(inviteTimestamp, s.getInviteTimestamp());
 	}
 
-	protected void expectGetLocalTimestamp(final long time) {
+	protected void expectGetLocalTimestamp(long time) {
 		context.checking(new Expectations() {{
 			oneOf(clock).currentTimeMillis();
 			will(returnValue(time));
 		}});
 	}
 
-	protected void expectSendInviteMessage(final String msg)
+	protected void expectSendInviteMessage(String msg)
 			throws Exception {
 		context.checking(new Expectations() {{
 			oneOf(messageEncoder)
@@ -131,7 +131,7 @@ public abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
 		expectSendMessage(INVITE, true);
 	}
 
-	protected void expectSendJoinMessage(final JoinMessage m, boolean visible)
+	protected void expectSendJoinMessage(JoinMessage m, boolean visible)
 			throws Exception {
 		expectGetLocalTimestamp(messageTimestamp);
 		context.checking(new Expectations() {{
@@ -165,8 +165,8 @@ public abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
 		expectSendMessage(ABORT, false);
 	}
 
-	private void expectSendMessage(final MessageType type,
-			final boolean visible) throws Exception {
+	private void expectSendMessage(MessageType type, boolean visible)
+			throws Exception {
 		context.checking(new Expectations() {{
 			oneOf(messageEncoder).encodeMetadata(type, privateGroupId,
 					message.getTimestamp(), true, true, visible, false, false);
@@ -175,7 +175,7 @@ public abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
 		}});
 	}
 
-	protected void expectSetPrivateGroupVisibility(final Group.Visibility v)
+	protected void expectSetPrivateGroupVisibility(Group.Visibility v)
 			throws Exception {
 		expectGetContactId();
 		context.checking(new Expectations() {{
@@ -184,7 +184,7 @@ public abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
 	}
 
 	protected void expectGetContactId() throws Exception {
-		final BdfDictionary groupMeta = BdfDictionary
+		BdfDictionary groupMeta = BdfDictionary
 				.of(new BdfEntry(GROUP_KEY_CONTACT_ID, contactId.getInt()));
 		context.checking(new Expectations() {{
 			oneOf(clientHelper)
@@ -211,10 +211,9 @@ public abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
 		}});
 	}
 
-	protected void expectMarkMessageVisibleInUi(final MessageId m,
-			final boolean visible)
+	protected void expectMarkMessageVisibleInUi(MessageId m, boolean visible)
 			throws Exception {
-		final BdfDictionary d = new BdfDictionary();
+		BdfDictionary d = new BdfDictionary();
 		context.checking(new Expectations() {{
 			oneOf(messageEncoder).setVisibleInUi(d, visible);
 			oneOf(clientHelper).mergeMessageMetadata(txn, m, d);
diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/CreatorProtocolEngineTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/CreatorProtocolEngineTest.java
index d116e018d05572872bb2bc82af768728f585144f..22e64a9f98378e79d0ee242d9f24dbcca51474e3 100644
--- a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/CreatorProtocolEngineTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/CreatorProtocolEngineTest.java
@@ -66,7 +66,7 @@ public class CreatorProtocolEngineTest extends AbstractProtocolEngineTest {
 		assertSessionConstantsUnchanged(session, newSession);
 	}
 
-	private void expectOnLocalInvite(final String msg) throws Exception {
+	private void expectOnLocalInvite(String msg) throws Exception {
 		context.checking(new Expectations() {{
 			oneOf(db).getGroup(txn, privateGroupId);
 			will(returnValue(privateGroupGroup));
diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java
index c0bbe0dab07757baf60773abcc4d60347c288a7c..50167d6e27636a48e1b005bb1809e536e3ccf994 100644
--- a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java
@@ -159,8 +159,8 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 		groupInvitationManager.createLocalState(txn);
 	}
 
-	private void expectAddingContact(final Contact c,
-			final boolean contactExists) throws Exception {
+	private void expectAddingContact(Contact c, boolean contactExists)
+			throws Exception {
 		context.checking(new Expectations() {{
 			oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, c);
 			will(returnValue(contactGroup));
@@ -169,7 +169,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 		}});
 		if (contactExists) return;
 
-		final BdfDictionary meta = BdfDictionary
+		BdfDictionary meta = BdfDictionary
 				.of(new BdfEntry(GROUP_KEY_CONTACT_ID, c.getId().getInt()));
 		context.checking(new Expectations() {{
 			oneOf(db).addGroup(txn, contactGroup);
@@ -186,8 +186,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 		expectAddingMember(privateGroup.getId(), c);
 	}
 
-	private void expectAddingMember(final GroupId g, final Contact c)
-			throws Exception {
+	private void expectAddingMember(GroupId g, Contact c) throws Exception {
 		context.checking(new Expectations() {{
 			oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, c);
 			will(returnValue(contactGroup));
@@ -214,8 +213,8 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 		}});
 	}
 
-	private void expectStoreSession(final Session session,
-			final MessageId storageId) throws Exception {
+	private void expectStoreSession(Session session, MessageId storageId)
+			throws Exception {
 		context.checking(new Expectations() {{
 			oneOf(sessionEncoder).encodeSession(session);
 			will(returnValue(meta));
@@ -223,10 +222,9 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 		}});
 	}
 
-	private void expectGetSession(final Map<MessageId, BdfDictionary> results,
-			final SessionId sessionId, final GroupId contactGroupId)
-			throws Exception {
-		final BdfDictionary query = BdfDictionary.of(new BdfEntry("q", "u"));
+	private void expectGetSession(Map<MessageId, BdfDictionary> results,
+			SessionId sessionId, GroupId contactGroupId) throws Exception {
+		BdfDictionary query = BdfDictionary.of(new BdfEntry("q", "u"));
 		context.checking(new Expectations() {{
 			oneOf(sessionParser).getSessionQuery(sessionId);
 			will(returnValue(query));
@@ -327,9 +325,8 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 		expectIncomingMessageWithSession(role, type, bdfSession);
 	}
 
-	private void expectIncomingMessageWithSession(final Role role,
-			final MessageType type, final BdfDictionary bdfSession)
-			throws Exception {
+	private void expectIncomingMessageWithSession(Role role, MessageType type,
+			BdfDictionary bdfSession) throws Exception {
 		expectParseMessageMetadata();
 		expectGetSession(oneResult, sessionId, contactGroup.getId());
 		Session session = expectHandleMessage(role, messageMetadata, bdfSession,
@@ -339,7 +336,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 
 	@Nullable
 	private Session expectHandleFirstMessage(Role role,
-			final MessageMetadata messageMetadata, final MessageType type)
+			MessageMetadata messageMetadata, MessageType type)
 			throws Exception {
 		context.checking(new Expectations() {{
 			oneOf(messageMetadata).getPrivateGroupId();
@@ -367,9 +364,9 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 	}
 
 	@Nullable
-	private Session expectHandleMessage(final Role role,
-			final MessageMetadata messageMetadata, final BdfDictionary state,
-			final MessageType type) throws Exception {
+	private Session expectHandleMessage(Role role,
+			MessageMetadata messageMetadata, BdfDictionary state,
+			MessageType type) throws Exception {
 		context.checking(new Expectations() {{
 			oneOf(messageMetadata).getMessageType();
 			will(returnValue(type));
@@ -405,11 +402,10 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 		}
 	}
 
-	private <S extends Session> void expectIndividualMessage(
-			final MessageType type, final ProtocolEngine<S> engine,
-			final S session) throws Exception {
+	private <S extends Session> void expectIndividualMessage(MessageType type,
+			ProtocolEngine<S> engine, S session) throws Exception {
 		if (type == INVITE) {
-			final InviteMessage msg = context.mock(InviteMessage.class);
+			InviteMessage msg = context.mock(InviteMessage.class);
 			context.checking(new Expectations() {{
 				oneOf(messageParser).parseInviteMessage(message, body);
 				will(returnValue(msg));
@@ -418,7 +414,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 				will(returnValue(session));
 			}});
 		} else if (type == JOIN) {
-			final JoinMessage msg = context.mock(JoinMessage.class);
+			JoinMessage msg = context.mock(JoinMessage.class);
 			context.checking(new Expectations() {{
 				oneOf(messageParser).parseJoinMessage(message, body);
 				will(returnValue(msg));
@@ -427,7 +423,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 				will(returnValue(session));
 			}});
 		} else if (type == LEAVE) {
-			final LeaveMessage msg = context.mock(LeaveMessage.class);
+			LeaveMessage msg = context.mock(LeaveMessage.class);
 			context.checking(new Expectations() {{
 				oneOf(messageParser).parseLeaveMessage(message, body);
 				will(returnValue(msg));
@@ -436,7 +432,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 				will(returnValue(session));
 			}});
 		} else if (type == ABORT) {
-			final AbortMessage msg = context.mock(AbortMessage.class);
+			AbortMessage msg = context.mock(AbortMessage.class);
 			context.checking(new Expectations() {{
 				oneOf(messageParser).parseAbortMessage(message, body);
 				will(returnValue(msg));
@@ -451,9 +447,9 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testSendFirstInvitation() throws Exception {
-		final String msg = "Invitation text for first invitation";
-		final long time = 42L;
-		final byte[] signature = getRandomBytes(42);
+		String msg = "Invitation text for first invitation";
+		long time = 42L;
+		byte[] signature = getRandomBytes(42);
 
 		expectGetSession(noResults, sessionId, contactGroup.getId());
 		context.checking(new Expectations() {{
@@ -482,9 +478,9 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testSendSubsequentInvitation() throws Exception {
-		final String msg = "Invitation text for subsequent invitation";
-		final long time = 43L;
-		final byte[] signature = getRandomBytes(43);
+		String msg = "Invitation text for subsequent invitation";
+		long time = 43L;
+		byte[] signature = getRandomBytes(43);
 
 		expectGetSession(oneResult, sessionId, contactGroup.getId());
 		context.checking(new Expectations() {{
@@ -513,7 +509,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 
 	@Test(expected = IllegalArgumentException.class)
 	public void testRespondToInvitationWithoutSession() throws Exception {
-		final SessionId sessionId = new SessionId(getRandomId());
+		SessionId sessionId = new SessionId(getRandomId());
 
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(false);
@@ -563,8 +559,8 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 		groupInvitationManager.respondToInvitation(contactId, pg, false);
 	}
 
-	private void expectRespondToInvitation(final SessionId sessionId,
-			final boolean accept) throws Exception {
+	private void expectRespondToInvitation(SessionId sessionId, boolean accept)
+			throws Exception {
 		expectGetSession(oneResult, sessionId, contactGroup.getId());
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(false);
@@ -628,25 +624,24 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testGetInvitationMessages() throws Exception {
-		final BdfDictionary query = BdfDictionary.of(new BdfEntry("q", "u"));
-		final MessageId messageId2 = new MessageId(TestUtils.getRandomId());
-		final BdfDictionary meta2 = BdfDictionary.of(new BdfEntry("m2", "e"));
-		final Map<MessageId, BdfDictionary> results =
-				new HashMap<MessageId, BdfDictionary>();
+		BdfDictionary query = BdfDictionary.of(new BdfEntry("q", "u"));
+		MessageId messageId2 = new MessageId(TestUtils.getRandomId());
+		BdfDictionary meta2 = BdfDictionary.of(new BdfEntry("m2", "e"));
+		Map<MessageId, BdfDictionary> results = new HashMap<>();
 		results.put(message.getId(), meta);
 		results.put(messageId2, meta2);
-		final long time1 = 1L, time2 = 2L;
-		final MessageMetadata messageMetadata1 =
+		long time1 = 1L, time2 = 2L;
+		MessageMetadata messageMetadata1 =
 				new MessageMetadata(INVITE, privateGroup.getId(), time1, true,
 						true, true, false, true);
-		final MessageMetadata messageMetadata2 =
+		MessageMetadata messageMetadata2 =
 				new MessageMetadata(JOIN, privateGroup.getId(), time2, true,
 						true, true, true, false);
-		final InviteMessage invite =
+		InviteMessage invite =
 				new InviteMessage(message.getId(), contactGroup.getId(),
 						privateGroup.getId(), time1, "name", author,
 						new byte[0], null, new byte[0]);
-		final PrivateGroup pg =
+		PrivateGroup pg =
 				new PrivateGroup(privateGroup, invite.getGroupName(),
 						invite.getCreator(), invite.getSalt());
 
@@ -702,29 +697,27 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testGetInvitations() throws Exception {
-		final BdfDictionary query = BdfDictionary.of(new BdfEntry("q", "u"));
-		final MessageId messageId2 = new MessageId(TestUtils.getRandomId());
-		final BdfDictionary meta2 = BdfDictionary.of(new BdfEntry("m2", "e"));
-		final Map<MessageId, BdfDictionary> results =
-				new HashMap<MessageId, BdfDictionary>();
+		BdfDictionary query = BdfDictionary.of(new BdfEntry("q", "u"));
+		MessageId messageId2 = new MessageId(TestUtils.getRandomId());
+		BdfDictionary meta2 = BdfDictionary.of(new BdfEntry("m2", "e"));
+		Map<MessageId, BdfDictionary> results = new HashMap<>();
 		results.put(message.getId(), meta);
 		results.put(messageId2, meta2);
-		final Message message2 = new Message(messageId2, contactGroup.getId(),
+		Message message2 = new Message(messageId2, contactGroup.getId(),
 				0L, getRandomBytes(MESSAGE_HEADER_LENGTH + 1));
 		long time1 = 1L, time2 = 2L;
-		final String groupName = getRandomString(MAX_GROUP_NAME_LENGTH);
-		final byte[] salt = getRandomBytes(GROUP_SALT_LENGTH);
-		final InviteMessage inviteMessage1 =
+		String groupName = getRandomString(MAX_GROUP_NAME_LENGTH);
+		byte[] salt = getRandomBytes(GROUP_SALT_LENGTH);
+		InviteMessage inviteMessage1 =
 				new InviteMessage(message.getId(), contactGroup.getId(),
 						privateGroup.getId(), time1, groupName, author, salt,
 						null, getRandomBytes(5));
-		final InviteMessage inviteMessage2 =
-				new InviteMessage(message.getId(), contactGroup.getId(),
+		InviteMessage inviteMessage2 =
+				new InviteMessage(message2.getId(), contactGroup.getId(),
 						privateGroup.getId(), time2, groupName, author, salt,
 						null, getRandomBytes(5));
-		final PrivateGroup pg = new PrivateGroup(privateGroup, groupName,
+		PrivateGroup pg = new PrivateGroup(privateGroup, groupName,
 				author, salt);
-		final BdfList body2 = BdfList.of("body2");
 
 		context.checking(new Expectations() {{
 			oneOf(messageParser).getInvitesAvailableToAnswerQuery();
@@ -796,7 +789,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 				.isInvitationAllowed(contact, privateGroup.getId()));
 	}
 
-	private void expectIsInvitationAllowed(final CreatorState state)
+	private void expectIsInvitationAllowed(CreatorState state)
 			throws Exception {
 		expectGetSession(oneResult, sessionId, contactGroup.getId());
 		context.checking(new Expectations() {{
@@ -826,23 +819,23 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testRemovingGroupEndsSessions() throws Exception {
-		final Contact contact2 = new Contact(new ContactId(2), author,
+		Contact contact2 = new Contact(new ContactId(2), author,
 				author.getId(), true, true);
-		final Contact contact3 = new Contact(new ContactId(3), author,
+		Contact contact3 = new Contact(new ContactId(3), author,
 				author.getId(), true, true);
-		final Collection<Contact> contacts =
+		Collection<Contact> contacts =
 				Arrays.asList(contact, contact2, contact3);
 
-		final Group contactGroup2 = new Group(new GroupId(getRandomId()),
+		Group contactGroup2 = new Group(new GroupId(getRandomId()),
 				CLIENT_ID, getRandomBytes(5));
-		final Group contactGroup3 = new Group(new GroupId(getRandomId()),
+		Group contactGroup3 = new Group(new GroupId(getRandomId()),
 				CLIENT_ID, getRandomBytes(5));
 
-		final MessageId storageId2 = new MessageId(getRandomId());
-		final MessageId storageId3 = new MessageId(getRandomId());
-		final BdfDictionary bdfSession2 =
+		MessageId storageId2 = new MessageId(getRandomId());
+		MessageId storageId3 = new MessageId(getRandomId());
+		BdfDictionary bdfSession2 =
 				BdfDictionary.of(new BdfEntry("f2", "o"));
-		final BdfDictionary bdfSession3 =
+		BdfDictionary bdfSession3 =
 				BdfDictionary.of(new BdfEntry("f3", "o"));
 
 		expectGetSession(oneResult, sessionId, contactGroup.getId());
diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationValidatorTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationValidatorTest.java
index 1a4377e40aa4e37f19434e6e3f7c1f7762fd1d51..136f34075cd6cb8086d8d8994d8bd9594797c9ab 100644
--- a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationValidatorTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationValidatorTest.java
@@ -295,8 +295,8 @@ public class GroupInvitationValidatorTest extends ValidatorTestCase {
 		assertEquals(meta, messageContext.getDictionary());
 	}
 
-	private void expectInviteMessage(final boolean exception) throws Exception {
-		final BdfList signed = BdfList.of(message.getTimestamp(),
+	private void expectInviteMessage(boolean exception) throws Exception {
+		BdfList signed = BdfList.of(message.getTimestamp(),
 				message.getGroupId(), privateGroup.getId());
 		context.checking(new Expectations() {{
 			oneOf(authorFactory).createAuthor(creatorName, creatorKey);
diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/InviteeProtocolEngineTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/InviteeProtocolEngineTest.java
index 1165c7ceeba4805a5cfb5cf14978b226b67ae985..f2eb56a256200c6d49c7d265d17562c281bf9741 100644
--- a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/InviteeProtocolEngineTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/InviteeProtocolEngineTest.java
@@ -127,13 +127,13 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
 
 	@Test
 	public void testOnJoinActionFromInvited() throws Exception {
-		final JoinMessage properJoinMessage =
+		JoinMessage properJoinMessage =
 				new JoinMessage(messageId, contactGroupId, privateGroupId,
 						messageTimestamp, lastRemoteMessageId);
-		final long timestamp = 0L;
-		final GroupMessage joinGroupMessage =
+		long timestamp = 0L;
+		GroupMessage joinGroupMessage =
 				new GroupMessage(message, null, localAuthor);
-		final BdfDictionary meta = new BdfDictionary();
+		BdfDictionary meta = new BdfDictionary();
 
 		expectMarkMessageAvailableToAnswer(lastRemoteMessageId, false);
 		context.checking(new Expectations() {{
@@ -327,7 +327,7 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
 		Author notCreator =
 				new Author(new AuthorId(getRandomId()), "Not Creator",
 						getRandomBytes(5));
-		final Contact notCreatorContact =
+		Contact notCreatorContact =
 				new Contact(contactId, notCreator, localAuthor.getId(), true,
 						true);
 
@@ -346,7 +346,7 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
 	@Test
 	public void testOnInviteMessageFromStart() throws Exception {
 		InviteeSession session = getDefaultSession(START);
-		final InviteMessage properInviteMessage =
+		InviteMessage properInviteMessage =
 				new InviteMessage(new MessageId(getRandomId()), contactGroupId,
 						privateGroupId, session.getInviteTimestamp() + 1,
 						privateGroup.getName(), privateGroup.getCreator(),
@@ -717,9 +717,9 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
 
 	// helper methods
 
-	private void expectMarkMessageAvailableToAnswer(final MessageId id,
-			final boolean available) throws Exception {
-		final BdfDictionary meta = new BdfDictionary();
+	private void expectMarkMessageAvailableToAnswer(MessageId id,
+			boolean available) throws Exception {
+		BdfDictionary meta = new BdfDictionary();
 		context.checking(new Expectations() {{
 			oneOf(messageEncoder)
 					.setAvailableToAnswer(meta, available);
@@ -748,9 +748,9 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
 	}
 
 	private void expectMarkInvitesUnavailableToAnswer() throws Exception {
-		final BdfDictionary query = BdfDictionary.of(new BdfEntry("query", ""));
-		final BdfDictionary meta = BdfDictionary.of(new BdfEntry("meta", ""));
-		final Map<MessageId, BdfDictionary> invites =
+		BdfDictionary query = BdfDictionary.of(new BdfEntry("query", ""));
+		BdfDictionary meta = BdfDictionary.of(new BdfEntry("meta", ""));
+		Map<MessageId, BdfDictionary> invites =
 				Collections.singletonMap(lastRemoteMessageId, meta);
 		context.checking(new Expectations() {{
 			oneOf(messageParser)
diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/PeerProtocolEngineTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/PeerProtocolEngineTest.java
index fb3ebb49a71e89b40eb126a51ebe83bb20190f5c..d5d53168fa57a672bcdd48e187b08b9bbb6065df 100644
--- a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/PeerProtocolEngineTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/PeerProtocolEngineTest.java
@@ -660,7 +660,7 @@ public class PeerProtocolEngineTest extends AbstractProtocolEngineTest {
 
 	// helper methods
 
-	private void expectRelationshipRevealed(final boolean byContact)
+	private void expectRelationshipRevealed(boolean byContact)
 			throws Exception {
 		expectGetContactId();
 		context.checking(new Expectations() {{
diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingIntegrationTest.java
index 39db620840a177bf6df759057aae81d9c0b71df7..8a7a974a817a66ccbc27f28bc12a44ffbdb82b26 100644
--- a/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingIntegrationTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingIntegrationTest.java
@@ -146,9 +146,8 @@ public class BlogSharingIntegrationTest
 		assertTrue(blogManager1.getBlogs().contains(blog2));
 
 		// invitee has one invitation message from sharer
-		List<InvitationMessage> list =
-				new ArrayList<InvitationMessage>(blogSharingManager1
-						.getInvitationMessages(contactId0From1));
+		List<InvitationMessage> list = new ArrayList<>(
+				blogSharingManager1.getInvitationMessages(contactId0From1));
 		assertEquals(2, list.size());
 		// check other things are alright with the message
 		for (InvitationMessage m : list) {
@@ -222,9 +221,8 @@ public class BlogSharingIntegrationTest
 		assertTrue(blogManager1.getBlogs().contains(rssBlog));
 
 		// invitee has one invitation message from sharer
-		List<InvitationMessage> list =
-				new ArrayList<InvitationMessage>(blogSharingManager1
-						.getInvitationMessages(contactId0From1));
+		List<InvitationMessage> list = new ArrayList<>(
+				blogSharingManager1.getInvitationMessages(contactId0From1));
 		assertEquals(2, list.size());
 		// check other things are alright with the message
 		for (InvitationMessage m : list) {
@@ -286,9 +284,8 @@ public class BlogSharingIntegrationTest
 		assertEquals(0, blogSharingManager1.getInvitations().size());
 
 		// invitee has one invitation message from sharer and one response
-		List<InvitationMessage> list =
-				new ArrayList<InvitationMessage>(blogSharingManager1
-						.getInvitationMessages(contactId0From1));
+		List<InvitationMessage> list = new ArrayList<>(
+				blogSharingManager1.getInvitationMessages(contactId0From1));
 		assertEquals(2, list.size());
 		// check things are alright with the  message
 		for (InvitationMessage m : list) {
diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingManagerImplTest.java
index 11ef75f1f9872a6466f4aedc935b8c8e968a699a..a7c76401723561a33efdd7dec370bfbcf5b697a9 100644
--- a/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingManagerImplTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingManagerImplTest.java
@@ -94,23 +94,20 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testAddingContactFreshState() throws Exception {
-		Map<MessageId, BdfDictionary> sessions =
-				new HashMap<MessageId, BdfDictionary>(0);
+		Map<MessageId, BdfDictionary> sessions = new HashMap<>(0);
 		testAddingContact(sessions);
 	}
 
 	@Test
 	public void testAddingContactExistingState() throws Exception {
-		Map<MessageId, BdfDictionary> sessions =
-				new HashMap<MessageId, BdfDictionary>(1);
+		Map<MessageId, BdfDictionary> sessions = new HashMap<>(1);
 		sessions.put(new MessageId(getRandomId()), new BdfDictionary());
 		testAddingContact(sessions);
 	}
 
 	@Test(expected = DbException.class)
 	public void testAddingContactMultipleSessions() throws Exception {
-		Map<MessageId, BdfDictionary> sessions =
-				new HashMap<MessageId, BdfDictionary>(2);
+		Map<MessageId, BdfDictionary> sessions = new HashMap<>(2);
 		sessions.put(new MessageId(getRandomId()), new BdfDictionary());
 		sessions.put(new MessageId(getRandomId()), new BdfDictionary());
 		testAddingContact(sessions);
@@ -118,42 +115,39 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testRemovingBlogFreshState() throws Exception {
-		Map<MessageId, BdfDictionary> sessions =
-				new HashMap<MessageId, BdfDictionary>(0);
+		Map<MessageId, BdfDictionary> sessions = new HashMap<>(0);
 		testRemovingBlog(sessions);
 	}
 
 	@Test
 	public void testRemovingBlogExistingState() throws Exception {
-		Map<MessageId, BdfDictionary> sessions =
-				new HashMap<MessageId, BdfDictionary>(1);
+		Map<MessageId, BdfDictionary> sessions = new HashMap<>(1);
 		sessions.put(new MessageId(getRandomId()), new BdfDictionary());
 		testRemovingBlog(sessions);
 	}
 
 	@Test(expected = DbException.class)
 	public void testRemovingBlogMultipleSessions() throws Exception {
-		Map<MessageId, BdfDictionary> sessions =
-				new HashMap<MessageId, BdfDictionary>(2);
+		Map<MessageId, BdfDictionary> sessions = new HashMap<>(2);
 		sessions.put(new MessageId(getRandomId()), new BdfDictionary());
 		sessions.put(new MessageId(getRandomId()), new BdfDictionary());
 		testRemovingBlog(sessions);
 	}
 
-	private void testAddingContact(final Map<MessageId, BdfDictionary> sessions)
+	private void testAddingContact(Map<MessageId, BdfDictionary> sessions)
 			throws Exception {
-		final Transaction txn = new Transaction(null, false);
-		final LocalAuthor localAuthor =
+		Transaction txn = new Transaction(null, false);
+		LocalAuthor localAuthor =
 				new LocalAuthor(localAuthorId, "Local Author",
 						getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
 						getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
 						System.currentTimeMillis());
-		final BdfDictionary meta = BdfDictionary
+		BdfDictionary meta = BdfDictionary
 				.of(new BdfEntry(GROUP_KEY_CONTACT_ID, contactId.getInt()));
-		final Group localBlogGroup =
+		Group localBlogGroup =
 				new Group(new GroupId(getRandomId()), BlogManager.CLIENT_ID,
 						getRandomBytes(42));
-		final Blog localBlog = new Blog(localBlogGroup, localAuthor, false);
+		Blog localBlog = new Blog(localBlogGroup, localAuthor, false);
 
 		context.checking(new Expectations() {{
 			oneOf(db).getContacts(txn);
@@ -180,14 +174,14 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
 		blogSharingManager.createLocalState(txn);
 	}
 
-	private void expectPreShareShareable(final Transaction txn,
-			final Contact contact, final Blog blog,
-			final Map<MessageId, BdfDictionary> sessions) throws Exception {
-		final Group contactGroup =
+	private void expectPreShareShareable(Transaction txn, Contact contact,
+			Blog blog, Map<MessageId, BdfDictionary> sessions)
+			throws Exception {
+		Group contactGroup =
 				new Group(new GroupId(getRandomId()), CLIENT_ID,
 						getRandomBytes(42));
-		final BdfDictionary sessionDict = new BdfDictionary();
-		final Message message =
+		BdfDictionary sessionDict = new BdfDictionary();
+		Message message =
 				new Message(new MessageId(getRandomId()), contactGroup.getId(),
 						42L, getRandomBytes(1337));
 		context.checking(new Expectations() {{
@@ -217,11 +211,11 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
 		}});
 	}
 
-	private void testRemovingBlog(final Map<MessageId, BdfDictionary> sessions)
+	private void testRemovingBlog(Map<MessageId, BdfDictionary> sessions)
 			throws Exception {
-		final Transaction txn = new Transaction(null, false);
-		final BdfDictionary sessionDict = new BdfDictionary();
-		final Session session = new Session(contactGroup.getId(), blog.getId());
+		Transaction txn = new Transaction(null, false);
+		BdfDictionary sessionDict = new BdfDictionary();
+		Session session = new Session(contactGroup.getId(), blog.getId());
 
 		context.checking(new Expectations() {{
 			oneOf(db).getContacts(txn);
diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingValidatorTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingValidatorTest.java
index a660dd9acb33a776dad792a361acfb06ff16688f..c363f4330ea5d05b99c9efe983854822d021c654 100644
--- a/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingValidatorTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingValidatorTest.java
@@ -175,7 +175,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
 						invalidContent));
 	}
 
-	private void expectCreateBlog(final String name, final byte[] key) {
+	private void expectCreateBlog(String name, byte[] key) {
 		context.checking(new Expectations() {{
 			oneOf(authorFactory).createAuthor(name, key);
 			will(returnValue(author));
diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingIntegrationTest.java
index df1cdd48ff98e2df9ebaaa0af1c9a13bef287700..01cd70589fb3f01b3c9102cf2711faf404dc599c 100644
--- a/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingIntegrationTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingIntegrationTest.java
@@ -129,9 +129,8 @@ public class ForumSharingIntegrationTest
 		assertEquals(1, forumManager1.getForums().size());
 
 		// invitee has one invitation message from sharer
-		List<InvitationMessage> list =
-				new ArrayList<InvitationMessage>(forumSharingManager1
-						.getInvitationMessages(contactId0From1));
+		List<InvitationMessage> list = new ArrayList<>(
+				forumSharingManager1.getInvitationMessages(contactId0From1));
 		assertEquals(2, list.size());
 		// check other things are alright with the forum message
 		for (InvitationMessage m : list) {
@@ -189,9 +188,8 @@ public class ForumSharingIntegrationTest
 		assertEquals(0, forumSharingManager1.getInvitations().size());
 
 		// invitee has one invitation message from sharer and one response
-		List<InvitationMessage> list =
-				new ArrayList<InvitationMessage>(forumSharingManager1
-						.getInvitationMessages(contactId0From1));
+		List<InvitationMessage> list = new ArrayList<>(
+				forumSharingManager1.getInvitationMessages(contactId0From1));
 		assertEquals(2, list.size());
 		// check things are alright with the forum message
 		for (InvitationMessage m : list) {
diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingValidatorTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingValidatorTest.java
index 8ede843f15e1c72ab100709ca541dfb0430439cd..34599f4663a2ba4139f8266c104d177125891e7b 100644
--- a/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingValidatorTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingValidatorTest.java
@@ -165,7 +165,7 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
 						invalidContent));
 	}
 
-	private void expectCreateForum(final String name) {
+	private void expectCreateForum(String name) {
 		context.checking(new Expectations() {{
 			oneOf(forumFactory).createForum(name, salt);
 			will(returnValue(forum));
diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/SharingValidatorTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/SharingValidatorTest.java
index f0c87e9d7319bcefa84432c4675c1a8990576456..20a9b95e7433e7fb7b065aeabb1ad2fdb7d355a7 100644
--- a/briar-core/src/test/java/org/briarproject/briar/sharing/SharingValidatorTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/sharing/SharingValidatorTest.java
@@ -143,7 +143,7 @@ public abstract class SharingValidatorTest extends ValidatorTestCase {
 				BdfList.of(ABORT.getValue(), groupId, previousMsgId, 123));
 	}
 
-	protected void expectEncodeMetadata(final MessageType type) {
+	protected void expectEncodeMetadata(MessageType type) {
 		context.checking(new Expectations() {{
 			oneOf(messageEncoder)
 					.encodeMetadata(type, groupId, timestamp, false, false,