diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.java b/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.java
deleted file mode 100644
index 626b2a7..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.virtualization.terminal;
-
-import static com.android.virtualization.terminal.MainActivity.TAG;
-
-import android.os.Build;
-import android.os.Environment;
-import android.util.Log;
-
-import org.apache.commons.compress.archivers.ArchiveEntry;
-import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
-import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
-
-import java.io.BufferedInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardCopyOption;
-import java.util.Arrays;
-import java.util.function.Function;
-
-/**
- * ImageArchive models the archive file (images.tar.gz) where VM payload files are in. This class
- * provides methods for handling the archive file, most importantly installing it.
- */
-class ImageArchive {
-    private static final String DIR_IN_SDCARD = "linux";
-    private static final String ARCHIVE_NAME = "images.tar.gz";
-    private static final String BUILD_TAG = "latest";
-    private static final String HOST_URL = "https://dl.google.com/android/ferrochrome/" + BUILD_TAG;
-
-    // Only one can be non-null
-    private final URL mUrl;
-    private final Path mPath;
-
-    private ImageArchive(URL url) {
-        mUrl = url;
-        mPath = null;
-    }
-
-    private ImageArchive(Path path) {
-        mUrl = null;
-        mPath = path;
-    }
-
-    public static Path getSdcardPathForTesting() {
-        return Environment.getExternalStoragePublicDirectory(DIR_IN_SDCARD).toPath();
-    }
-
-    /** Creates ImageArchive which is located in the sdcard. This archive is for testing only. */
-    public static ImageArchive fromSdCard() {
-        Path file = getSdcardPathForTesting().resolve(ARCHIVE_NAME);
-        return new ImageArchive(file);
-    }
-
-    /** Creates ImageArchive which is hosted in the Google server. This is the official archive. */
-    public static ImageArchive fromInternet() {
-        String arch = Arrays.asList(Build.SUPPORTED_ABIS).contains("x86_64") ? "x86_64" : "aarch64";
-        try {
-            URL url = new URL(HOST_URL + "/" + arch + "/" + ARCHIVE_NAME);
-            return new ImageArchive(url);
-        } catch (MalformedURLException e) {
-            // cannot happen
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Creates ImageArchive from either SdCard or Internet. SdCard is used only when the build is
-     * debuggable and the file actually exists.
-     */
-    public static ImageArchive getDefault() {
-        ImageArchive archive = fromSdCard();
-        if (Build.isDebuggable() && archive.exists()) {
-            return archive;
-        } else {
-            return fromInternet();
-        }
-    }
-
-    /** Tests if ImageArchive exists on the medium. */
-    public boolean exists() {
-        if (mPath != null) {
-            return Files.exists(mPath);
-        } else {
-            // TODO
-            return true;
-        }
-    }
-
-    /** Returns size of the archive in bytes */
-    public long getSize() throws IOException {
-        if (!exists()) {
-            throw new IllegalStateException("Cannot get size of non existing archive");
-        }
-        if (mPath != null) {
-            return Files.size(mPath);
-        } else {
-            HttpURLConnection conn = null;
-            try {
-                conn = (HttpURLConnection) mUrl.openConnection();
-                conn.setRequestMethod("HEAD");
-                conn.getInputStream();
-                return conn.getContentLength();
-            } finally {
-                if (conn != null) {
-                    conn.disconnect();
-                }
-            }
-        }
-    }
-
-    private InputStream getInputStream(Function<InputStream, InputStream> filter)
-            throws IOException {
-        InputStream is = mPath != null ? new FileInputStream(mPath.toFile()) : mUrl.openStream();
-        BufferedInputStream bufStream = new BufferedInputStream(is);
-        return filter == null ? bufStream : filter.apply(bufStream);
-    }
-
-    /**
-     * Installs this ImageArchive to a directory pointed by path. filter can be supplied to provide
-     * an additional input stream which will be used during the installation.
-     */
-    public void installTo(Path dir, Function<InputStream, InputStream> filter) throws IOException {
-        String source = mPath != null ? mPath.toString() : mUrl.toString();
-        Log.d(TAG, "Installing. source: " + source + ", destination: " + dir.toString());
-        try (InputStream stream = getInputStream(filter);
-                GzipCompressorInputStream gzStream = new GzipCompressorInputStream(stream);
-                TarArchiveInputStream tarStream = new TarArchiveInputStream(gzStream)) {
-
-            Files.createDirectories(dir);
-            ArchiveEntry entry;
-            while ((entry = tarStream.getNextEntry()) != null) {
-                Path to = dir.resolve(entry.getName());
-                if (Files.isDirectory(to)) {
-                    Files.createDirectories(to);
-                    continue;
-                }
-                Files.copy(tarStream, to, StandardCopyOption.REPLACE_EXISTING);
-            }
-        }
-        commitInstallationAt(dir);
-    }
-
-    private void commitInstallationAt(Path dir) throws IOException {
-        // To save storage, delete the source archive on the disk.
-        if (mPath != null) {
-            Files.deleteIfExists(mPath);
-        }
-
-        // Mark the completion
-        Path marker = dir.resolve(InstalledImage.MARKER_FILENAME);
-        Files.createFile(marker);
-    }
-}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.kt b/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.kt
new file mode 100644
index 0000000..e84250b
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.kt
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.virtualization.terminal
+
+import android.os.Build
+import android.os.Environment
+import android.util.Log
+import com.android.virtualization.terminal.MainActivity.TAG
+import java.io.BufferedInputStream
+import java.io.FileInputStream
+import java.io.IOException
+import java.io.InputStream
+import java.lang.RuntimeException
+import java.net.HttpURLConnection
+import java.net.MalformedURLException
+import java.net.URL
+import java.nio.file.Files
+import java.nio.file.Path
+import java.nio.file.StandardCopyOption
+import java.util.function.Function
+import org.apache.commons.compress.archivers.ArchiveEntry
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream
+import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream
+
+/**
+ * ImageArchive models the archive file (images.tar.gz) where VM payload files are in. This class
+ * provides methods for handling the archive file, most importantly installing it.
+ */
+internal class ImageArchive {
+    // Only one can be non-null
+    private sealed class Source<out A, out B>
+
+    private data class UrlSource<out Url>(val value: Url) : Source<Url, Nothing>()
+
+    private data class PathSource<out Path>(val value: Path) : Source<Nothing, Path>()
+
+    private val source: Source<URL, Path>
+
+    private constructor(url: URL) {
+        source = UrlSource(url)
+    }
+
+    private constructor(path: Path) {
+        source = PathSource(path)
+    }
+
+    /** Tests if ImageArchive exists on the medium. */
+    fun exists(): Boolean {
+        return when (source) {
+            is UrlSource -> true
+            is PathSource -> Files.exists(source.value)
+        }
+    }
+
+    /** Returns size of the archive in bytes */
+    @Throws(IOException::class)
+    fun getSize(): Long {
+        check(exists()) { "Cannot get size of non existing archive" }
+        return when (source) {
+            is UrlSource -> {
+                val conn = source.value.openConnection() as HttpURLConnection
+                try {
+                    conn.requestMethod = "HEAD"
+                    conn.getInputStream()
+                    return conn.contentLength.toLong()
+                } finally {
+                    conn.disconnect()
+                }
+            }
+            is PathSource -> Files.size(source.value)
+        }
+    }
+
+    @Throws(IOException::class)
+    private fun getInputStream(filter: Function<InputStream, InputStream>?): InputStream? {
+        val bufStream =
+            BufferedInputStream(
+                when (source) {
+                    is UrlSource -> source.value.openStream()
+                    is PathSource -> FileInputStream(source.value.toFile())
+                }
+            )
+        return filter?.apply(bufStream) ?: bufStream
+    }
+
+    /**
+     * Installs this ImageArchive to a directory pointed by path. filter can be supplied to provide
+     * an additional input stream which will be used during the installation.
+     */
+    @Throws(IOException::class)
+    fun installTo(dir: Path, filter: Function<InputStream, InputStream>?) {
+        val source =
+            when (source) {
+                is PathSource -> source.value.toString()
+                is UrlSource -> source.value.toString()
+            }
+        Log.d(TAG, "Installing. source: $source, destination: $dir")
+        TarArchiveInputStream(GzipCompressorInputStream(getInputStream(filter))).use { tarStream ->
+            Files.createDirectories(dir)
+            var entry: ArchiveEntry?
+            while ((tarStream.nextEntry.also { entry = it }) != null) {
+                val to = dir.resolve(entry!!.getName())
+                if (Files.isDirectory(to)) {
+                    Files.createDirectories(to)
+                    continue
+                }
+                Files.copy(tarStream, to, StandardCopyOption.REPLACE_EXISTING)
+            }
+        }
+        commitInstallationAt(dir)
+    }
+
+    @Throws(IOException::class)
+    private fun commitInstallationAt(dir: Path) {
+        // To save storage, delete the source archive on the disk.
+        if (source is PathSource) {
+            Files.deleteIfExists(source.value)
+        }
+
+        // Mark the completion
+        val marker = dir.resolve(InstalledImage.MARKER_FILENAME)
+        Files.createFile(marker)
+    }
+
+    companion object {
+        private const val DIR_IN_SDCARD = "linux"
+        private const val ARCHIVE_NAME = "images.tar.gz"
+        private const val BUILD_TAG = "latest" // TODO: use actual tag name
+        private const val HOST_URL = "https://dl.google.com/android/ferrochrome/$BUILD_TAG"
+
+        @JvmStatic
+        fun getSdcardPathForTesting(): Path? {
+            return Environment.getExternalStoragePublicDirectory(DIR_IN_SDCARD).toPath()
+        }
+
+        /**
+         * Creates ImageArchive which is located in the sdcard. This archive is for testing only.
+         */
+        @JvmStatic
+        fun fromSdCard(): ImageArchive {
+            return ImageArchive(getSdcardPathForTesting()!!.resolve(ARCHIVE_NAME))
+        }
+
+        /**
+         * Creates ImageArchive which is hosted in the Google server. This is the official archive.
+         */
+        @JvmStatic
+        fun fromInternet(): ImageArchive {
+            val arch =
+                if (listOf<String?>(*Build.SUPPORTED_ABIS).contains("x86_64")) "x86_64"
+                else "aarch64"
+            try {
+                return ImageArchive(URL("$HOST_URL/$arch/$ARCHIVE_NAME"))
+            } catch (e: MalformedURLException) {
+                // cannot happen
+                throw RuntimeException(e)
+            }
+        }
+
+        /**
+         * Creates ImageArchive from either SdCard or Internet. SdCard is used only when the build
+         * is debuggable and the file actually exists.
+         */
+        @JvmStatic
+        fun getDefault(): ImageArchive {
+            val archive = fromSdCard()
+            return if (Build.isDebuggable() && archive.exists()) {
+                archive
+            } else {
+                fromInternet()
+            }
+        }
+    }
+}
