diff --git a/savedstate/savedstate/api/current.txt b/savedstate/savedstate/api/current.txt
index 6ef8e87..e1371e1 100644
--- a/savedstate/savedstate/api/current.txt
+++ b/savedstate/savedstate/api/current.txt
@@ -2,19 +2,22 @@
 package androidx.savedstate {
 
   public final class SavedStateRegistry {
-    method @MainThread public android.os.Bundle? consumeRestoredStateForKey(String);
-    method public androidx.savedstate.SavedStateRegistry.SavedStateProvider? getSavedStateProvider(String);
+    method @MainThread public android.os.Bundle? consumeRestoredStateForKey(String key);
+    method public androidx.savedstate.SavedStateRegistry.SavedStateProvider? getSavedStateProvider(String key);
     method @MainThread public boolean isRestored();
-    method @MainThread public void registerSavedStateProvider(String, androidx.savedstate.SavedStateRegistry.SavedStateProvider);
-    method @MainThread public void runOnNextRecreation(Class<? extends androidx.savedstate.SavedStateRegistry.AutoRecreated>);
-    method @MainThread public void unregisterSavedStateProvider(String);
+    method @MainThread public void performAttach(androidx.lifecycle.Lifecycle lifecycle);
+    method @MainThread public void performRestore(android.os.Bundle? savedState);
+    method @MainThread public void registerSavedStateProvider(String key, androidx.savedstate.SavedStateRegistry.SavedStateProvider provider);
+    method @MainThread public void runOnNextRecreation(Class<? extends androidx.savedstate.SavedStateRegistry.AutoRecreated> clazz);
+    method @MainThread public void unregisterSavedStateProvider(String key);
+    property @MainThread public final boolean isRestored;
   }
 
   public static interface SavedStateRegistry.AutoRecreated {
-    method public void onRecreated(androidx.savedstate.SavedStateRegistryOwner);
+    method public void onRecreated(androidx.savedstate.SavedStateRegistryOwner owner);
   }
 
-  public static interface SavedStateRegistry.SavedStateProvider {
+  public static fun interface SavedStateRegistry.SavedStateProvider {
     method public android.os.Bundle saveState();
   }
 
diff --git a/savedstate/savedstate/api/public_plus_experimental_current.txt b/savedstate/savedstate/api/public_plus_experimental_current.txt
index 6ef8e87..e1371e1 100644
--- a/savedstate/savedstate/api/public_plus_experimental_current.txt
+++ b/savedstate/savedstate/api/public_plus_experimental_current.txt
@@ -2,19 +2,22 @@
 package androidx.savedstate {
 
   public final class SavedStateRegistry {
-    method @MainThread public android.os.Bundle? consumeRestoredStateForKey(String);
-    method public androidx.savedstate.SavedStateRegistry.SavedStateProvider? getSavedStateProvider(String);
+    method @MainThread public android.os.Bundle? consumeRestoredStateForKey(String key);
+    method public androidx.savedstate.SavedStateRegistry.SavedStateProvider? getSavedStateProvider(String key);
     method @MainThread public boolean isRestored();
-    method @MainThread public void registerSavedStateProvider(String, androidx.savedstate.SavedStateRegistry.SavedStateProvider);
-    method @MainThread public void runOnNextRecreation(Class<? extends androidx.savedstate.SavedStateRegistry.AutoRecreated>);
-    method @MainThread public void unregisterSavedStateProvider(String);
+    method @MainThread public void performAttach(androidx.lifecycle.Lifecycle lifecycle);
+    method @MainThread public void performRestore(android.os.Bundle? savedState);
+    method @MainThread public void registerSavedStateProvider(String key, androidx.savedstate.SavedStateRegistry.SavedStateProvider provider);
+    method @MainThread public void runOnNextRecreation(Class<? extends androidx.savedstate.SavedStateRegistry.AutoRecreated> clazz);
+    method @MainThread public void unregisterSavedStateProvider(String key);
+    property @MainThread public final boolean isRestored;
   }
 
   public static interface SavedStateRegistry.AutoRecreated {
-    method public void onRecreated(androidx.savedstate.SavedStateRegistryOwner);
+    method public void onRecreated(androidx.savedstate.SavedStateRegistryOwner owner);
   }
 
-  public static interface SavedStateRegistry.SavedStateProvider {
+  public static fun interface SavedStateRegistry.SavedStateProvider {
     method public android.os.Bundle saveState();
   }
 
diff --git a/savedstate/savedstate/api/restricted_current.txt b/savedstate/savedstate/api/restricted_current.txt
index 6ef8e87..e1371e1 100644
--- a/savedstate/savedstate/api/restricted_current.txt
+++ b/savedstate/savedstate/api/restricted_current.txt
@@ -2,19 +2,22 @@
 package androidx.savedstate {
 
   public final class SavedStateRegistry {
-    method @MainThread public android.os.Bundle? consumeRestoredStateForKey(String);
-    method public androidx.savedstate.SavedStateRegistry.SavedStateProvider? getSavedStateProvider(String);
+    method @MainThread public android.os.Bundle? consumeRestoredStateForKey(String key);
+    method public androidx.savedstate.SavedStateRegistry.SavedStateProvider? getSavedStateProvider(String key);
     method @MainThread public boolean isRestored();
-    method @MainThread public void registerSavedStateProvider(String, androidx.savedstate.SavedStateRegistry.SavedStateProvider);
-    method @MainThread public void runOnNextRecreation(Class<? extends androidx.savedstate.SavedStateRegistry.AutoRecreated>);
-    method @MainThread public void unregisterSavedStateProvider(String);
+    method @MainThread public void performAttach(androidx.lifecycle.Lifecycle lifecycle);
+    method @MainThread public void performRestore(android.os.Bundle? savedState);
+    method @MainThread public void registerSavedStateProvider(String key, androidx.savedstate.SavedStateRegistry.SavedStateProvider provider);
+    method @MainThread public void runOnNextRecreation(Class<? extends androidx.savedstate.SavedStateRegistry.AutoRecreated> clazz);
+    method @MainThread public void unregisterSavedStateProvider(String key);
+    property @MainThread public final boolean isRestored;
   }
 
   public static interface SavedStateRegistry.AutoRecreated {
-    method public void onRecreated(androidx.savedstate.SavedStateRegistryOwner);
+    method public void onRecreated(androidx.savedstate.SavedStateRegistryOwner owner);
   }
 
-  public static interface SavedStateRegistry.SavedStateProvider {
+  public static fun interface SavedStateRegistry.SavedStateProvider {
     method public android.os.Bundle saveState();
   }
 
diff --git a/savedstate/savedstate/src/main/java/androidx/savedstate/SavedStateRegistry.kt b/savedstate/savedstate/src/main/java/androidx/savedstate/SavedStateRegistry.kt
index 3bca4f1..a8bd28d 100644
--- a/savedstate/savedstate/src/main/java/androidx/savedstate/SavedStateRegistry.kt
+++ b/savedstate/savedstate/src/main/java/androidx/savedstate/SavedStateRegistry.kt
@@ -13,270 +13,259 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package androidx.savedstate
 
-package androidx.savedstate;
-
-import android.annotation.SuppressLint;
-import android.os.Bundle;
-
-import androidx.annotation.MainThread;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.arch.core.internal.SafeIterableMap;
-import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.LifecycleEventObserver;
-
-import java.util.Iterator;
-import java.util.Map;
+import android.annotation.SuppressLint
+import android.os.Bundle
+import androidx.annotation.MainThread
+import androidx.arch.core.internal.SafeIterableMap
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleEventObserver
 
 /**
  * An interface for plugging components that consumes and contributes to the saved state.
  *
- * <p>This objects lifetime is bound to the lifecycle of owning component: when activity or
+ *
+ * This objects lifetime is bound to the lifecycle of owning component: when activity or
  * fragment is recreated, new instance of the object is created as well.
  */
 @SuppressLint("RestrictedApi")
-public final class SavedStateRegistry {
-    private static final String SAVED_COMPONENTS_KEY =
-            "androidx.lifecycle.BundlableSavedStateRegistry.key";
-
-    private final SafeIterableMap<String, SavedStateProvider> mComponents =
-            new SafeIterableMap<>();
-    private boolean mAttached;
-    @Nullable
-    private Bundle mRestoredState;
-    private boolean mRestored;
-    private Recreator.SavedStateProvider mRecreatorProvider;
-    boolean mAllowingSavingState = true;
-
-    SavedStateRegistry() {
-    }
+class SavedStateRegistry internal constructor() {
+    private val components = SafeIterableMap<String, SavedStateProvider>()
+    private var attached = false
+    private var restoredState: Bundle? = null
 
     /**
-     * Consumes saved state previously supplied by {@link SavedStateProvider} registered
-     * via {@link #registerSavedStateProvider(String, SavedStateProvider)}
-     * with the given {@code key}.
-     * <p>
+     * Whether the state was restored after creation and can be safely consumed
+     * with [consumeRestoredStateForKey].
+     *
+     * [isRestored] == true if state was restored
+     */
+    @get: MainThread
+    var isRestored = false
+        private set
+    private var recreatorProvider: Recreator.SavedStateProvider? = null
+    internal var isAllowingSavingState = true
+
+    /**
+     * Consumes saved state previously supplied by [SavedStateProvider] registered
+     * via [registerSavedStateProvider] with the given `key`.
+     *
+     *
      * This call clears an internal reference to returned saved state, so if you call it second time
-     * in the row it will return {@code null}.
-     * <p>
-     * All unconsumed values will be saved during {@code onSaveInstanceState(Bundle savedState)}
-     * <p>
-     * This method can be called after {@code super.onCreate(savedStateBundle)} of the corresponding
-     * component. Calling it before that will result in {@code IllegalArgumentException}.
-     * {@link Lifecycle.Event#ON_CREATE} can be used as a signal
+     * in the row it will return `null`.
+     *
+     *
+     * All unconsumed values will be saved during `onSaveInstanceState(Bundle savedState)`
+     *
+     *
+     * This method can be called after `super.onCreate(savedStateBundle)` of the corresponding
+     * component. Calling it before that will result in `IllegalArgumentException`.
+     * [Lifecycle.Event.ON_CREATE] can be used as a signal
      * that a saved state can be safely consumed.
      *
-     * @param key a key with which {@link SavedStateProvider} was previously registered.
-     * @return {@code S} with the previously saved state or {@code null}
+     * @param key a key with which [SavedStateProvider] was previously registered.
+     * @return `S` with the previously saved state or {@code null}
      */
     @MainThread
-    @Nullable
-    public Bundle consumeRestoredStateForKey(@NonNull String key) {
-        if (!mRestored) {
-            throw new IllegalStateException("You can consumeRestoredStateForKey "
-                    + "only after super.onCreate of corresponding component");
+    fun consumeRestoredStateForKey(key: String): Bundle? {
+        check(isRestored) {
+            ("You can consumeRestoredStateForKey " +
+                "only after super.onCreate of corresponding component")
         }
-        if (mRestoredState != null) {
-            Bundle result = mRestoredState.getBundle(key);
-            mRestoredState.remove(key);
-            if (mRestoredState.isEmpty()) {
-                mRestoredState = null;
+        if (restoredState != null) {
+            val result = restoredState?.getBundle(key)
+            restoredState?.remove(key)
+            if (restoredState?.isEmpty != false) {
+                restoredState = null
             }
-            return result;
+            return result
         }
-        return null;
+        return null
     }
 
     /**
-     * Registers a {@link SavedStateProvider} by the given {@code key}. This
-     * {@code savedStateProvider} will be called
-     * during state saving phase, returned object will be associated with the given {@code key}
-     * and can be used after the restoration via {@link #consumeRestoredStateForKey(String)}.
-     * <p>
-     * If there is unconsumed value with the same {@code key},
-     * the value supplied by {@code savedStateProvider} will be override and
+     * Registers a [SavedStateProvider] by the given `key`. This
+     * `savedStateProvider` will be called
+     * during state saving phase, returned object will be associated with the given `key`
+     * and can be used after the restoration via [.consumeRestoredStateForKey].
+     *
+     *
+     * If there is unconsumed value with the same `key`,
+     * the value supplied by `savedStateProvider` will be overridden and
      * will be written to resulting saved state.
-     * <p> if a provider was already registered with the given {@code key}, an implementation should
-     * throw an {@link IllegalArgumentException}
+     *
+     * If a provider was already registered with the given `key`, an implementation should
+     * throw an [IllegalArgumentException]
      *
      * @param key      a key with which returned saved state will be associated
      * @param provider savedStateProvider to get saved state.
      */
     @MainThread
-    public void registerSavedStateProvider(@NonNull String key,
-            @NonNull SavedStateProvider provider) {
-        SavedStateProvider previous = mComponents.putIfAbsent(key, provider);
-        if (previous != null) {
-            throw new IllegalArgumentException("SavedStateProvider with the given key is"
-                    + " already registered");
+    fun registerSavedStateProvider(
+        key: String,
+        provider: SavedStateProvider
+    ) {
+        val previous = components.putIfAbsent(key, provider)
+        require(previous == null) {
+            ("SavedStateProvider with the given key is" +
+                " already registered")
         }
     }
 
     /**
-     * Get a previously registered {@link SavedStateProvider}.
+     * Get a previously registered [SavedStateProvider].
      *
-     * @param key The key used to register the {@link SavedStateProvider} when it was registered
-     *            with {@link #registerSavedStateProvider(String, SavedStateProvider)}.
-     * @return The {@link SavedStateProvider} previously registered with
-     * {@link #registerSavedStateProvider(String, SavedStateProvider)} or null if no provider
+     * @param key The key used to register the [SavedStateProvider] when it was registered
+     *            with registerSavedStateProvider(String, SavedStateProvider).
+     *
+     * Returns the [SavedStateProvider] previously registered with
+     * [registerSavedStateProvider] or null if no provider
      * has been registered with the given key.
-     * @see #registerSavedStateProvider(String, SavedStateProvider)
      */
-    @Nullable
-    public SavedStateProvider getSavedStateProvider(@NonNull String key) {
-        SavedStateProvider provider = null;
-        for (Map.Entry<String, SavedStateProvider> entry : mComponents) {
-            if (entry.getKey().equals(key)) {
-                provider = entry.getValue();
-                break;
+    fun getSavedStateProvider(key: String): SavedStateProvider? {
+        var provider: SavedStateProvider? = null
+        for ((k, value) in components) {
+            if (k == key) {
+                provider = value
+                break
             }
         }
-        return provider;
+        return provider
     }
 
     /**
-     * Unregisters a component previously registered by the given {@code key}
+     * Unregisters a component previously registered by the given `key`
      *
      * @param key a key with which a component was previously registered.
      */
     @MainThread
-    public void unregisterSavedStateProvider(@NonNull String key) {
-        mComponents.remove(key);
-    }
-
-    /**
-     * Returns if state was restored after creation and can be safely consumed
-     * with {@link #consumeRestoredStateForKey(String)}
-     *
-     * @return true if state was restored.
-     */
-    @MainThread
-    public boolean isRestored() {
-        return mRestored;
+    fun unregisterSavedStateProvider(key: String) {
+        components.remove(key)
     }
 
     /**
      * Subclasses of this interface will be automatically recreated if they were previously
-     * registered via {@link #runOnNextRecreation(Class)}.
-     * <p>
+     * registered via [runOnNextRecreation].
+     *
+     *
      * Subclasses must have a default constructor
      */
-    public interface AutoRecreated {
+    interface AutoRecreated {
         /**
          * This method will be called during
-         * dispatching of {@link androidx.lifecycle.Lifecycle.Event#ON_CREATE} of owning component.
+         * dispatching of [androidx.lifecycle.Lifecycle.Event.ON_CREATE] of owning component
+         * which was restarted
          *
          * @param owner a component that was restarted
          */
-        void onRecreated(@NonNull SavedStateRegistryOwner owner);
+        fun onRecreated(owner: SavedStateRegistryOwner)
     }
 
     /**
      * Executes the given class when the owning component restarted.
-     * <p>
+     *
+     *
      * The given class will be automatically instantiated via default constructor and method
-     * {@link AutoRecreated#onRecreated(SavedStateRegistryOwner)} will be called.
-     * It is called as part of dispatching of {@link androidx.lifecycle.Lifecycle.Event#ON_CREATE}
+     * [AutoRecreated.onRecreated] will be called.
+     * It is called as part of dispatching of [androidx.lifecycle.Lifecycle.Event.ON_CREATE]
      * event.
      *
      * @param clazz that will need to be instantiated on the next component recreation
-     * @throws IllegalStateException if you try to call if after {@link Lifecycle.Event#ON_STOP}
+     * @throws IllegalArgumentException if you try to call if after [Lifecycle.Event.ON_STOP]
      *                               was dispatched
      */
     @MainThread
-    public void runOnNextRecreation(@NonNull Class<? extends AutoRecreated> clazz) {
-        if (!mAllowingSavingState) {
-            throw new IllegalStateException(
-                    "Can not perform this action after onSaveInstanceState");
-        }
-        if (mRecreatorProvider == null) {
-            mRecreatorProvider = new Recreator.SavedStateProvider(this);
-        }
+    fun runOnNextRecreation(clazz: Class<out AutoRecreated>) {
+        check(isAllowingSavingState) { "Can not perform this action after onSaveInstanceState" }
+        recreatorProvider = recreatorProvider ?: Recreator.SavedStateProvider(this)
         try {
-            clazz.getDeclaredConstructor();
-        } catch (NoSuchMethodException e) {
-            throw new IllegalArgumentException("Class" + clazz.getSimpleName() + " must have "
-                    + "default constructor in order to be automatically recreated", e);
+            clazz.getDeclaredConstructor()
+        } catch (e: NoSuchMethodException) {
+            throw IllegalArgumentException(
+                "Class ${clazz.simpleName} must have " +
+                    "default constructor in order to be automatically recreated", e
+            )
         }
-        mRecreatorProvider.add(clazz.getName());
+        recreatorProvider?.add(clazz.name)
     }
 
     /**
-     * An interface for an owner of this @{code {@link SavedStateRegistry} to attach this
-     * to a {@link Lifecycle}.
+     * An interface for an owner of this [SavedStateRegistry] to attach this
+     * to a [Lifecycle].
      */
     @MainThread
-    void performAttach(@NonNull Lifecycle lifecycle) {
-        if (mAttached) {
-            throw new IllegalStateException("SavedStateRegistry was already attached.");
-        }
+    fun performAttach(lifecycle: Lifecycle) {
+        check(!attached) { "SavedStateRegistry was already attached." }
 
-        lifecycle.addObserver((LifecycleEventObserver) (source, event) -> {
+        lifecycle.addObserver(LifecycleEventObserver { _, event ->
             if (event == Lifecycle.Event.ON_START) {
-                mAllowingSavingState = true;
+                isAllowingSavingState = true
             } else if (event == Lifecycle.Event.ON_STOP) {
-                mAllowingSavingState = false;
+                isAllowingSavingState = false
             }
-        });
-
-        mAttached = true;
+        })
+        attached = true
     }
 
     /**
-     * An interface for an owner of this @{code {@link SavedStateRegistry} to restore saved state.
+     * An interface for an owner of this [SavedStateRegistry] to restore saved state.
      *
      */
     @MainThread
-    void performRestore(@Nullable Bundle savedState) {
-        if (!mAttached) {
-            throw new IllegalStateException("You must call performAttach() before calling "
-                    + "performRestore(Bundle).");
+    fun performRestore(savedState: Bundle?) {
+        check(attached) {
+            ("You must call performAttach() before calling " +
+                "performRestore(Bundle).")
         }
-        if (mRestored) {
-            throw new IllegalStateException("SavedStateRegistry was already restored.");
-        }
-        if (savedState != null) {
-            mRestoredState = savedState.getBundle(SAVED_COMPONENTS_KEY);
-        }
+        check(!isRestored) { "SavedStateRegistry was already restored." }
+        restoredState = savedState?.getBundle(SAVED_COMPONENTS_KEY)
 
-        mRestored = true;
+        isRestored = true
     }
 
     /**
-     * An interface for an owner of this @{code {@link SavedStateRegistry}
+     * An interface for an owner of this [SavedStateRegistry]
      * to perform state saving, it will call all registered providers and
      * merge with unconsumed state.
      *
      * @param outBundle Bundle in which to place a saved state
+     * @suppress INACCESSIBLE_TYPE iterator is used strictly as Iterator, does not access
+     * inaccessible type IteratorWithAdditions
      */
     @MainThread
-    void performSave(@NonNull Bundle outBundle) {
-        Bundle components = new Bundle();
-        if (mRestoredState != null) {
-            components.putAll(mRestoredState);
+    @Suppress("INACCESSIBLE_TYPE")
+    fun performSave(outBundle: Bundle) {
+        val components = Bundle()
+        if (restoredState != null) {
+            components.putAll(restoredState)
         }
-        for (Iterator<Map.Entry<String, SavedStateProvider>> it =
-                mComponents.iteratorWithAdditions(); it.hasNext(); ) {
-            Map.Entry<String, SavedStateProvider> entry1 = it.next();
-            components.putBundle(entry1.getKey(), entry1.getValue().saveState());
+        val it: Iterator<Map.Entry<String, SavedStateProvider>> =
+            this.components.iteratorWithAdditions()
+        while (it.hasNext()) {
+            val (key, value) = it.next()
+            components.putBundle(key, value.saveState())
         }
-        if (!components.isEmpty()) {
-            outBundle.putBundle(SAVED_COMPONENTS_KEY, components);
+        if (!components.isEmpty) {
+            outBundle.putBundle(SAVED_COMPONENTS_KEY, components)
         }
     }
 
     /**
      * This interface marks a component that contributes to saved state.
      */
-    public interface SavedStateProvider {
+    fun interface SavedStateProvider {
         /**
          * Called to retrieve a state from a component before being killed
-         * so later the state can be received from {@link #consumeRestoredStateForKey(String)}
+         * so later the state can be received from [consumeRestoredStateForKey]
          *
-         * @return S with your saved state.
+         * Returns `S` with your saved state.
          */
-        @NonNull
-        Bundle saveState();
+        fun saveState(): Bundle
+    }
+
+    private companion object {
+        private const val SAVED_COMPONENTS_KEY =
+            "androidx.lifecycle.BundlableSavedStateRegistry.key"
     }
 }
