diff --git a/app/src/main/java/im/vector/riotredesign/core/extensions/LiveData.kt b/app/src/main/java/im/vector/riotredesign/core/extensions/LiveData.kt
index bf33acda5b..b012483a4a 100644
--- a/app/src/main/java/im/vector/riotredesign/core/extensions/LiveData.kt
+++ b/app/src/main/java/im/vector/riotredesign/core/extensions/LiveData.kt
@@ -3,7 +3,7 @@ package im.vector.riotredesign.core.extensions
 import android.arch.lifecycle.LifecycleOwner
 import android.arch.lifecycle.LiveData
 import android.arch.lifecycle.Observer
-import im.vector.riotredesign.core.utils.Event
+import im.vector.riotredesign.core.utils.LiveEvent
 import im.vector.riotredesign.core.utils.EventObserver
 
 inline fun <T> LiveData<T>.observeK(owner: LifecycleOwner, crossinline observer: (T?) -> Unit) {
@@ -14,6 +14,6 @@ inline fun <T> LiveData<T>.observeNotNull(owner: LifecycleOwner, crossinline obs
     this.observe(owner, Observer { it?.run(observer) })
 }
 
-inline fun <T> LiveData<Event<T>>.observeEvent(owner: LifecycleOwner, crossinline observer: (T) -> Unit) {
+inline fun <T> LiveData<LiveEvent<T>>.observeEvent(owner: LifecycleOwner, crossinline observer: (T) -> Unit) {
     this.observe(owner, EventObserver { it.run(observer) })
 }
\ No newline at end of file
diff --git a/app/src/main/java/im/vector/riotredesign/core/utils/Constants.kt b/app/src/main/java/im/vector/riotredesign/core/utils/Constants.kt
deleted file mode 100644
index ade18b3617..0000000000
--- a/app/src/main/java/im/vector/riotredesign/core/utils/Constants.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package im.vector.riotredesign.core.utils
-
-object Constants {
-
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/im/vector/riotredesign/core/utils/FragmentArgumentDelegate.kt b/app/src/main/java/im/vector/riotredesign/core/utils/FragmentArgumentDelegate.kt
deleted file mode 100644
index 565c421cae..0000000000
--- a/app/src/main/java/im/vector/riotredesign/core/utils/FragmentArgumentDelegate.kt
+++ /dev/null
@@ -1,63 +0,0 @@
-package im.vector.riotredesign.core.utils
-
-import android.os.Binder
-import android.os.Bundle
-import android.support.v4.app.BundleCompat
-import android.support.v4.app.Fragment
-import kotlin.reflect.KProperty
-
-class FragmentArgumentDelegate<T : Any> : kotlin.properties.ReadWriteProperty<Fragment, T?> {
-
-    var value: T? = null
-
-    override operator fun getValue(thisRef: android.support.v4.app.Fragment, property: kotlin.reflect.KProperty<*>): T? {
-        if (value == null) {
-            val args = thisRef.arguments
-            @Suppress("UNCHECKED_CAST")
-            value = args?.get(property.name) as T?
-        }
-        return value
-    }
-
-    override operator fun setValue(thisRef: Fragment, property: KProperty<*>, value: T?) {
-        if (value == null) return
-
-        if (thisRef.arguments == null) {
-            thisRef.arguments = Bundle()
-        }
-        val args = thisRef.arguments!!
-        val key = property.name
-
-        when (value) {
-            is String                -> args.putString(key, value)
-            is Int                   -> args.putInt(key, value)
-            is Short                 -> args.putShort(key, value)
-            is Long                  -> args.putLong(key, value)
-            is Byte                  -> args.putByte(key, value)
-            is ByteArray             -> args.putByteArray(key, value)
-            is Char                  -> args.putChar(key, value)
-            is CharArray             -> args.putCharArray(key, value)
-            is CharSequence          -> args.putCharSequence(key, value)
-            is Float                 -> args.putFloat(key, value)
-            is Bundle                -> args.putBundle(key, value)
-            is Binder                -> BundleCompat.putBinder(args, key, value)
-            is android.os.Parcelable -> args.putParcelable(key, value)
-            is java.io.Serializable  -> args.putSerializable(key, value)
-            else                     -> throw IllegalStateException("Type ${value.javaClass.name} of property ${property.name} is not supported")
-        }
-    }
-}
-
-class UnsafeFragmentArgumentDelegate<T : Any> : kotlin.properties.ReadWriteProperty<Fragment, T> {
-
-    private val innerDelegate = FragmentArgumentDelegate<T>()
-
-    override fun setValue(thisRef: Fragment, property: KProperty<*>, value: T) {
-        innerDelegate.setValue(thisRef, property, value)
-    }
-
-    override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
-        return innerDelegate.getValue(thisRef, property)!!
-    }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/im/vector/riotredesign/core/utils/Event.kt b/app/src/main/java/im/vector/riotredesign/core/utils/LiveEvent.kt
similarity index 68%
rename from app/src/main/java/im/vector/riotredesign/core/utils/Event.kt
rename to app/src/main/java/im/vector/riotredesign/core/utils/LiveEvent.kt
index d67ada6629..153e3c3f2d 100644
--- a/app/src/main/java/im/vector/riotredesign/core/utils/Event.kt
+++ b/app/src/main/java/im/vector/riotredesign/core/utils/LiveEvent.kt
@@ -2,7 +2,7 @@ package im.vector.riotredesign.core.utils
 
 import android.arch.lifecycle.Observer
 
-open class Event<out T>(private val content: T) {
+open class LiveEvent<out T>(private val content: T) {
 
     var hasBeenHandled = false
         private set // Allow external read but not write
@@ -26,13 +26,13 @@ open class Event<out T>(private val content: T) {
 }
 
 /**
- * An [Observer] for [Event]s, simplifying the pattern of checking if the [Event]'s content has
+ * An [Observer] for [LiveEvent]s, simplifying the pattern of checking if the [LiveEvent]'s content has
  * already been handled.
  *
- * [onEventUnhandledContent] is *only* called if the [Event]'s contents has not been handled.
+ * [onEventUnhandledContent] is *only* called if the [LiveEvent]'s contents has not been handled.
  */
-class EventObserver<T>(private val onEventUnhandledContent: (T) -> Unit) : Observer<Event<T>> {
-    override fun onChanged(event: Event<T>?) {
+class EventObserver<T>(private val onEventUnhandledContent: (T) -> Unit) : Observer<LiveEvent<T>> {
+    override fun onChanged(event: LiveEvent<T>?) {
         event?.getContentIfNotHandled()?.let { value ->
             onEventUnhandledContent(value)
         }
diff --git a/app/src/main/java/im/vector/riotredesign/features/home/HomeActivityViewModel.kt b/app/src/main/java/im/vector/riotredesign/features/home/HomeActivityViewModel.kt
index 108469da35..06509e8a2c 100644
--- a/app/src/main/java/im/vector/riotredesign/features/home/HomeActivityViewModel.kt
+++ b/app/src/main/java/im/vector/riotredesign/features/home/HomeActivityViewModel.kt
@@ -9,7 +9,7 @@ import im.vector.matrix.android.api.Matrix
 import im.vector.matrix.android.api.session.Session
 import im.vector.matrix.rx.rx
 import im.vector.riotredesign.core.platform.RiotViewModel
-import im.vector.riotredesign.core.utils.Event
+import im.vector.riotredesign.core.utils.LiveEvent
 import im.vector.riotredesign.features.home.room.list.RoomSelectionRepository
 import io.reactivex.rxkotlin.subscribeBy
 import org.koin.android.ext.android.get
@@ -31,8 +31,8 @@ class HomeActivityViewModel(state: EmptyState,
         }
     }
 
-    private val _openRoomLiveData = MutableLiveData<Event<String>>()
-    val openRoomLiveData: LiveData<Event<String>>
+    private val _openRoomLiveData = MutableLiveData<LiveEvent<String>>()
+    val openRoomLiveData: LiveData<LiveEvent<String>>
         get() = _openRoomLiveData
 
     init {
@@ -40,7 +40,7 @@ class HomeActivityViewModel(state: EmptyState,
         if (lastSelectedRoom == null) {
             getTheFirstRoomWhenAvailable()
         } else {
-            _openRoomLiveData.postValue(Event(lastSelectedRoom))
+            _openRoomLiveData.postValue(LiveEvent(lastSelectedRoom))
         }
     }
 
@@ -51,7 +51,7 @@ class HomeActivityViewModel(state: EmptyState,
                 .subscribeBy {
                     val firstRoom = it.firstOrNull()
                     if (firstRoom != null) {
-                        _openRoomLiveData.postValue(Event(firstRoom.roomId))
+                        _openRoomLiveData.postValue(LiveEvent(firstRoom.roomId))
                     }
                 }
                 .disposeOnClear()
diff --git a/app/src/main/java/im/vector/riotredesign/features/home/HomeNavigator.kt b/app/src/main/java/im/vector/riotredesign/features/home/HomeNavigator.kt
index 41f61688d5..29cb66bc52 100644
--- a/app/src/main/java/im/vector/riotredesign/features/home/HomeNavigator.kt
+++ b/app/src/main/java/im/vector/riotredesign/features/home/HomeNavigator.kt
@@ -23,7 +23,6 @@ class HomeNavigator {
         if (!addToBackstack && isRoomOpened(roomId)) {
             return
         }
-        currentRoomId = roomId
         activity?.let {
             val args = RoomDetailArgs(roomId, eventId)
             val roomDetailFragment = RoomDetailFragment.newInstance(args)
@@ -31,6 +30,7 @@ class HomeNavigator {
             if (addToBackstack) {
                 it.addFragmentToBackstack(roomDetailFragment, R.id.homeDetailFragmentContainer, roomId)
             } else {
+                currentRoomId = roomId
                 clearBackStack(it.supportFragmentManager)
                 it.replaceFragment(roomDetailFragment, R.id.homeDetailFragmentContainer)
             }
diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt
index 560e8824d1..d3f47e3d07 100644
--- a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt
+++ b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt
@@ -73,7 +73,7 @@ class RoomDetailFragment : RiotFragment(), TimelineEventController.Callback {
         scrollOnNewMessageCallback = ScrollOnNewMessageCallback(layoutManager)
         recyclerView.layoutManager = layoutManager
         recyclerView.setHasFixedSize(true)
-        //timelineEventController.addModelBuildListener { it.dispatchTo(scrollOnNewMessageCallback) }
+        timelineEventController.addModelBuildListener { it.dispatchTo(scrollOnNewMessageCallback) }
         recyclerView.setController(timelineEventController)
         timelineEventController.callback = this
     }
@@ -95,8 +95,15 @@ class RoomDetailFragment : RiotFragment(), TimelineEventController.Callback {
 
     private fun renderTimeline(state: RoomDetailViewState) {
         when (state.asyncTimelineData) {
-            is Success -> timelineEventController.update(state.asyncTimelineData())
+            is Success -> {
+                val timelineData = state.asyncTimelineData()
+                val lockAutoScroll = timelineData?.let {
+                    it.events == timelineEventController.currentList && it.isLoadingForward
+                } ?: true
 
+                scrollOnNewMessageCallback.isLocked.set(lockAutoScroll)
+                timelineEventController.update(timelineData)
+            }
         }
     }
 
diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/ScrollOnNewMessageCallback.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/ScrollOnNewMessageCallback.kt
index aec98efe40..1ffbb50198 100644
--- a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/ScrollOnNewMessageCallback.kt
+++ b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/ScrollOnNewMessageCallback.kt
@@ -6,10 +6,10 @@ import java.util.concurrent.atomic.AtomicBoolean
 
 class ScrollOnNewMessageCallback(private val layoutManager: LinearLayoutManager) : DefaultListUpdateCallback {
 
-    val hasBeenUpdated = AtomicBoolean(false)
+    var isLocked = AtomicBoolean(true)
 
     override fun onInserted(position: Int, count: Int) {
-        if (hasBeenUpdated.compareAndSet(true, false) && position == 0 && layoutManager.findFirstVisibleItemPosition() == 0) {
+        if (isLocked.compareAndSet(false, true) && position == 0 && layoutManager.findFirstVisibleItemPosition() == 0) {
             layoutManager.scrollToPosition(0)
         }
     }
diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/MessageItemFactory.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/MessageItemFactory.kt
index 5e5d1b1ecd..2122e5457f 100644
--- a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/MessageItemFactory.kt
+++ b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/MessageItemFactory.kt
@@ -4,7 +4,7 @@ import android.text.SpannableStringBuilder
 import android.text.util.Linkify
 import im.vector.matrix.android.api.permalinks.MatrixLinkify
 import im.vector.matrix.android.api.permalinks.MatrixPermalinkSpan
-import im.vector.matrix.android.api.session.events.model.EnrichedEvent
+import im.vector.matrix.android.api.session.events.model.TimelineEvent
 import im.vector.matrix.android.api.session.events.model.toModel
 import im.vector.matrix.android.api.session.room.model.MessageContent
 import org.threeten.bp.LocalDateTime
@@ -13,8 +13,8 @@ class MessageItemFactory(private val timelineDateFormatter: TimelineDateFormatte
 
     private val messagesDisplayedWithInformation = HashSet<String?>()
 
-    fun create(event: EnrichedEvent,
-               nextEvent: EnrichedEvent?,
+    fun create(event: TimelineEvent,
+               nextEvent: TimelineEvent?,
                addDaySeparator: Boolean,
                date: LocalDateTime,
                callback: TimelineEventController.Callback?
diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TextItemFactory.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TextItemFactory.kt
index e123d7f8bc..1ca81862d3 100644
--- a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TextItemFactory.kt
+++ b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TextItemFactory.kt
@@ -1,10 +1,10 @@
 package im.vector.riotredesign.features.home.room.detail.timeline
 
-import im.vector.matrix.android.api.session.events.model.EnrichedEvent
+import im.vector.matrix.android.api.session.events.model.TimelineEvent
 
 class TextItemFactory {
 
-    fun create(event: EnrichedEvent): TextItem? {
+    fun create(event: TimelineEvent): TextItem? {
         val text = "${event.root.type} events are not yet handled"
         return TextItem(text = text)
     }
diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventController.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventController.kt
index 8f5d70cb59..0c32025cfb 100644
--- a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventController.kt
+++ b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventController.kt
@@ -2,7 +2,7 @@ package im.vector.riotredesign.features.home.room.detail.timeline
 
 import com.airbnb.epoxy.EpoxyAsyncUtil
 import com.airbnb.epoxy.EpoxyModel
-import im.vector.matrix.android.api.session.events.model.EnrichedEvent
+import im.vector.matrix.android.api.session.events.model.TimelineEvent
 import im.vector.matrix.android.api.session.events.model.EventType
 import im.vector.matrix.android.api.session.room.timeline.TimelineData
 import im.vector.riotredesign.core.extensions.localDateTime
@@ -13,7 +13,7 @@ class TimelineEventController(private val roomId: String,
                               private val messageItemFactory: MessageItemFactory,
                               private val textItemFactory: TextItemFactory,
                               private val dateFormatter: TimelineDateFormatter
-) : PagedListEpoxyController<EnrichedEvent>(
+) : PagedListEpoxyController<TimelineEvent>(
         EpoxyAsyncUtil.getAsyncBackgroundHandler(),
         EpoxyAsyncUtil.getAsyncBackgroundHandler()
 ) {
@@ -38,7 +38,7 @@ class TimelineEventController(private val roomId: String,
     }
 
 
-    override fun buildItemModels(currentPosition: Int, items: List<EnrichedEvent?>): List<EpoxyModel<*>> {
+    override fun buildItemModels(currentPosition: Int, items: List<TimelineEvent?>): List<EpoxyModel<*>> {
         if (items.isNullOrEmpty()) {
             return emptyList()
         }
diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/paging/PagedListEpoxyController.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/paging/PagedListEpoxyController.kt
index a01c2904de..b0bdd5a903 100644
--- a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/paging/PagedListEpoxyController.kt
+++ b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/paging/PagedListEpoxyController.kt
@@ -70,6 +70,9 @@ abstract class PagedListEpoxyController<T>(
             modelBuildingHandler = modelBuildingHandler
     )
 
+    var currentList: PagedList<T>? = null
+        private set
+
     final override fun buildModels() {
         addModels(modelCache.getModels())
     }
@@ -107,6 +110,7 @@ abstract class PagedListEpoxyController<T>(
      * to [buildItemModel] with items from the previous list.
      */
     fun submitList(newList: PagedList<T>?) {
+        currentList = newList
         modelCache.submitList(newList)
     }
 
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/TimelineHolderTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/TimelineHolderTest.kt
index 38b465d8d8..11555dd281 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/TimelineHolderTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/TimelineHolderTest.kt
@@ -7,7 +7,7 @@ import im.vector.matrix.android.InstrumentedTest
 import im.vector.matrix.android.LiveDataTestObserver
 import im.vector.matrix.android.api.thread.MainThreadExecutor
 import im.vector.matrix.android.internal.session.room.members.RoomMemberExtractor
-import im.vector.matrix.android.internal.session.room.timeline.DefaultTimelineHolder
+import im.vector.matrix.android.internal.session.room.timeline.DefaultTimelineService
 import im.vector.matrix.android.internal.session.room.timeline.TimelineBoundaryCallback
 import im.vector.matrix.android.internal.session.room.timeline.TokenChunkEventPersistor
 import im.vector.matrix.android.internal.task.TaskExecutor
@@ -44,17 +44,17 @@ internal class TimelineHolderTest : InstrumentedTest {
         val boundaryCallback = TimelineBoundaryCallback(roomId, taskExecutor, paginationTask, monarchy, PagingRequestHelper(MainThreadExecutor()))
 
         RoomDataHelper.fakeInitialSync(monarchy, roomId)
-        val timelineHolder = DefaultTimelineHolder(roomId, monarchy, taskExecutor, boundaryCallback, getContextOfEventTask, RoomMemberExtractor(monarchy, roomId))
+        val timelineHolder = DefaultTimelineService(roomId, monarchy, taskExecutor, boundaryCallback, getContextOfEventTask, RoomMemberExtractor(monarchy, roomId))
         val timelineObserver = LiveDataTestObserver.test(timelineHolder.timeline())
         timelineObserver.awaitNextValue().assertHasValue()
-        var pagedList = timelineObserver.value()
-        pagedList.size shouldEqual 30
-        (0 until pagedList.size).map {
-            pagedList.loadAround(it)
+        var timelineData = timelineObserver.value()
+        timelineData.events.size shouldEqual 30
+        (0 until timelineData.events.size).map {
+            timelineData.events.loadAround(it)
         }
         timelineObserver.awaitNextValue().assertHasValue()
-        pagedList = timelineObserver.value()
-        pagedList.size shouldEqual 60
+        timelineData = timelineObserver.value()
+        timelineData.events.size shouldEqual 60
     }
 
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt
index cd4af40182..d5652ef15b 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt
@@ -15,4 +15,12 @@ interface Session : RoomService, GroupService {
     @MainThread
     fun close()
 
+    fun addListener(listener: Listener)
+
+    fun removeListener(listener: Listener)
+
+    // Not used at the moment
+    interface Listener
+
+
 }
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/interceptor/EnrichedEventInterceptor.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/interceptor/EnrichedEventInterceptor.kt
deleted file mode 100644
index c781f29b68..0000000000
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/interceptor/EnrichedEventInterceptor.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package im.vector.matrix.android.api.session.events.interceptor
-
-import im.vector.matrix.android.api.session.events.model.EnrichedEvent
-
-interface EnrichedEventInterceptor {
-
-    fun canEnrich(event: EnrichedEvent): Boolean
-
-    fun enrich(event: EnrichedEvent)
-
-}
-
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/interceptor/TimelineEventInterceptor.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/interceptor/TimelineEventInterceptor.kt
new file mode 100644
index 0000000000..cf7df317de
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/interceptor/TimelineEventInterceptor.kt
@@ -0,0 +1,12 @@
+package im.vector.matrix.android.api.session.events.interceptor
+
+import im.vector.matrix.android.api.session.events.model.TimelineEvent
+
+interface TimelineEventInterceptor {
+
+    fun canEnrich(event: TimelineEvent): Boolean
+
+    fun enrich(event: TimelineEvent)
+
+}
+
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EnrichedEvent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/TimelineEvent.kt
similarity index 95%
rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EnrichedEvent.kt
rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/TimelineEvent.kt
index 5cf64db9c2..97a5eced2c 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EnrichedEvent.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/TimelineEvent.kt
@@ -2,7 +2,7 @@ package im.vector.matrix.android.api.session.events.model
 
 import im.vector.matrix.android.api.session.room.model.RoomMember
 
-data class EnrichedEvent(
+data class TimelineEvent(
         val root: Event,
         val localId: String,
         val roomMember: RoomMember?
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineData.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineData.kt
index 556c95f980..01727cd287 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineData.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineData.kt
@@ -1,10 +1,10 @@
 package im.vector.matrix.android.api.session.room.timeline
 
 import android.arch.paging.PagedList
-import im.vector.matrix.android.api.session.events.model.EnrichedEvent
+import im.vector.matrix.android.api.session.events.model.TimelineEvent
 
 data class TimelineData(
-        val events: PagedList<EnrichedEvent>,
+        val events: PagedList<TimelineEvent>,
         val isLoadingForward: Boolean = false,
         val isLoadingBackward: Boolean = false
 )
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/RealmLiveEntityObserver.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/RealmLiveEntityObserver.kt
index bc81a709ba..5f01f433d3 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/RealmLiveEntityObserver.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/RealmLiveEntityObserver.kt
@@ -4,7 +4,6 @@ import android.arch.lifecycle.LiveData
 import android.arch.lifecycle.Observer
 import com.zhuinden.monarchy.Monarchy
 import io.realm.RealmObject
-import io.realm.RealmResults
 import java.util.concurrent.atomic.AtomicBoolean
 
 internal interface LiveEntityObserver {
@@ -39,11 +38,15 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val m
         if (changeSet == null) {
             return
         }
-        val updateIndexes = changeSet.orderedCollectionChangeSet.changes + changeSet.orderedCollectionChangeSet.insertions
+        val insertionIndexes = changeSet.orderedCollectionChangeSet.insertions
+        val updateIndexes = changeSet.orderedCollectionChangeSet.changes
         val deletionIndexes = changeSet.orderedCollectionChangeSet.deletions
-        process(changeSet.realmResults, updateIndexes, deletionIndexes)
+        val inserted = changeSet.realmResults.filterIndexed { index, _ -> insertionIndexes.contains(index) }
+        val updated = changeSet.realmResults.filterIndexed { index, _ -> updateIndexes.contains(index) }
+        val deleted = changeSet.realmResults.filterIndexed { index, _ -> deletionIndexes.contains(index) }
+        process(inserted, updated, deleted)
     }
 
-    abstract fun process(results: RealmResults<T>, updateIndexes: IntArray, deletionIndexes: IntArray)
+    abstract fun process(inserted: List<T>, updated: List<T>, deleted: List<T>)
 
 }
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/EventEntityQueries.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/EventEntityQueries.kt
index 2d846d8b02..2a723512f0 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/EventEntityQueries.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/EventEntityQueries.kt
@@ -26,12 +26,13 @@ internal fun EventEntity.Companion.where(realm: Realm,
         query.equalTo(EventEntityFields.TYPE, type)
     }
     return when (linkFilterMode) {
-        LINKED_ONLY -> query.equalTo(EventEntityFields.IS_UNLINKED, false)
+        LINKED_ONLY   -> query.equalTo(EventEntityFields.IS_UNLINKED, false)
         UNLINKED_ONLY -> query.equalTo(EventEntityFields.IS_UNLINKED, true)
-        BOTH -> query
+        BOTH          -> query
     }
 }
 
+
 internal fun RealmQuery<EventEntity>.next(from: Int? = null, strict: Boolean = true): EventEntity? {
     if (from != null) {
         if (strict) {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt
index 2841f089b9..0c9356ed8c 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt
@@ -31,6 +31,7 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
     private lateinit var scope: Scope
 
     private val liveEntityUpdaters by inject<List<LiveEntityObserver>>()
+    private val sessionListeners by inject<SessionListeners>()
     private val roomService by inject<RoomService>()
     private val groupService by inject<GroupService>()
     private val syncThread by inject<SyncThread>()
@@ -62,6 +63,14 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
         isOpen = false
     }
 
+    override fun addListener(listener: Session.Listener) {
+        sessionListeners.addListener(listener)
+    }
+
+    override fun removeListener(listener: Session.Listener) {
+        sessionListeners.removeListener(listener)
+    }
+
     // ROOM SERVICE
 
     override fun getRoom(roomId: String): Room? {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionListeners.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionListeners.kt
new file mode 100644
index 0000000000..92c87ee46a
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionListeners.kt
@@ -0,0 +1,17 @@
+package im.vector.matrix.android.internal.session
+
+import im.vector.matrix.android.api.session.Session
+
+internal class SessionListeners {
+
+    private val listeners = ArrayList<Session.Listener>()
+
+    fun addListener(listener: Session.Listener) {
+        listeners.add(listener)
+    }
+
+    fun removeListener(listener: Session.Listener) {
+        listeners.remove(listener)
+    }
+
+}
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt
index 41644ad8cc..d36cbcbf0a 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt
@@ -6,7 +6,6 @@ import im.vector.matrix.android.api.auth.data.SessionParams
 import im.vector.matrix.android.api.session.group.GroupService
 import im.vector.matrix.android.api.session.room.RoomService
 import im.vector.matrix.android.internal.database.LiveEntityObserver
-import im.vector.matrix.android.internal.session.room.prune.EventsPruner
 import im.vector.matrix.android.internal.session.group.DefaultGroupService
 import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater
 import im.vector.matrix.android.internal.session.room.DefaultRoomService
@@ -14,6 +13,7 @@ import im.vector.matrix.android.internal.session.room.RoomAvatarResolver
 import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater
 import im.vector.matrix.android.internal.session.room.members.RoomDisplayNameResolver
 import im.vector.matrix.android.internal.session.room.members.RoomMemberDisplayNameResolver
+import im.vector.matrix.android.internal.session.room.prune.EventsPruner
 import im.vector.matrix.android.internal.util.md5
 import io.realm.RealmConfiguration
 import org.koin.dsl.module.module
@@ -75,7 +75,10 @@ internal class SessionModule(private val sessionParams: SessionParams) {
         }
 
         scope(DefaultSession.SCOPE) {
+            SessionListeners()
+        }
 
+        scope(DefaultSession.SCOPE) {
             val roomSummaryUpdater = RoomSummaryUpdater(get(), get(), get(), get(), sessionParams.credentials)
             val groupSummaryUpdater = GroupSummaryUpdater(get())
             val eventsPruner = EventsPruner(get())
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GetGroupDataWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GetGroupDataWorker.kt
index fc5c0d1e53..861e964033 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GetGroupDataWorker.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GetGroupDataWorker.kt
@@ -15,9 +15,7 @@ internal class GetGroupDataWorker(context: Context,
 
     @JsonClass(generateAdapter = true)
     internal data class Params(
-            val groupIds: List<String>,
-            val updateIndexes: List<Int>,
-            val deletionIndexes: List<Int>
+            val groupIds: List<String>
     )
 
     private val getGroupDataTask by inject<GetGroupDataTask>()
@@ -26,8 +24,7 @@ internal class GetGroupDataWorker(context: Context,
         val params = WorkerParamsFactory.fromData<Params>(inputData)
                      ?: return Result.failure()
 
-        val results = params.updateIndexes.map { index ->
-            val groupId = params.groupIds[index]
+        val results = params.groupIds.map { groupId ->
             fetchGroupData(groupId)
         }
         val isSuccessful = results.none { it.isFailure() }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GroupSummaryUpdater.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GroupSummaryUpdater.kt
index be70a16038..7d5d4f3d56 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GroupSummaryUpdater.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GroupSummaryUpdater.kt
@@ -1,12 +1,15 @@
 package im.vector.matrix.android.internal.session.group
 
-import androidx.work.*
+import androidx.work.Constraints
+import androidx.work.ExistingWorkPolicy
+import androidx.work.NetworkType
+import androidx.work.OneTimeWorkRequestBuilder
+import androidx.work.WorkManager
 import com.zhuinden.monarchy.Monarchy
 import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
 import im.vector.matrix.android.internal.database.model.GroupEntity
 import im.vector.matrix.android.internal.database.query.where
 import im.vector.matrix.android.internal.util.WorkerParamsFactory
-import io.realm.RealmResults
 
 private const val GET_GROUP_DATA_WORKER = "GET_GROUP_DATA_WORKER"
 
@@ -19,9 +22,9 @@ internal class GroupSummaryUpdater(monarchy: Monarchy
             .setRequiredNetworkType(NetworkType.CONNECTED)
             .build()
 
-    override fun process(results: RealmResults<GroupEntity>, updateIndexes: IntArray, deletionIndexes: IntArray) {
-        val groupIds = results.map { it.groupId }
-        val getGroupDataWorkerParams = GetGroupDataWorker.Params(groupIds, updateIndexes.toList(), deletionIndexes.toList())
+    override fun process(inserted: List<GroupEntity>, updated: List<GroupEntity>, deleted: List<GroupEntity>) {
+        val newGroupIds = inserted.map { it.groupId }
+        val getGroupDataWorkerParams = GetGroupDataWorker.Params(newGroupIds)
         val workData = WorkerParamsFactory.toData(getGroupDataWorkerParams)
 
         val sendWork = OneTimeWorkRequestBuilder<GetGroupDataWorker>()
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt
index 4cf645a50d..2359c30190 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt
@@ -2,24 +2,23 @@ package im.vector.matrix.android.internal.session.room
 
 import android.arch.lifecycle.LiveData
 import android.arch.lifecycle.Transformations
-import android.arch.paging.PagedList
 import com.zhuinden.monarchy.Monarchy
 import im.vector.matrix.android.api.MatrixCallback
-import im.vector.matrix.android.api.session.events.model.EnrichedEvent
 import im.vector.matrix.android.api.session.events.model.Event
 import im.vector.matrix.android.api.session.room.Room
 import im.vector.matrix.android.api.session.room.SendService
-import im.vector.matrix.android.api.session.room.timeline.TimelineService
 import im.vector.matrix.android.api.session.room.model.Membership
 import im.vector.matrix.android.api.session.room.model.MyMembership
 import im.vector.matrix.android.api.session.room.model.RoomSummary
 import im.vector.matrix.android.api.session.room.timeline.TimelineData
+import im.vector.matrix.android.api.session.room.timeline.TimelineService
 import im.vector.matrix.android.api.util.Cancelable
 import im.vector.matrix.android.internal.database.mapper.asDomain
 import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
 import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields
 import im.vector.matrix.android.internal.database.query.where
 import im.vector.matrix.android.internal.di.MatrixKoinComponent
+import im.vector.matrix.android.internal.session.SessionListeners
 import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersTask
 import im.vector.matrix.android.internal.task.TaskExecutor
 import im.vector.matrix.android.internal.task.configureWith
@@ -62,4 +61,5 @@ internal data class DefaultRoom(
         return sendService.sendTextMessage(text, callback)
     }
 
+
 }
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt
index 37fe93c198..c0e9863c74 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt
@@ -17,7 +17,6 @@ import im.vector.matrix.android.internal.database.query.where
 import im.vector.matrix.android.internal.session.room.members.RoomDisplayNameResolver
 import im.vector.matrix.android.internal.session.room.members.RoomMembers
 import io.realm.Realm
-import io.realm.RealmResults
 import io.realm.kotlin.createObject
 
 internal class RoomSummaryUpdater(monarchy: Monarchy,
@@ -29,13 +28,10 @@ internal class RoomSummaryUpdater(monarchy: Monarchy,
 
     override val query = Monarchy.Query<RoomEntity> { RoomEntity.where(it) }
 
-    override fun process(results: RealmResults<RoomEntity>, updateIndexes: IntArray, deletionIndexes: IntArray) {
-        val rooms = results.map { it.asDomain() }
+    override fun process(inserted: List<RoomEntity>, updated: List<RoomEntity>, deleted: List<RoomEntity>) {
+        val rooms = (inserted + updated).map { it.asDomain() }
         monarchy.writeAsync { realm ->
-            updateIndexes.forEach { index ->
-                val data = rooms[index]
-                updateRoom(realm, data)
-            }
+            rooms.forEach { updateRoom(realm, it) }
         }
     }
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/prune/EventsPruner.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/prune/EventsPruner.kt
index a80b7ccc9d..ea5d8d643c 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/prune/EventsPruner.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/prune/EventsPruner.kt
@@ -10,7 +10,6 @@ import im.vector.matrix.android.internal.database.mapper.asDomain
 import im.vector.matrix.android.internal.database.model.EventEntity
 import im.vector.matrix.android.internal.database.query.where
 import im.vector.matrix.android.internal.util.WorkerParamsFactory
-import io.realm.RealmResults
 
 private const val PRUNE_EVENT_WORKER = "PRUNE_EVENT_WORKER"
 
@@ -19,9 +18,9 @@ internal class EventsPruner(monarchy: Monarchy) :
 
     override val query = Monarchy.Query<EventEntity> { EventEntity.where(it, type = EventType.REDACTION) }
 
-    override fun process(results: RealmResults<EventEntity>, updateIndexes: IntArray, deletionIndexes: IntArray) {
-        val redactionEvents = results.map { it.asDomain() }
-        val pruneEventWorkerParams = PruneEventWorker.Params(redactionEvents, updateIndexes.toList(), deletionIndexes.toList())
+    override fun process(inserted: List<EventEntity>, updated: List<EventEntity>, deleted: List<EventEntity>) {
+        val redactionEvents = inserted.map { it.asDomain() }
+        val pruneEventWorkerParams = PruneEventWorker.Params(redactionEvents)
         val workData = WorkerParamsFactory.toData(pruneEventWorkerParams)
 
         val sendWork = OneTimeWorkRequestBuilder<PruneEventWorker>()
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/prune/PruneEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/prune/PruneEventWorker.kt
index 6562fd14fe..90e5cdc4ff 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/prune/PruneEventWorker.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/prune/PruneEventWorker.kt
@@ -13,6 +13,7 @@ import im.vector.matrix.android.internal.database.query.where
 import im.vector.matrix.android.internal.di.MatrixKoinComponent
 import im.vector.matrix.android.internal.util.WorkerParamsFactory
 import im.vector.matrix.android.internal.util.tryTransactionAsync
+import im.vector.matrix.android.internal.util.tryTransactionSync
 import io.realm.Realm
 import org.koin.standalone.inject
 
@@ -22,9 +23,7 @@ internal class PruneEventWorker(context: Context,
 
     @JsonClass(generateAdapter = true)
     internal data class Params(
-            val redactionEvents: List<Event>,
-            val updateIndexes: List<Int>,
-            val deletionIndexes: List<Int>
+            val redactionEvents: List<Event>
     )
 
     private val monarchy by inject<Monarchy>()
@@ -33,10 +32,9 @@ internal class PruneEventWorker(context: Context,
         val params = WorkerParamsFactory.fromData<Params>(inputData)
                      ?: return Result.failure()
 
-        val result = monarchy.tryTransactionAsync { realm ->
-            params.updateIndexes.forEach { index ->
-                val data = params.redactionEvents[index]
-                pruneEvent(realm, data)
+        val result = monarchy.tryTransactionSync { realm ->
+            params.redactionEvents.forEach { event ->
+                pruneEvent(realm, event)
             }
         }
         return result.fold({ Result.retry() }, { Result.success() })
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimelineService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimelineService.kt
index 6f5a80ad6b..2a06dbb497 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimelineService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimelineService.kt
@@ -4,8 +4,8 @@ import android.arch.lifecycle.LiveData
 import android.arch.paging.LivePagedListBuilder
 import android.arch.paging.PagedList
 import com.zhuinden.monarchy.Monarchy
-import im.vector.matrix.android.api.session.events.interceptor.EnrichedEventInterceptor
-import im.vector.matrix.android.api.session.events.model.EnrichedEvent
+import im.vector.matrix.android.api.session.events.interceptor.TimelineEventInterceptor
+import im.vector.matrix.android.api.session.events.model.TimelineEvent
 import im.vector.matrix.android.api.session.room.timeline.TimelineData
 import im.vector.matrix.android.api.session.room.timeline.TimelineService
 import im.vector.matrix.android.internal.database.mapper.asDomain
@@ -34,35 +34,21 @@ internal class DefaultTimelineService(private val roomId: String,
                                       private val roomMemberExtractor: RoomMemberExtractor
 ) : TimelineService {
 
-    private val eventInterceptors = ArrayList<EnrichedEventInterceptor>()
+    private val eventInterceptors = ArrayList<TimelineEventInterceptor>()
 
     override fun timeline(eventId: String?): LiveData<TimelineData> {
         clearUnlinkedEvents()
-        var initialLoadKey = 0
-        if (eventId != null) {
-            val indexOfEvent = indexOfEvent(eventId)
-            if (indexOfEvent == EVENT_NOT_FOUND_INDEX) {
-                val params = GetContextOfEventTask.Params(roomId, eventId)
-                contextOfEventTask.configureWith(params).executeBy(taskExecutor)
-            } else {
-                initialLoadKey = indexOfEvent
-            }
-        }
+        val initialLoadKey = getInitialLoadKey(eventId)
         val realmDataSourceFactory = monarchy.createDataSourceFactory {
             buildDataSourceFactoryQuery(it, eventId)
         }
         val domainSourceFactory = realmDataSourceFactory
                 .map { eventEntity ->
                     val roomMember = roomMemberExtractor.extractFrom(eventEntity)
-                    EnrichedEvent(eventEntity.asDomain(), eventEntity.localId, roomMember)
+                    TimelineEvent(eventEntity.asDomain(), eventEntity.localId, roomMember)
                 }
 
-        val pagedListConfig = PagedList.Config.Builder()
-                .setEnablePlaceholders(false)
-                .setPageSize(PAGE_SIZE)
-                .setInitialLoadSizeHint(2 * PAGE_SIZE)
-                .setPrefetchDistance(PREFETCH_DISTANCE)
-                .build()
+        val pagedListConfig = buildPagedListConfig()
 
         val livePagedListBuilder = LivePagedListBuilder(domainSourceFactory, pagedListConfig)
                 .setBoundaryCallback(boundaryCallback)
@@ -77,6 +63,35 @@ internal class DefaultTimelineService(private val roomId: String,
         }
     }
 
+    // PRIVATE FUNCTIONS ***************************************************************************
+
+    private fun getInitialLoadKey(eventId: String?): Int {
+        var initialLoadKey = 0
+        if (eventId != null) {
+            val indexOfEvent = indexOfEvent(eventId)
+            if (indexOfEvent == EVENT_NOT_FOUND_INDEX) {
+                fetchEvent(eventId)
+            } else {
+                initialLoadKey = indexOfEvent
+            }
+        }
+        return initialLoadKey
+    }
+
+
+    private fun fetchEvent(eventId: String) {
+        val params = GetContextOfEventTask.Params(roomId, eventId)
+        contextOfEventTask.configureWith(params).executeBy(taskExecutor)
+    }
+
+    private fun buildPagedListConfig(): PagedList.Config {
+        return PagedList.Config.Builder()
+                .setEnablePlaceholders(false)
+                .setPageSize(PAGE_SIZE)
+                .setInitialLoadSizeHint(2 * PAGE_SIZE)
+                .setPrefetchDistance(PREFETCH_DISTANCE)
+                .build()
+    }
 
     private fun clearUnlinkedEvents() {
         monarchy.tryTransactionAsync { realm ->
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineBoundaryCallback.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineBoundaryCallback.kt
index 2ce550f337..88282e85e0 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineBoundaryCallback.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineBoundaryCallback.kt
@@ -4,7 +4,7 @@ import android.arch.lifecycle.LiveData
 import android.arch.paging.PagedList
 import com.zhuinden.monarchy.Monarchy
 import im.vector.matrix.android.api.MatrixCallback
-import im.vector.matrix.android.api.session.events.model.EnrichedEvent
+import im.vector.matrix.android.api.session.events.model.TimelineEvent
 import im.vector.matrix.android.internal.database.model.ChunkEntity
 import im.vector.matrix.android.internal.database.query.findIncludingEvent
 import im.vector.matrix.android.internal.task.TaskExecutor
@@ -16,7 +16,7 @@ internal class TimelineBoundaryCallback(private val roomId: String,
                                         private val paginationTask: PaginationTask,
                                         private val monarchy: Monarchy,
                                         private val helper: PagingRequestHelper
-) : PagedList.BoundaryCallback<EnrichedEvent>() {
+) : PagedList.BoundaryCallback<TimelineEvent>() {
 
     var limit = 30
 
@@ -41,7 +41,7 @@ internal class TimelineBoundaryCallback(private val roomId: String,
         // actually, it's not possible
     }
 
-    override fun onItemAtEndLoaded(itemAtEnd: EnrichedEvent) {
+    override fun onItemAtEndLoaded(itemAtEnd: TimelineEvent) {
         val token = itemAtEnd.root.eventId?.let { getToken(it, PaginationDirection.BACKWARDS) }
                 ?: return
 
@@ -50,7 +50,7 @@ internal class TimelineBoundaryCallback(private val roomId: String,
         }
     }
 
-    override fun onItemAtFrontLoaded(itemAtFront: EnrichedEvent) {
+    override fun onItemAtFrontLoaded(itemAtFront: TimelineEvent) {
         val token = itemAtFront.root.eventId?.let { getToken(it, PaginationDirection.FORWARDS) }
                 ?: return