diff --git a/lifecycle/lifecycle-runtime/api/current.txt b/lifecycle/lifecycle-runtime/api/current.txt
index 5bbe95f..c7da237 100644
--- a/lifecycle/lifecycle-runtime/api/current.txt
+++ b/lifecycle/lifecycle-runtime/api/current.txt
@@ -2,15 +2,22 @@
 package androidx.lifecycle {
 
   public class LifecycleRegistry extends androidx.lifecycle.Lifecycle {
-    ctor public LifecycleRegistry(androidx.lifecycle.LifecycleOwner);
-    method public void addObserver(androidx.lifecycle.LifecycleObserver);
-    method @VisibleForTesting public static androidx.lifecycle.LifecycleRegistry createUnsafe(androidx.lifecycle.LifecycleOwner);
+    ctor public LifecycleRegistry(androidx.lifecycle.LifecycleOwner provider);
+    method public void addObserver(androidx.lifecycle.LifecycleObserver observer);
+    method @VisibleForTesting public static final androidx.lifecycle.LifecycleRegistry createUnsafe(androidx.lifecycle.LifecycleOwner owner);
     method public androidx.lifecycle.Lifecycle.State getCurrentState();
     method public int getObserverCount();
-    method public void handleLifecycleEvent(androidx.lifecycle.Lifecycle.Event);
-    method @Deprecated @MainThread public void markState(androidx.lifecycle.Lifecycle.State);
-    method public void removeObserver(androidx.lifecycle.LifecycleObserver);
-    method @MainThread public void setCurrentState(androidx.lifecycle.Lifecycle.State);
+    method public void handleLifecycleEvent(androidx.lifecycle.Lifecycle.Event event);
+    method @Deprecated @MainThread public void markState(androidx.lifecycle.Lifecycle.State state);
+    method public void removeObserver(androidx.lifecycle.LifecycleObserver observer);
+    method public void setCurrentState(androidx.lifecycle.Lifecycle.State);
+    property public androidx.lifecycle.Lifecycle.State currentState;
+    property public int observerCount;
+    field public static final androidx.lifecycle.LifecycleRegistry.Companion Companion;
+  }
+
+  public static final class LifecycleRegistry.Companion {
+    method @VisibleForTesting public androidx.lifecycle.LifecycleRegistry createUnsafe(androidx.lifecycle.LifecycleOwner owner);
   }
 
   @Deprecated public interface LifecycleRegistryOwner extends androidx.lifecycle.LifecycleOwner {
diff --git a/lifecycle/lifecycle-runtime/api/public_plus_experimental_current.txt b/lifecycle/lifecycle-runtime/api/public_plus_experimental_current.txt
index 5bbe95f..c7da237 100644
--- a/lifecycle/lifecycle-runtime/api/public_plus_experimental_current.txt
+++ b/lifecycle/lifecycle-runtime/api/public_plus_experimental_current.txt
@@ -2,15 +2,22 @@
 package androidx.lifecycle {
 
   public class LifecycleRegistry extends androidx.lifecycle.Lifecycle {
-    ctor public LifecycleRegistry(androidx.lifecycle.LifecycleOwner);
-    method public void addObserver(androidx.lifecycle.LifecycleObserver);
-    method @VisibleForTesting public static androidx.lifecycle.LifecycleRegistry createUnsafe(androidx.lifecycle.LifecycleOwner);
+    ctor public LifecycleRegistry(androidx.lifecycle.LifecycleOwner provider);
+    method public void addObserver(androidx.lifecycle.LifecycleObserver observer);
+    method @VisibleForTesting public static final androidx.lifecycle.LifecycleRegistry createUnsafe(androidx.lifecycle.LifecycleOwner owner);
     method public androidx.lifecycle.Lifecycle.State getCurrentState();
     method public int getObserverCount();
-    method public void handleLifecycleEvent(androidx.lifecycle.Lifecycle.Event);
-    method @Deprecated @MainThread public void markState(androidx.lifecycle.Lifecycle.State);
-    method public void removeObserver(androidx.lifecycle.LifecycleObserver);
-    method @MainThread public void setCurrentState(androidx.lifecycle.Lifecycle.State);
+    method public void handleLifecycleEvent(androidx.lifecycle.Lifecycle.Event event);
+    method @Deprecated @MainThread public void markState(androidx.lifecycle.Lifecycle.State state);
+    method public void removeObserver(androidx.lifecycle.LifecycleObserver observer);
+    method public void setCurrentState(androidx.lifecycle.Lifecycle.State);
+    property public androidx.lifecycle.Lifecycle.State currentState;
+    property public int observerCount;
+    field public static final androidx.lifecycle.LifecycleRegistry.Companion Companion;
+  }
+
+  public static final class LifecycleRegistry.Companion {
+    method @VisibleForTesting public androidx.lifecycle.LifecycleRegistry createUnsafe(androidx.lifecycle.LifecycleOwner owner);
   }
 
   @Deprecated public interface LifecycleRegistryOwner extends androidx.lifecycle.LifecycleOwner {
diff --git a/lifecycle/lifecycle-runtime/api/restricted_current.txt b/lifecycle/lifecycle-runtime/api/restricted_current.txt
index 74af488..4602a21 100644
--- a/lifecycle/lifecycle-runtime/api/restricted_current.txt
+++ b/lifecycle/lifecycle-runtime/api/restricted_current.txt
@@ -2,15 +2,22 @@
 package androidx.lifecycle {
 
   public class LifecycleRegistry extends androidx.lifecycle.Lifecycle {
-    ctor public LifecycleRegistry(androidx.lifecycle.LifecycleOwner);
-    method public void addObserver(androidx.lifecycle.LifecycleObserver);
-    method @VisibleForTesting public static androidx.lifecycle.LifecycleRegistry createUnsafe(androidx.lifecycle.LifecycleOwner);
+    ctor public LifecycleRegistry(androidx.lifecycle.LifecycleOwner provider);
+    method public void addObserver(androidx.lifecycle.LifecycleObserver observer);
+    method @VisibleForTesting public static final androidx.lifecycle.LifecycleRegistry createUnsafe(androidx.lifecycle.LifecycleOwner owner);
     method public androidx.lifecycle.Lifecycle.State getCurrentState();
     method public int getObserverCount();
-    method public void handleLifecycleEvent(androidx.lifecycle.Lifecycle.Event);
-    method @Deprecated @MainThread public void markState(androidx.lifecycle.Lifecycle.State);
-    method public void removeObserver(androidx.lifecycle.LifecycleObserver);
-    method @MainThread public void setCurrentState(androidx.lifecycle.Lifecycle.State);
+    method public void handleLifecycleEvent(androidx.lifecycle.Lifecycle.Event event);
+    method @Deprecated @MainThread public void markState(androidx.lifecycle.Lifecycle.State state);
+    method public void removeObserver(androidx.lifecycle.LifecycleObserver observer);
+    method public void setCurrentState(androidx.lifecycle.Lifecycle.State);
+    property public androidx.lifecycle.Lifecycle.State currentState;
+    property public int observerCount;
+    field public static final androidx.lifecycle.LifecycleRegistry.Companion Companion;
+  }
+
+  public static final class LifecycleRegistry.Companion {
+    method @VisibleForTesting public androidx.lifecycle.LifecycleRegistry createUnsafe(androidx.lifecycle.LifecycleOwner owner);
   }
 
   @Deprecated public interface LifecycleRegistryOwner extends androidx.lifecycle.LifecycleOwner {
diff --git a/lifecycle/lifecycle-runtime/build.gradle b/lifecycle/lifecycle-runtime/build.gradle
index bd48528..dc3c2eb 100644
--- a/lifecycle/lifecycle-runtime/build.gradle
+++ b/lifecycle/lifecycle-runtime/build.gradle
@@ -3,6 +3,7 @@
 plugins {
     id("AndroidXPlugin")
     id("com.android.library")
+    id("org.jetbrains.kotlin.android")
 }
 
 android {
@@ -13,6 +14,7 @@
 }
 
 dependencies {
+    api(libs.kotlinStdlib)
     api(project(":lifecycle:lifecycle-common"))
 
     api("androidx.arch.core:core-common:2.1.0")
diff --git a/lifecycle/lifecycle-runtime/src/main/java/androidx/lifecycle/LifecycleRegistry.kt b/lifecycle/lifecycle-runtime/src/main/java/androidx/lifecycle/LifecycleRegistry.kt
index 5279d4c..a0d64db 100644
--- a/lifecycle/lifecycle-runtime/src/main/java/androidx/lifecycle/LifecycleRegistry.kt
+++ b/lifecycle/lifecycle-runtime/src/main/java/androidx/lifecycle/LifecycleRegistry.kt
@@ -13,34 +13,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package androidx.lifecycle
 
-package androidx.lifecycle;
-
-import static androidx.lifecycle.Lifecycle.State.DESTROYED;
-import static androidx.lifecycle.Lifecycle.State.INITIALIZED;
-
-import android.annotation.SuppressLint;
-
-import androidx.annotation.MainThread;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.arch.core.executor.ArchTaskExecutor;
-import androidx.arch.core.internal.FastSafeIterableMap;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Map;
+import android.annotation.SuppressLint
+import androidx.annotation.MainThread
+import androidx.annotation.VisibleForTesting
+import androidx.arch.core.executor.ArchTaskExecutor
+import androidx.arch.core.internal.FastSafeIterableMap
+import java.lang.ref.WeakReference
 
 /**
- * An implementation of {@link Lifecycle} that can handle multiple observers.
- * <p>
+ * An implementation of [Lifecycle] that can handle multiple observers.
+ *
  * It is used by Fragments and Support Library Activities. You can also directly use it if you have
  * a custom LifecycleOwner.
  */
-public class LifecycleRegistry extends Lifecycle {
-
+open class LifecycleRegistry private constructor(
+    provider: LifecycleOwner,
+    private val enforceMainThread: Boolean
+) : Lifecycle() {
     /**
      * Custom list that keeps observers and can handle removals / additions during traversal.
      *
@@ -48,12 +39,13 @@
      * if addition_order(observer1) < addition_order(observer2), then
      * state(observer1) >= state(observer2),
      */
-    private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
-            new FastSafeIterableMap<>();
+    private var observerMap = FastSafeIterableMap<LifecycleObserver, ObserverWithState>()
+
     /**
      * Current state
      */
-    private State mState;
+    private var state: State = State.INITIALIZED
+
     /**
      * The provider that owns this Lifecycle.
      * Only WeakReference on LifecycleOwner is kept, so if somebody leaks Lifecycle, they won't leak
@@ -61,12 +53,10 @@
      * because it keeps strong references on all other listeners, so you'll leak all of them as
      * well.
      */
-    private final WeakReference<LifecycleOwner> mLifecycleOwner;
-
-    private int mAddingObserverCounter = 0;
-
-    private boolean mHandlingEvent = false;
-    private boolean mNewEventOccurred = false;
+    private val lifecycleOwner: WeakReference<LifecycleOwner>
+    private var addingObserverCounter = 0
+    private var handlingEvent = false
+    private var newEventOccurred = false
 
     // we have to keep it for cases:
     // void onStart() {
@@ -74,40 +64,22 @@
     //     mRegistry.add(newObserver);
     // }
     // newObserver should be brought only to CREATED state during the execution of
-    // this onStart method. our invariant with mObserverMap doesn't help, because parent observer
+    // this onStart method. our invariant with observerMap doesn't help, because parent observer
     // is no longer in the map.
-    private ArrayList<State> mParentStates = new ArrayList<>();
-    private final boolean mEnforceMainThread;
+    private var parentStates = ArrayList<State>()
 
     /**
      * Creates a new LifecycleRegistry for the given provider.
-     * <p>
+     *
      * You should usually create this inside your LifecycleOwner class's constructor and hold
      * onto the same instance.
      *
      * @param provider The owner LifecycleOwner
      */
-    public LifecycleRegistry(@NonNull LifecycleOwner provider) {
-        this(provider, true);
-    }
+    constructor(provider: LifecycleOwner) : this(provider, true)
 
-    private LifecycleRegistry(@NonNull LifecycleOwner provider, boolean enforceMainThread) {
-        mLifecycleOwner = new WeakReference<>(provider);
-        mState = INITIALIZED;
-        mEnforceMainThread = enforceMainThread;
-    }
-
-    /**
-     * Moves the Lifecycle to the given state and dispatches necessary events to the observers.
-     *
-     * @param state new state
-     * @deprecated Use {@link #setCurrentState(State)}.
-     */
-    @Deprecated
-    @MainThread
-    public void markState(@NonNull State state) {
-        enforceMainThreadIfNeeded("markState");
-        setCurrentState(state);
+    init {
+        lifecycleOwner = WeakReference(provider)
     }
 
     /**
@@ -116,114 +88,129 @@
      * @param state new state
      */
     @MainThread
-    public void setCurrentState(@NonNull State state) {
-        enforceMainThreadIfNeeded("setCurrentState");
-        moveToState(state);
+    @Deprecated("Override [currentState].")
+    open fun markState(state: State) {
+        enforceMainThreadIfNeeded("markState")
+        currentState = state
     }
 
+    override var currentState: State
+        get() = state
+        /**
+         * Moves the Lifecycle to the given state and dispatches necessary events to the observers.
+         *
+         * @param state new state
+         */
+        set(state) {
+            enforceMainThreadIfNeeded("setCurrentState")
+            moveToState(state)
+        }
+
     /**
      * Sets the current state and notifies the observers.
-     * <p>
-     * Note that if the {@code currentState} is the same state as the last call to this method,
+     *
+     * Note that if the `currentState` is the same state as the last call to this method,
      * calling this method has no effect.
      *
      * @param event The event that was received
      */
-    public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
-        enforceMainThreadIfNeeded("handleLifecycleEvent");
-        moveToState(event.getTargetState());
+    open fun handleLifecycleEvent(event: Event) {
+        enforceMainThreadIfNeeded("handleLifecycleEvent")
+        moveToState(event.targetState)
     }
 
-    private void moveToState(State next) {
-        if (mState == next) {
-            return;
+    private fun moveToState(next: State) {
+        if (state == next) {
+            return
         }
-        if (mState == INITIALIZED && next == DESTROYED) {
-            throw new IllegalStateException(
-                    "no event down from " + mState + " in component " + mLifecycleOwner.get());
+        check(!(state == State.INITIALIZED && next == State.DESTROYED)) {
+            "no event down from $state in component ${lifecycleOwner.get()}"
         }
-        mState = next;
-        if (mHandlingEvent || mAddingObserverCounter != 0) {
-            mNewEventOccurred = true;
+        state = next
+        if (handlingEvent || addingObserverCounter != 0) {
+            newEventOccurred = true
             // we will figure out what to do on upper level.
-            return;
+            return
         }
-        mHandlingEvent = true;
-        sync();
-        mHandlingEvent = false;
-        if (mState == DESTROYED) {
-            mObserverMap = new FastSafeIterableMap<>();
+        handlingEvent = true
+        sync()
+        handlingEvent = false
+        if (state == State.DESTROYED) {
+            observerMap = FastSafeIterableMap()
         }
     }
 
-    private boolean isSynced() {
-        if (mObserverMap.size() == 0) {
-            return true;
-        }
-        State eldestObserverState = mObserverMap.eldest().getValue().mState;
-        State newestObserverState = mObserverMap.newest().getValue().mState;
-        return eldestObserverState == newestObserverState && mState == newestObserverState;
-    }
-
-    private State calculateTargetState(LifecycleObserver observer) {
-        Map.Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);
-
-        State siblingState = previous != null ? previous.getValue().mState : null;
-        State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
-                : null;
-        return min(min(mState, siblingState), parentState);
-    }
-
-    @Override
-    public void addObserver(@NonNull LifecycleObserver observer) {
-        enforceMainThreadIfNeeded("addObserver");
-        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
-        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
-        ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
-
-        if (previous != null) {
-            return;
-        }
-        LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
-        if (lifecycleOwner == null) {
-            // it is null we should be destroyed. Fallback quickly
-            return;
-        }
-
-        boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
-        State targetState = calculateTargetState(observer);
-        mAddingObserverCounter++;
-        while ((statefulObserver.mState.compareTo(targetState) < 0
-                && mObserverMap.contains(observer))) {
-            pushParentState(statefulObserver.mState);
-            final Event event = Event.upFrom(statefulObserver.mState);
-            if (event == null) {
-                throw new IllegalStateException("no event up from " + statefulObserver.mState);
+    private val isSynced: Boolean
+        get() {
+            if (observerMap.size() == 0) {
+                return true
             }
-            statefulObserver.dispatchEvent(lifecycleOwner, event);
-            popParentState();
-            // mState / subling may have been changed recalculate
-            targetState = calculateTargetState(observer);
+            val eldestObserverState = observerMap.eldest()!!.value.state
+            val newestObserverState = observerMap.newest()!!.value.state
+            return eldestObserverState == newestObserverState && state == newestObserverState
         }
 
+    private fun calculateTargetState(observer: LifecycleObserver): State {
+        val map = observerMap.ceil(observer)
+        val siblingState = map?.value?.state
+        val parentState =
+            if (parentStates.isNotEmpty()) parentStates[parentStates.size - 1] else null
+        return min(min(state, siblingState), parentState)
+    }
+
+    /**
+     * Adds a LifecycleObserver that will be notified when the LifecycleOwner changes
+     * state.
+     *
+     * The given observer will be brought to the current state of the LifecycleOwner.
+     * For example, if the LifecycleOwner is in [Lifecycle.State.STARTED] state, the given observer
+     * will receive [Lifecycle.Event.ON_CREATE], [Lifecycle.Event.ON_START] events.
+     *
+     * @param observer The observer to notify.
+     *
+     * @throws IllegalStateException if no event up from observer's initial state
+     */
+    override fun addObserver(observer: LifecycleObserver) {
+        enforceMainThreadIfNeeded("addObserver")
+        val initialState = if (state == State.DESTROYED) State.DESTROYED else State.INITIALIZED
+        val statefulObserver = ObserverWithState(observer, initialState)
+        val previous = observerMap.putIfAbsent(observer, statefulObserver)
+        if (previous != null) {
+            return
+        }
+        val lifecycleOwner = lifecycleOwner.get()
+            ?: // it is null we should be destroyed. Fallback quickly
+            return
+        val isReentrance = addingObserverCounter != 0 || handlingEvent
+        var targetState = calculateTargetState(observer)
+        addingObserverCounter++
+        while (statefulObserver.state < targetState && observerMap.contains(observer)
+        ) {
+            pushParentState(statefulObserver.state)
+            val event = Event.upFrom(statefulObserver.state)
+                ?: throw IllegalStateException("no event up from ${statefulObserver.state}")
+            statefulObserver.dispatchEvent(lifecycleOwner, event)
+            popParentState()
+            // mState / subling may have been changed recalculate
+            targetState = calculateTargetState(observer)
+        }
         if (!isReentrance) {
             // we do sync only on the top level.
-            sync();
+            sync()
         }
-        mAddingObserverCounter--;
+        addingObserverCounter--
     }
 
-    private void popParentState() {
-        mParentStates.remove(mParentStates.size() - 1);
+    private fun popParentState() {
+        parentStates.removeAt(parentStates.size - 1)
     }
 
-    private void pushParentState(State state) {
-        mParentStates.add(state);
+    private fun pushParentState(state: State) {
+        parentStates.add(state)
     }
 
-    @Override
-    public void removeObserver(@NonNull LifecycleObserver observer) {
-        enforceMainThreadIfNeeded("removeObserver");
+    override fun removeObserver(observer: LifecycleObserver) {
+        enforceMainThreadIfNeeded("removeObserver")
         // we consciously decided not to send destruction events here in opposition to addObserver.
         // Our reasons for that:
         // 1. These events haven't yet happened at all. In contrast to events in addObservers, that
@@ -236,7 +223,7 @@
         // lost an internet and as a result you removed this observer. If you get destruction
         // events in removeObserver, you should have a special case in your onStop method that
         // checks if your web connection died and you shouldn't try to report anything to a server.
-        mObserverMap.remove(observer);
+        observerMap.remove(observer)
     }
 
     /**
@@ -244,122 +231,109 @@
      *
      * @return The number of observers.
      */
-    @SuppressWarnings("WeakerAccess")
-    public int getObserverCount() {
-        enforceMainThreadIfNeeded("getObserverCount");
-        return mObserverMap.size();
-    }
+    open val observerCount: Int
+        get() {
+            enforceMainThreadIfNeeded("getObserverCount")
+            return observerMap.size()
+        }
 
-    @NonNull
-    @Override
-    public State getCurrentState() {
-        return mState;
-    }
-
-    private void forwardPass(LifecycleOwner lifecycleOwner) {
-        Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
-                mObserverMap.iteratorWithAdditions();
-        while (ascendingIterator.hasNext() && !mNewEventOccurred) {
-            Map.Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
-            ObserverWithState observer = entry.getValue();
-            while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
-                    && mObserverMap.contains(entry.getKey()))) {
-                pushParentState(observer.mState);
-                final Event event = Event.upFrom(observer.mState);
-                if (event == null) {
-                    throw new IllegalStateException("no event up from " + observer.mState);
-                }
-                observer.dispatchEvent(lifecycleOwner, event);
-                popParentState();
+    private fun forwardPass(lifecycleOwner: LifecycleOwner) {
+        @Suppress()
+        val ascendingIterator: Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> =
+            observerMap.iteratorWithAdditions()
+        while (ascendingIterator.hasNext() && !newEventOccurred) {
+            val (key, observer) = ascendingIterator.next()
+            while (observer.state < state && !newEventOccurred && observerMap.contains(key)
+            ) {
+                pushParentState(observer.state)
+                val event = Event.upFrom(observer.state)
+                    ?: throw IllegalStateException("no event up from ${observer.state}")
+                observer.dispatchEvent(lifecycleOwner, event)
+                popParentState()
             }
         }
     }
 
-    private void backwardPass(LifecycleOwner lifecycleOwner) {
-        Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
-                mObserverMap.descendingIterator();
-        while (descendingIterator.hasNext() && !mNewEventOccurred) {
-            Map.Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
-            ObserverWithState observer = entry.getValue();
-            while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
-                    && mObserverMap.contains(entry.getKey()))) {
-                Event event = Event.downFrom(observer.mState);
-                if (event == null) {
-                    throw new IllegalStateException("no event down from " + observer.mState);
-                }
-                pushParentState(event.getTargetState());
-                observer.dispatchEvent(lifecycleOwner, event);
-                popParentState();
+    private fun backwardPass(lifecycleOwner: LifecycleOwner) {
+        val descendingIterator = observerMap.descendingIterator()
+        while (descendingIterator.hasNext() && !newEventOccurred) {
+            val (key, observer) = descendingIterator.next()
+            while (observer.state > state && !newEventOccurred && observerMap.contains(key)
+            ) {
+                val event = Event.downFrom(observer.state)
+                    ?: throw IllegalStateException("no event down from ${observer.state}")
+                pushParentState(event.targetState)
+                observer.dispatchEvent(lifecycleOwner, event)
+                popParentState()
             }
         }
     }
 
     // happens only on the top of stack (never in reentrance),
     // so it doesn't have to take in account parents
-    private void sync() {
-        LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
-        if (lifecycleOwner == null) {
-            throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
-                    + "garbage collected. It is too late to change lifecycle state.");
-        }
-        while (!isSynced()) {
-            mNewEventOccurred = false;
-            // no need to check eldest for nullability, because isSynced does it for us.
-            if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
-                backwardPass(lifecycleOwner);
+    private fun sync() {
+        val lifecycleOwner = lifecycleOwner.get()
+            ?: throw IllegalStateException(
+                "LifecycleOwner of this LifecycleRegistry is already " +
+                    "garbage collected. It is too late to change lifecycle state."
+            )
+        while (!isSynced) {
+            newEventOccurred = false
+            if (state < observerMap.eldest()!!.value.state) {
+                backwardPass(lifecycleOwner)
             }
-            Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
-            if (!mNewEventOccurred && newest != null
-                    && mState.compareTo(newest.getValue().mState) > 0) {
-                forwardPass(lifecycleOwner);
+            val newest = observerMap.newest()
+            if (!newEventOccurred && newest != null && state > newest.value.state) {
+                forwardPass(lifecycleOwner)
             }
         }
-        mNewEventOccurred = false;
+        newEventOccurred = false
     }
 
     @SuppressLint("RestrictedApi")
-    private void enforceMainThreadIfNeeded(String methodName) {
-        if (mEnforceMainThread) {
-            if (!ArchTaskExecutor.getInstance().isMainThread()) {
-                throw new IllegalStateException("Method " + methodName + " must be called on the "
-                        + "main thread");
+    private fun enforceMainThreadIfNeeded(methodName: String) {
+        if (enforceMainThread) {
+            check(ArchTaskExecutor.getInstance().isMainThread) {
+                ("Method $methodName must be called on the main thread")
             }
         }
     }
 
-    /**
-     * Creates a new LifecycleRegistry for the given provider, that doesn't check
-     * that its methods are called on the threads other than main.
-     * <p>
-     * LifecycleRegistry is not synchronized: if multiple threads access this {@code
-     * LifecycleRegistry}, it must be synchronized externally.
-     * <p>
-     * Another possible use-case for this method is JVM testing, when main thread is not present.
-     */
-    @VisibleForTesting
-    @NonNull
-    public static LifecycleRegistry createUnsafe(@NonNull LifecycleOwner owner) {
-        return new LifecycleRegistry(owner, false);
-    }
+    internal class ObserverWithState(observer: LifecycleObserver?, initialState: State) {
+        var state: State
+        var lifecycleObserver: LifecycleEventObserver
 
-    static State min(@NonNull State state1, @Nullable State state2) {
-        return state2 != null && state2.compareTo(state1) < 0 ? state2 : state1;
-    }
-
-    static class ObserverWithState {
-        State mState;
-        LifecycleEventObserver mLifecycleObserver;
-
-        ObserverWithState(LifecycleObserver observer, State initialState) {
-            mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
-            mState = initialState;
+        init {
+            lifecycleObserver = Lifecycling.lifecycleEventObserver(observer)
+            state = initialState
         }
 
-        void dispatchEvent(LifecycleOwner owner, Event event) {
-            State newState = event.getTargetState();
-            mState = min(mState, newState);
-            mLifecycleObserver.onStateChanged(owner, event);
-            mState = newState;
+        fun dispatchEvent(owner: LifecycleOwner?, event: Event) {
+            val newState = event.targetState
+            state = min(state, newState)
+            lifecycleObserver.onStateChanged(owner!!, event)
+            state = newState
         }
     }
-}
+
+    companion object {
+        /**
+         * Creates a new LifecycleRegistry for the given provider, that doesn't check
+         * that its methods are called on the threads other than main.
+         *
+         * LifecycleRegistry is not synchronized: if multiple threads access this `LifecycleRegistry`, it must be synchronized externally.
+         *
+         * Another possible use-case for this method is JVM testing, when main thread is not present.
+         */
+        @JvmStatic
+        @VisibleForTesting
+        fun createUnsafe(owner: LifecycleOwner): LifecycleRegistry {
+            return LifecycleRegistry(owner, false)
+        }
+
+        @JvmStatic
+        internal fun min(state1: State, state2: State?): State {
+            return if ((state2 != null) && (state2 < state1)) state2 else state1
+        }
+    }
+}
\ No newline at end of file
