diff --git a/README.md b/README.md
index 4b1317f06d677de4da99e0e42f35c8788aecb0a1..34f5615eaff536c2c03505da2d32ab50fe32656a 100644
--- a/README.md
+++ b/README.md
@@ -88,6 +88,11 @@ any hardware supporting Java (e.g. unix server, raspberry pi) could be added.
 
 [briarproject.org](https://briarproject.org/)
 
+## Server CLI version
+
+A fat JAR for running on a GNU/Linux server can be compiled with
+
+    ./gradlew x86LinuxJar
 
 ## Donate 
 [![Donate using Liberapay](https://briarproject.org/img/liberapay.svg)](https://liberapay.com/Briar/donate) [![Flattr this](https://briarproject.org/img/flattr-badge-large.png "Flattr this")](https://flattr.com/t/592836/)   
diff --git a/mailbox-android/src/main/java/org/briarproject/mailbox/android/AppModule.kt b/mailbox-android/src/main/java/org/briarproject/mailbox/android/AppModule.kt
index ec7f6a9096e20be9679e6975a7208ff093996d27..918541561ffd28db6cb217b45024757e2e3dbd19 100644
--- a/mailbox-android/src/main/java/org/briarproject/mailbox/android/AppModule.kt
+++ b/mailbox-android/src/main/java/org/briarproject/mailbox/android/AppModule.kt
@@ -57,10 +57,10 @@ internal class AppModule {
     fun provideFileProvider(app: Application) = object : FileProvider {
         override val root: File get() = app.applicationContext.filesDir
         override val folderRoot = app.applicationContext.getDir("folders", MODE_PRIVATE)
-        private val tempFilesDir = File(app.applicationContext.cacheDir, "tmp").also { it.mkdirs() }
+        private val tempFilesDir = File(app.applicationContext.cacheDir, "tmp").apply { mkdirs() }
 
         override fun getTemporaryFile(fileId: String) = File(tempFilesDir, fileId)
-        override fun getFolder(folderId: String) = File(folderRoot, folderId).also { it.mkdirs() }
+        override fun getFolder(folderId: String) = File(folderRoot, folderId).apply { mkdirs() }
         override fun getFile(folderId: String, fileId: String) = File(getFolder(folderId), fileId)
     }
 
diff --git a/mailbox-cli/build.gradle b/mailbox-cli/build.gradle
index 96f9cae33f24452668eba7e0d5cf820a312dfa07..b64d6ce7600a85c76f9a30425b6733806932189a 100644
--- a/mailbox-cli/build.gradle
+++ b/mailbox-cli/build.gradle
@@ -95,28 +95,29 @@ void jarFactory(Jar jarTask, jarArchitecture) {
     }
     jarTask.manifest {
         attributes(
-                'Main-Class': application.mainClassName
+                'Main-Class': application.getMainClass()
         )
     }
     jarTask.setArchiveClassifier(jarArchitecture)
     jarTask.from {
-        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
-    }
-            {
-                it.duplicatesStrategy(DuplicatesStrategy.EXCLUDE)
-                String[] architectures = ["linux-aarch64", "linux-armhf", "linux-x86_64"]
-                for (String arch : architectures) {
-                    if (arch != jarArchitecture) {
-                        exclude "obfs4proxy_" + arch + ".zip"
-                        exclude "tor_" + arch + ".zip"
-                    }
-                }
-                exclude 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA'
+        configurations.runtimeClasspath.collect { file ->
+            file.isDirectory() ? file : zipTree(file)
+        }
+    } { copySpec ->
+        copySpec.duplicatesStrategy(DuplicatesStrategy.EXCLUDE)
+        String[] architectures = ["linux-aarch64", "linux-armhf", "linux-x86_64"]
+        for (String arch : architectures) {
+            if (arch != jarArchitecture) {
+                exclude "obfs4proxy_" + arch + ".zip"
+                exclude "tor_" + arch + ".zip"
             }
+        }
+        exclude 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA'
+    }
     jarTask.with jar
     jarTask.doLast {
         // Rename the original jar
-        File jar = jarTask.archivePath
+        File jar = getArchiveFile().get().getAsFile()
         String srcPath = jar.toString().replaceFirst('\\.jar$', '.unsorted.jar')
         File srcFile = new File(srcPath)
         jar.renameTo(srcFile)
@@ -142,10 +143,13 @@ void jarFactory(Jar jarTask, jarArchitecture) {
         destStream.close()
         srcJarFile.close()
         println 'Building ' + jarArchitecture + ' version has finished'
+        println 'JAR: mailbox-cli/build/libs/mailbox-cli-linux-x86_64.jar'
     }
 }
 
 task x86LinuxJar(type: Jar) {
+    group = "Build"
+    description = "Assembles a runnable fat jar for x86-64 Linux"
     jarFactory(it, 'linux-x86_64')
 }
 
diff --git a/mailbox-cli/src/main/java/org/briarproject/mailbox/cli/JavaCliModule.kt b/mailbox-cli/src/main/java/org/briarproject/mailbox/cli/JavaCliModule.kt
index eb5d4421c4442bfef37d3dd880b495d8c599c1da..1e90dcadd2f9929bea369ae47a054aeb263a2685 100644
--- a/mailbox-cli/src/main/java/org/briarproject/mailbox/cli/JavaCliModule.kt
+++ b/mailbox-cli/src/main/java/org/briarproject/mailbox/cli/JavaCliModule.kt
@@ -61,6 +61,11 @@ internal class JavaCliModule {
         private const val DATAHOME_SUBDIR = "briar-mailbox"
     }
 
+    /**
+     * Returns the [File] for the data directory of the mailbox.
+     * If XDG_DATA_HOME is defined, it returns "$XDG_DATA_HOME/briar-mailbox"
+     * and otherwise it returns "~/.local/share/briar-mailbox".
+     */
     private val dataDir: File by lazy {
         val dataHome = when (val custom = System.getenv("XDG_DATA_HOME").orEmpty()) {
             "" -> File(DEFAULT_DATAHOME)
@@ -100,11 +105,11 @@ internal class JavaCliModule {
     @Provides
     fun provideFileProvider() = object : FileProvider {
         override val root: File get() = dataDir
-        private val tempFilesDir = File(dataDir, "tmp").also { it.mkdirs() }
-        override val folderRoot = File(dataDir, "folders").also { it.mkdirs() }
+        private val tempFilesDir = File(dataDir, "tmp").apply { mkdirs() }
+        override val folderRoot = File(dataDir, "folders").apply { mkdirs() }
 
         override fun getTemporaryFile(fileId: String) = File(tempFilesDir, fileId)
-        override fun getFolder(folderId: String) = File(folderRoot, folderId).also { it.mkdirs() }
+        override fun getFolder(folderId: String) = File(folderRoot, folderId).apply { mkdirs() }
         override fun getFile(folderId: String, fileId: String) = File(getFolder(folderId), fileId)
     }
 
diff --git a/mailbox-core/src/main/java/org/briarproject/mailbox/core/files/FileManager.kt b/mailbox-core/src/main/java/org/briarproject/mailbox/core/files/FileManager.kt
index 675dfdc06271c2bb2ebdc990987198fd49038771..8cc0869936a2c50288b8afb435c344174a1c151d 100644
--- a/mailbox-core/src/main/java/org/briarproject/mailbox/core/files/FileManager.kt
+++ b/mailbox-core/src/main/java/org/briarproject/mailbox/core/files/FileManager.kt
@@ -51,7 +51,6 @@ class FileManager @Inject constructor(
      */
     fun hasDbFile(): Boolean {
         val dbDir = dbConfig.getDatabaseDirectory()
-        println("${dbDir.absolutePath} exists: ${dbDir.exists()} isDirectory: ${dbDir.isDirectory}")
         return dbDir.isDirectory
     }
 
diff --git a/mailbox-core/src/main/java/org/briarproject/mailbox/core/files/FileProvider.kt b/mailbox-core/src/main/java/org/briarproject/mailbox/core/files/FileProvider.kt
index f9017f28ae299a6ce47726366ebe106e41a3d0c4..660a790b93060a8c4d546731b19636b78b879f2c 100644
--- a/mailbox-core/src/main/java/org/briarproject/mailbox/core/files/FileProvider.kt
+++ b/mailbox-core/src/main/java/org/briarproject/mailbox/core/files/FileProvider.kt
@@ -25,6 +25,9 @@ interface FileProvider {
     /**
      * The root files directory.
      * Attention: This is not guaranteed to be the parent of other files on all platforms.
+     *            Also this directory and all of its content are deleted during wipe,
+     *            so make sure this is a directory where this doesn't do any harm,
+     *            i.e. a directory used for the mailbox only.
      */
     val root: File
     val folderRoot: File
diff --git a/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/SetupManager.kt b/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/SetupManager.kt
index b1d5aaa18c045ce2cb5be89b8f47e1011e056790..faccb6fdde94d89dff9cfccee8c0e0901dc98006 100644
--- a/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/SetupManager.kt
+++ b/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/SetupManager.kt
@@ -50,6 +50,7 @@ interface SetupManager : OpenDatabaseHook {
     @Throws(DbException::class)
     fun setToken(setupToken: String?, ownerToken: String?)
 
+    @Throws(DbException::class)
     fun getSetupToken(txn: Transaction): String?
 
     @Throws(DbException::class)
@@ -64,6 +65,7 @@ class SetupManagerImpl @Inject constructor(
 
     override val hasDb: Boolean get() = fileManager.hasDbFile()
 
+    @Throws(DbException::class)
     override fun onDatabaseOpened(txn: Transaction) {
         val settings = settingsManager.getSettings(txn, SETTINGS_NAMESPACE_OWNER)
         val setupToken = settings[SETTINGS_SETUP_TOKEN]
@@ -90,6 +92,7 @@ class SetupManagerImpl @Inject constructor(
         settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE_OWNER)
     }
 
+    @Throws(DbException::class)
     override fun getSetupToken(txn: Transaction): String? {
         val settings = settingsManager.getSettings(txn, SETTINGS_NAMESPACE_OWNER)
         return settings[SETTINGS_SETUP_TOKEN]
diff --git a/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/WipeManager.kt b/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/WipeManager.kt
index 6fde359876a0212dcf002a46034ef2c22b466cc1..430c47bd240bd380c3896b72a76e5a10106c1c25 100644
--- a/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/WipeManager.kt
+++ b/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/WipeManager.kt
@@ -24,7 +24,6 @@ import io.ktor.auth.principal
 import io.ktor.http.HttpStatusCode
 import io.ktor.response.respond
 import org.briarproject.mailbox.core.db.Database
-import org.briarproject.mailbox.core.db.DatabaseConfig
 import org.briarproject.mailbox.core.files.FileManager
 import org.briarproject.mailbox.core.lifecycle.LifecycleManager
 import org.briarproject.mailbox.core.server.AuthException
@@ -34,20 +33,23 @@ import javax.inject.Inject
 
 class WipeManager @Inject constructor(
     private val db: Database,
-    private val databaseConfig: DatabaseConfig,
     private val fileManager: FileManager,
 ) {
 
-    /*
-     * This must only be called by the LifecycleManager
+    /**
+     * Drops database tables and then deletes all files, includes the database files.
+     *
+     * This must only be called by the [LifecycleManager].
      */
     fun wipeDatabaseAndFiles() {
         db.dropAllTablesAndClose()
         fileManager.deleteAllFiles()
     }
 
-    /*
-     * This must only be called by the LifecycleManager
+    /**
+     * Deletes all files, includes the database files.
+     *
+     * This must only be called by the [LifecycleManager].
      */
     fun wipeFilesOnly() {
         fileManager.deleteAllFiles()
diff --git a/mailbox-core/src/test/java/org/briarproject/mailbox/core/TestModule.kt b/mailbox-core/src/test/java/org/briarproject/mailbox/core/TestModule.kt
index 1764c14999c730a122f02ccfee6cea3ca34376a8..5ac0c7dfe6ef609fee33651b68b7d308457b7257 100644
--- a/mailbox-core/src/test/java/org/briarproject/mailbox/core/TestModule.kt
+++ b/mailbox-core/src/test/java/org/briarproject/mailbox/core/TestModule.kt
@@ -44,13 +44,14 @@ internal class TestModule(private val tempDir: File) {
     fun provideFileProvider() = object : FileProvider {
         override val root: File get() = tempDir
         override val folderRoot = File(tempDir, "folders")
-        private val tempFilesDir = File(tempDir, "tmp").also { it.mkdirs() }
+        private val tempFilesDir = File(tempDir, "tmp").apply { mkdirs() }
 
-        override fun getTemporaryFile(fileId: String) = File(tempFilesDir, fileId).also { file ->
+        override fun getTemporaryFile(fileId: String) = File(tempFilesDir, fileId).apply {
             // we delete root at the end of each test, so tempFilesDir gets deleted as well
-            file.parentFile.mkdirs()
+            parentFile.mkdirs()
         }
-        override fun getFolder(folderId: String) = File(folderRoot, folderId).also { it.mkdirs() }
+
+        override fun getFolder(folderId: String) = File(folderRoot, folderId).apply { mkdirs() }
         override fun getFile(folderId: String, fileId: String) = File(getFolder(folderId), fileId)
     }
 }