diff --git a/Corona-Warn-App/build.gradle b/Corona-Warn-App/build.gradle
index 89dce2971ae418754d9a64535590705274ecc2ff..25be009f467df291bb66c886d5c653ec3b92bff2 100644
--- a/Corona-Warn-App/build.gradle
+++ b/Corona-Warn-App/build.gradle
@@ -173,7 +173,8 @@ android {
                     "-Xno-kotlin-nothing-value-exception",
                     "-Xuse-experimental=kotlinx.coroutines.ExperimentalCoroutinesApi",
                     "-Xuse-experimental=kotlinx.coroutines.FlowPreview",
-                    "-Xuse-experimental=kotlin.time.ExperimentalTime"
+                    "-Xuse-experimental=kotlin.time.ExperimentalTime",
+                    "-Xopt-in=kotlin.RequiresOptIn"
             ]
         }
     }
diff --git a/Corona-Warn-App/schemas/de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase/1.json b/Corona-Warn-App/schemas/de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase/1.json
index befd229435a5e47f296ec11550b0b1534c07e0cb..856916f58dfa37e09331ebb2dbe0f6297e126d3e 100644
--- a/Corona-Warn-App/schemas/de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase/1.json
+++ b/Corona-Warn-App/schemas/de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase/1.json
@@ -2,11 +2,11 @@
   "formatVersion": 1,
   "database": {
     "version": 1,
-    "identityHash": "5117ed4caaa7ecd70051902d844cc665",
+    "identityHash": "e23913768d43dc0cb1374df83b2fa78a",
     "entities": [
       {
         "tableName": "checkin",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `traceLocationIdBase64` TEXT NOT NULL, `version` INTEGER NOT NULL, `type` INTEGER NOT NULL, `description` TEXT NOT NULL, `address` TEXT NOT NULL, `traceLocationStart` TEXT, `traceLocationEnd` TEXT, `defaultCheckInLengthInMinutes` INTEGER, `cryptographicSeedBase64` TEXT NOT NULL, `cnPublicKey` TEXT NOT NULL, `checkInStart` TEXT NOT NULL, `checkInEnd` TEXT NOT NULL, `completed` INTEGER NOT NULL, `createJournalEntry` INTEGER NOT NULL)",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `traceLocationIdBase64` TEXT NOT NULL, `version` INTEGER NOT NULL, `type` INTEGER NOT NULL, `description` TEXT NOT NULL, `address` TEXT NOT NULL, `traceLocationStart` TEXT, `traceLocationEnd` TEXT, `defaultCheckInLengthInMinutes` INTEGER, `cryptographicSeedBase64` TEXT NOT NULL, `cnPublicKey` TEXT NOT NULL, `checkInStart` TEXT NOT NULL, `checkInEnd` TEXT NOT NULL, `completed` INTEGER NOT NULL, `createJournalEntry` INTEGER NOT NULL, `submitted` INTEGER NOT NULL)",
         "fields": [
           {
             "fieldPath": "id",
@@ -97,6 +97,12 @@
             "columnName": "createJournalEntry",
             "affinity": "INTEGER",
             "notNull": true
+          },
+          {
+            "fieldPath": "isSubmitted",
+            "columnName": "submitted",
+            "affinity": "INTEGER",
+            "notNull": true
           }
         ],
         "primaryKey": {
@@ -186,7 +192,7 @@
     "views": [],
     "setupQueries": [
       "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
-      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5117ed4caaa7ecd70051902d844cc665')"
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e23913768d43dc0cb1374df83b2fa78a')"
     ]
   }
 }
\ No newline at end of file
diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryDatabaseMigrationTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryDatabaseMigrationTest.kt
index dd683c4bb199b41cb7b86bafd5c90a391a5b63c7..ca8693d3e9f5dbffcb530372d64118dfb452d477 100644
--- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryDatabaseMigrationTest.kt
+++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryDatabaseMigrationTest.kt
@@ -20,6 +20,7 @@ import io.kotest.assertions.throwables.shouldThrow
 import io.kotest.matchers.shouldBe
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.runBlocking
+import okio.ByteString.Companion.decodeBase64
 import org.joda.time.Duration
 import org.joda.time.LocalDate
 import org.junit.Rule
@@ -176,7 +177,7 @@ class ContactDiaryDatabaseMigrationTest : BaseTestInstrumentation() {
             checkInID = null
         )
 
-        val locationAfter = location.copy(traceLocationID = "jshrgu-aifhioaio-aofsjof-samofp-kjsadngsgf")
+        val locationAfter = location.copy(traceLocationID = "jshrgu-aifhioaio-aofsjof-samofp-kjsadngsgf".decodeBase64())
         val locationVisitAfter = locationVisit.copy(checkInID = 101)
 
         val locationValues = ContentValues().apply {
diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryDatabaseTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryDatabaseTest.kt
index e3573457d057cb87c2ee4b83e266b9ea276d85b6..6cdc211e2e3dcede9208f035865bd672d741c736 100644
--- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryDatabaseTest.kt
+++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryDatabaseTest.kt
@@ -14,6 +14,7 @@ import io.kotest.matchers.shouldBe
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.runBlocking
+import okio.ByteString.Companion.decodeBase64
 import org.joda.time.Duration
 import org.joda.time.LocalDate
 import org.junit.After
@@ -37,7 +38,7 @@ class ContactDiaryDatabaseTest : BaseTestInstrumentation() {
         locationName = "Rewe Wiesloch",
         emailAddress = "location-emailAddress",
         phoneNumber = "location-phoneNumber",
-        traceLocationID = "a-b-c-d"
+        traceLocationID = "a-b-c-d".decodeBase64()
     )
     private val personEncounter = ContactDiaryPersonEncounterEntity(
         id = 3,
diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/CheckInDatabaseData.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/CheckInDatabaseData.kt
index 370276daf4fe3f5f3dae2b3a188cd403f52488b2..1ab9a7725c591841be423ccaad882b5d9481a744 100644
--- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/CheckInDatabaseData.kt
+++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/CheckInDatabaseData.kt
@@ -21,7 +21,8 @@ object CheckInDatabaseData {
         checkInStart = Instant.parse("2021-01-01T12:30:00.000Z"),
         checkInEnd = Instant.parse("2021-01-01T14:00:00.000Z"),
         completed = false,
-        createJournalEntry = true
+        createJournalEntry = true,
+        isSubmitted = false,
     )
 
     val testCheckInWithoutCheckOutTime = TraceLocationCheckInEntity(
@@ -38,6 +39,7 @@ object CheckInDatabaseData {
         checkInStart = Instant.parse("2021-01-01T12:30:00.000Z"),
         checkInEnd = Instant.parse("2021-01-01T14:00:00.000Z"),
         completed = false,
-        createJournalEntry = true
+        createJournalEntry = true,
+        isSubmitted = false,
     )
 }
diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/tracing/TracingData.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/tracing/TracingData.kt
index c1b30a16e5ee62271d1774e40f2bbd7690d67890..44c7ad447b3bf012d76b619785501206af247e24 100644
--- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/tracing/TracingData.kt
+++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/tracing/TracingData.kt
@@ -48,7 +48,7 @@ object TracingData {
                 daysSinceInstallation = 4,
                 tracingStatus = GeneralTracingStatus.Status.TRACING_INACTIVE
             ),
-            DetailsLowRiskBox.Item(riskState = RiskState.LOW_RISK, matchedKeyCount = 0)
+            DetailsLowRiskBox.Item(riskState = RiskState.LOW_RISK, matchedRiskCount = 0)
         )
     )
 
@@ -79,7 +79,7 @@ object TracingData {
                 daysSinceInstallation = 4,
                 tracingStatus = GeneralTracingStatus.Status.TRACING_ACTIVE
             ),
-            DetailsLowRiskBox.Item(riskState = RiskState.LOW_RISK, matchedKeyCount = 0)
+            DetailsLowRiskBox.Item(riskState = RiskState.LOW_RISK, matchedRiskCount = 0)
         )
     )
 
@@ -110,7 +110,7 @@ object TracingData {
                 daysSinceInstallation = 4,
                 tracingStatus = GeneralTracingStatus.Status.TRACING_ACTIVE
             ),
-            DetailsLowRiskBox.Item(riskState = RiskState.LOW_RISK, matchedKeyCount = 0)
+            DetailsLowRiskBox.Item(riskState = RiskState.LOW_RISK, matchedRiskCount = 0)
         )
     )
 
@@ -141,7 +141,7 @@ object TracingData {
                 daysSinceInstallation = 4,
                 tracingStatus = GeneralTracingStatus.Status.TRACING_ACTIVE
             ),
-            DetailsLowRiskBox.Item(riskState = RiskState.LOW_RISK, matchedKeyCount = 0)
+            DetailsLowRiskBox.Item(riskState = RiskState.LOW_RISK, matchedRiskCount = 0)
         )
     )
 
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/appconfig/ui/AppConfigTestFragment.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/appconfig/ui/AppConfigTestFragment.kt
index 9aa9ce21df5fb36f43c569af882b517ca8751ff5..c151d90a77c3853a014e640c38a5dce0d7f5305e 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/appconfig/ui/AppConfigTestFragment.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/appconfig/ui/AppConfigTestFragment.kt
@@ -28,6 +28,7 @@ class AppConfigTestFragment : Fragment(R.layout.fragment_test_appconfig), AutoIn
     private val timeFormatter = ISODateTimeFormat.dateTime()
         .withZone(DateTimeZone.forID("Europe/Berlin"))
 
+    @Suppress("DEPRECATION")
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
 
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/SettingsCrashReportViewModel.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/SettingsCrashReportViewModel.kt
index b02e7a18b31e5d7475a9e102204205ac43a1840c..0b43e0de5005ba6180632620c5f6ee808022fe16 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/SettingsCrashReportViewModel.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/crash.ui/SettingsCrashReportViewModel.kt
@@ -31,7 +31,7 @@ class SettingsCrashReportViewModel @AssistedInject constructor(
 
     fun simulateException() {
         try {
-            val a = 2 / 0
+            throw RuntimeException("Test crash reporting")
         } catch (e: Exception) {
             Timber.e(e, "Msg: ${e.message}")
             e.reportProblem(SettingsCrashReportViewModel::class.java.simpleName, e.message)
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/deltaonboarding/ui/DeltaOnboardingFragmentViewModel.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/deltaonboarding/ui/DeltaOnboardingFragmentViewModel.kt
index 49daaf6fa2da7d161058154d3607cca0196ca57c..9152f953ae3a51042e5a7e816e5a0f5998b3dc6b 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/deltaonboarding/ui/DeltaOnboardingFragmentViewModel.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/deltaonboarding/ui/DeltaOnboardingFragmentViewModel.kt
@@ -6,6 +6,7 @@ import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import de.rki.coronawarnapp.contactdiary.ui.ContactDiarySettings
 import de.rki.coronawarnapp.environment.BuildConfigWrap
+import de.rki.coronawarnapp.eventregistration.TraceLocationSettings
 import de.rki.coronawarnapp.main.CWASettings
 import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
@@ -13,6 +14,7 @@ import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory
 
 class DeltaOnboardingFragmentViewModel @AssistedInject constructor(
     private val settings: CWASettings,
+    private val traceLocationSettings: TraceLocationSettings,
     private val contactDiarySettings: ContactDiarySettings,
     dispatcherProvider: DispatcherProvider
 ) : CWAViewModel(dispatcherProvider = dispatcherProvider) {
@@ -43,10 +45,21 @@ class DeltaOnboardingFragmentViewModel @AssistedInject constructor(
 
     fun isDeltaOnboardingDone() = settings.wasInteroperabilityShownAtLeastOnce
 
-    fun setDeltaOboardinDone(value: Boolean) {
+    fun setDeltaOnboardingDone(value: Boolean) {
         settings.wasInteroperabilityShownAtLeastOnce = value
     }
 
+    fun isAttendeeOnboardingDone() =
+        traceLocationSettings.onboardingStatus == TraceLocationSettings.OnboardingStatus.ONBOARDED_2_0
+
+    fun setAttendeeOnboardingDone(value: Boolean) {
+        traceLocationSettings.onboardingStatus =
+            if (value)
+                TraceLocationSettings.OnboardingStatus.ONBOARDED_2_0
+            else
+                TraceLocationSettings.OnboardingStatus.NOT_ONBOARDED
+    }
+
     @AssistedFactory
     interface Factory : SimpleCWAViewModelFactory<DeltaOnboardingFragmentViewModel>
 }
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/deltaonboarding/ui/DeltaonboardingFragment.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/deltaonboarding/ui/DeltaonboardingFragment.kt
index 1179e8e0701823179fafe78cb56af5e5dc210d98..1308cff1b13d6ab80567562b9d346df0fb14a5d2 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/deltaonboarding/ui/DeltaonboardingFragment.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/deltaonboarding/ui/DeltaonboardingFragment.kt
@@ -26,6 +26,7 @@ class DeltaonboardingFragment : Fragment(R.layout.fragment_test_deltaonboarding)
 
         binding.switchContactJournalOnboarding.isChecked = viewModel.isContactJournalOnboardingDone()
         binding.switchDeltaOnboarding.isChecked = viewModel.isDeltaOnboardingDone()
+        binding.switchAttendeeOnboarding.isChecked = viewModel.isAttendeeOnboardingDone()
         viewModel.changelogVersion.observe(viewLifecycleOwner) {
             binding.lastChangelogEdittext.setText(it.toString())
         }
@@ -48,7 +49,11 @@ class DeltaonboardingFragment : Fragment(R.layout.fragment_test_deltaonboarding)
         }
 
         binding.switchDeltaOnboarding.setOnCheckedChangeListener { _, value ->
-            viewModel.setDeltaOboardinDone(value)
+            viewModel.setDeltaOnboardingDone(value)
+        }
+
+        binding.switchAttendeeOnboarding.setOnCheckedChangeListener { _, value ->
+            viewModel.setAttendeeOnboardingDone(value)
         }
     }
 
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/menu/ui/TestMenuFragmentViewModel.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/menu/ui/TestMenuFragmentViewModel.kt
index e631969b4290fe76b22c48870f35bb55b96d1b9d..b4200bc33c96ba2d8132bc803a3657f3831a69f5 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/menu/ui/TestMenuFragmentViewModel.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/menu/ui/TestMenuFragmentViewModel.kt
@@ -10,7 +10,7 @@ import de.rki.coronawarnapp.test.crash.ui.SettingsCrashReportFragment
 import de.rki.coronawarnapp.test.datadonation.ui.DataDonationTestFragment
 import de.rki.coronawarnapp.test.debugoptions.ui.DebugOptionsFragment
 import de.rki.coronawarnapp.test.deltaonboarding.ui.DeltaonboardingFragment
-import de.rki.coronawarnapp.test.eventregistration.ui.EventRegistrationTestFragment
+import de.rki.coronawarnapp.test.presencetracing.ui.PresenceTracingTestFragment
 import de.rki.coronawarnapp.test.keydownload.ui.KeyDownloadTestFragment
 import de.rki.coronawarnapp.test.playground.ui.PlaygroundFragment
 import de.rki.coronawarnapp.test.risklevel.ui.TestRiskLevelCalculationFragment
@@ -36,7 +36,7 @@ class TestMenuFragmentViewModel @AssistedInject constructor() : CWAViewModel() {
             PlaygroundFragment.MENU_ITEM,
             DataDonationTestFragment.MENU_ITEM,
             DeltaonboardingFragment.MENU_ITEM,
-            EventRegistrationTestFragment.MENU_ITEM,
+            PresenceTracingTestFragment.MENU_ITEM,
         ).let { MutableLiveData(it) }
     }
     val showTestScreenEvent = SingleLiveEvent<TestMenuItem>()
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/eventregistration/ui/EventRegistrationTestFragment.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/PresenceTracingTestFragment.kt
similarity index 84%
rename from Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/eventregistration/ui/EventRegistrationTestFragment.kt
rename to Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/PresenceTracingTestFragment.kt
index 95d522e04234c83bbafcb5d659bf3b60cca610e0..8e54311d1f424a8bb319fe076fc00ba731524871 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/eventregistration/ui/EventRegistrationTestFragment.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/PresenceTracingTestFragment.kt
@@ -1,4 +1,4 @@
-package de.rki.coronawarnapp.test.eventregistration.ui
+package de.rki.coronawarnapp.test.presencetracing.ui
 
 import android.annotation.SuppressLint
 import android.os.Bundle
@@ -11,7 +11,7 @@ import androidx.core.text.scale
 import androidx.core.view.isVisible
 import androidx.fragment.app.Fragment
 import de.rki.coronawarnapp.R
-import de.rki.coronawarnapp.databinding.FragmentTestEventregistrationBinding
+import de.rki.coronawarnapp.databinding.FragmentTestPresenceTracingBinding
 import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocation
 import de.rki.coronawarnapp.test.menu.ui.TestMenuItem
 import de.rki.coronawarnapp.util.ContextExtensions.getColorCompat
@@ -24,12 +24,12 @@ import de.rki.coronawarnapp.util.viewmodel.cwaViewModels
 import javax.inject.Inject
 
 @SuppressLint("SetTextI18n")
-class EventRegistrationTestFragment : Fragment(R.layout.fragment_test_eventregistration), AutoInject {
+class PresenceTracingTestFragment : Fragment(R.layout.fragment_test_presence_tracing), AutoInject {
 
     @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
-    private val viewModel: EventRegistrationTestFragmentViewModel by cwaViewModels { viewModelFactory }
+    private val viewModel: PresenceTracingTestViewModel by cwaViewModels { viewModelFactory }
 
-    private val binding: FragmentTestEventregistrationBinding by viewBindingLazy()
+    private val binding: FragmentTestPresenceTracingBinding by viewBindingLazy()
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
@@ -71,8 +71,8 @@ class EventRegistrationTestFragment : Fragment(R.layout.fragment_test_eventregis
                     lastOrganiserLocationUrl.text = styleText("URL", traceLocation.locationUrl)
                     qrcodeButton.setOnClickListener {
                         doNavigate(
-                            EventRegistrationTestFragmentDirections
-                                .actionEventRegistrationTestFragmentToQrCodePosterFragmentTest(traceLocation.id)
+                            PresenceTracingTestFragmentDirections
+                                .actionPresenceTracingTestFragmentToQrCodePosterTestFragment(traceLocation.id)
                         )
                     }
                 }
@@ -112,7 +112,7 @@ class EventRegistrationTestFragment : Fragment(R.layout.fragment_test_eventregis
         buildSpannedString {
             bold {
                 color(requireContext().getColorCompat(R.color.colorAccent)) {
-                    append("$key=")
+                    append("$key = ")
                 }
             }
 
@@ -121,14 +121,14 @@ class EventRegistrationTestFragment : Fragment(R.layout.fragment_test_eventregis
                     append(value.toString())
                 }
             }
-            append("\n")
+            appendLine()
         }
 
     companion object {
         val MENU_ITEM = TestMenuItem(
-            title = "Event Registration",
-            description = "View & Control the event registration.",
-            targetId = R.id.eventRegistrationTestFragment
+            title = "Presence Tracing",
+            description = "View & Control presence tracing",
+            targetId = R.id.presenceTracingTestFragment
         )
     }
 }
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/eventregistration/ui/EventRegistrationTestFragmentModule.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/PresenceTracingTestFragmentModule.kt
similarity index 53%
rename from Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/eventregistration/ui/EventRegistrationTestFragmentModule.kt
rename to Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/PresenceTracingTestFragmentModule.kt
index 3c95a0a4a47d729182eca300cc9e5b7a70ad655f..db41dfdf6a73e26b68393cb7cac9f3b978fba903 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/eventregistration/ui/EventRegistrationTestFragmentModule.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/PresenceTracingTestFragmentModule.kt
@@ -1,4 +1,4 @@
-package de.rki.coronawarnapp.test.eventregistration.ui
+package de.rki.coronawarnapp.test.presencetracing.ui
 
 import dagger.Binds
 import dagger.Module
@@ -8,11 +8,11 @@ import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey
 
 @Module
-abstract class EventRegistrationTestFragmentModule {
+abstract class PresenceTracingTestFragmentModule {
     @Binds
     @IntoMap
-    @CWAViewModelKey(EventRegistrationTestFragmentViewModel::class)
-    abstract fun testEventRegistrationFragment(
-        factory: EventRegistrationTestFragmentViewModel.Factory
+    @CWAViewModelKey(PresenceTracingTestViewModel::class)
+    abstract fun testPresenceTracingFragment(
+        factory: PresenceTracingTestViewModel.Factory
     ): CWAViewModelFactory<out CWAViewModel>
 }
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/eventregistration/ui/EventRegistrationTestFragmentViewModel.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/PresenceTracingTestViewModel.kt
similarity index 96%
rename from Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/eventregistration/ui/EventRegistrationTestFragmentViewModel.kt
rename to Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/PresenceTracingTestViewModel.kt
index 3913503fe7082eb9597ce0f5b8d136bd9d0513e1..7e0e674bcee1e3f48cb962d9a1f286e9ef20f8ba 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/eventregistration/ui/EventRegistrationTestFragmentViewModel.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/PresenceTracingTestViewModel.kt
@@ -1,4 +1,4 @@
-package de.rki.coronawarnapp.test.eventregistration.ui
+package de.rki.coronawarnapp.test.presencetracing.ui
 
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
@@ -26,7 +26,7 @@ import kotlinx.coroutines.flow.map
 import timber.log.Timber
 import kotlin.system.measureTimeMillis
 
-class EventRegistrationTestFragmentViewModel @AssistedInject constructor(
+class PresenceTracingTestViewModel @AssistedInject constructor(
     dispatcherProvider: DispatcherProvider,
     traceLocationRepository: TraceLocationRepository,
     checkInRepository: CheckInRepository,
@@ -144,5 +144,5 @@ class EventRegistrationTestFragmentViewModel @AssistedInject constructor(
     }
 
     @AssistedFactory
-    interface Factory : SimpleCWAViewModelFactory<EventRegistrationTestFragmentViewModel>
+    interface Factory : SimpleCWAViewModelFactory<PresenceTracingTestViewModel>
 }
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/poster/QrCodePosterTestFragment.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/poster/QrCodePosterTestFragment.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c4aa4a257925c75f84e399058b78d5abfc9eddb6
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/poster/QrCodePosterTestFragment.kt
@@ -0,0 +1,298 @@
+package de.rki.coronawarnapp.test.presencetracing.ui.poster
+
+import android.annotation.SuppressLint
+import android.os.Bundle
+import android.print.PrintAttributes
+import android.print.PrintManager
+import android.text.SpannedString
+import android.util.TypedValue
+import android.view.View
+import android.widget.Toast
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.content.getSystemService
+import androidx.core.text.bold
+import androidx.core.text.buildSpannedString
+import androidx.core.text.color
+import androidx.core.view.isVisible
+import androidx.core.widget.TextViewCompat
+import androidx.core.widget.doOnTextChanged
+import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.navArgs
+import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.databinding.FragmentTestQrCodePosterBinding
+import de.rki.coronawarnapp.exception.ExceptionCategory
+import de.rki.coronawarnapp.exception.reporting.report
+import de.rki.coronawarnapp.server.protocols.internal.pt.QrCodePosterTemplate
+import de.rki.coronawarnapp.ui.color.parseColor
+import de.rki.coronawarnapp.ui.print.PrintingAdapter
+import de.rki.coronawarnapp.util.ContextExtensions.getColorCompat
+import de.rki.coronawarnapp.util.di.AutoInject
+import de.rki.coronawarnapp.util.ui.popBackStack
+import de.rki.coronawarnapp.util.ui.viewBindingLazy
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
+import de.rki.coronawarnapp.util.viewmodel.cwaViewModelsAssisted
+import timber.log.Timber
+import java.io.File
+import javax.inject.Inject
+
+@SuppressLint("SetTextI18n")
+class QrCodePosterTestFragment : Fragment(R.layout.fragment_test_qr_code_poster), AutoInject {
+
+    @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
+
+    private val args by navArgs<QrCodePosterTestFragmentArgs>()
+    private val viewModel: QrCodePosterTestViewModel by cwaViewModelsAssisted(
+        factoryProducer = { viewModelFactory },
+        constructorCall = { factory, _ ->
+            factory as QrCodePosterTestViewModel.Factory
+            factory.create(args.traceLocationId)
+        }
+    )
+
+    private var itemId = -1
+
+    private val binding: FragmentTestQrCodePosterBinding by viewBindingLazy()
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        with(binding) {
+            toolbar.setNavigationOnClickListener { popBackStack() }
+            viewModel.poster.observe(viewLifecycleOwner) { poster ->
+                bindPoster(poster)
+                bindToolbar()
+            }
+        }
+
+        viewModel.sharingIntent.observe(viewLifecycleOwner) { fileIntent ->
+            when (itemId) {
+                R.id.action_print -> printFile(fileIntent.file)
+                R.id.action_share -> startActivity(fileIntent.intent(requireActivity()))
+            }
+        }
+
+        viewModel.qrCodeBitmap.observe(viewLifecycleOwner) {
+            binding.qrCodeImage.setImageBitmap(it)
+        }
+    }
+
+    private fun FragmentTestQrCodePosterBinding.bindPoster(poster: QrCodePosterTestViewModel.Poster) {
+        Timber.d("poster=$poster")
+        progressBar.hide()
+
+        val template = poster.template ?: return // Exit early
+        Timber.d("template=$template")
+
+        // Adjust poster image dimensions ratio to have a proper printing preview
+        val posterLayoutParam = posterImage.layoutParams as ConstraintLayout.LayoutParams
+        val dimensionRatio = template.run { "$width:$height" } // W:H
+        Timber.d("dimensionRatio=$dimensionRatio")
+        posterLayoutParam.dimensionRatio = dimensionRatio
+
+        // Display images
+        qrCodeImage.setImageBitmap(poster.qrCode)
+        posterImage.setImageBitmap(template.bitmap)
+
+        // Position QR Code image based on data provided by server
+        topGuideline.setGuidelinePercent(template.offsetY)
+        startGuideline.setGuidelinePercent(template.offsetX)
+        endGuideline.setGuidelinePercent(1 - template.offsetX)
+
+        // Qr Code positioning
+        qrOffsetXSlider.apply {
+            value = template.offsetX.sliderValue
+            addOnChangeListener { _, value, fromUser ->
+                if (fromUser) {
+                    val offset = value.percentage
+                    startGuideline.setGuidelinePercent(offset)
+                    endGuideline.setGuidelinePercent(1 - offset)
+                    updateQrCodeOffsetText()
+                }
+            }
+        }
+        qrOffsetYSlider.apply {
+            value = template.offsetY.sliderValue
+            addOnChangeListener { _, value, fromUser ->
+                if (fromUser) {
+                    topGuideline.setGuidelinePercent(value.percentage)
+                    updateQrCodeOffsetText()
+                }
+            }
+        }
+        updateQrCodeOffsetText()
+
+        qrLengthSlider.apply {
+            value = poster.template.qrCodeLength.toFloat()
+            addOnChangeListener { _, value, _ ->
+                updateQrCodeLengthText()
+                viewModel.generateQrCode(value.toInt())
+            }
+        }
+        updateQrCodeLengthText()
+
+        // Bind text info
+        bindTextBox(poster.infoText, poster.template.textBox)
+        offsetsPanel.isVisible = true
+        tooltip.setOnClickListener {
+            Toast.makeText(requireContext(), toastText(), Toast.LENGTH_LONG).show()
+        }
+    }
+
+    private fun toastText(): SpannedString =
+        buildSpannedString {
+            bold {
+                append("Tips:")
+            }
+            color(requireContext().getColorCompat(R.color.colorAccent)) {
+                appendLine()
+                appendLine()
+                append(
+                    "- Qr-Code Length defines Qr-Code bitmap length and not" +
+                        "\nthe displayed Qr-Code ImageView where its length is flexible per screen size" +
+                        "\nIn a way it defines the bitmap quality." +
+                        "\nThe more the length the more the bitmaps's sharpness."
+                )
+
+                appendLine()
+                appendLine()
+                append(
+                    "- Text below Qr-Code has max 2 lines and has a uniform auto scaling down to `fontSize - 6`." +
+                        "\nIf the size is way larger than it fits in two lines, it will be cut."
+                )
+
+                appendLine()
+                appendLine()
+                append(
+                    "- OffsetX defines the position of two guidelines left and right for the edges." +
+                        "\n If the offset is increasing, the space in between the guidelines is decreasing." +
+                        "\n Which means less width of the respective view. -> | -> view_width <- | <- "
+                )
+            }
+        }
+
+    private fun updateQrCodeLengthText() {
+        val value = binding.qrLengthSlider.value
+        binding.qrCodeLength.text = "Qr Code length:%d".format(value.toInt())
+    }
+
+    private fun FragmentTestQrCodePosterBinding.bindTextBox(
+        infoText: String,
+        textBox: QrCodePosterTemplate.QRCodePosterTemplateAndroid.QRCodeTextBoxAndroid
+    ) = with(infoTextView) {
+        text = infoText
+        setFontSize(textBox.fontSize)
+        setTextColor(textBox.fontColor.parseColor())
+        textEndGuideline.setGuidelinePercent(1 - textBox.offsetX)
+        textStartGuideline.setGuidelinePercent(textBox.offsetX)
+        textTopGuideline.setGuidelinePercent(textBox.offsetY)
+
+        // Text Position
+        txtOffsetXSlider.apply {
+            value = textBox.offsetX.sliderValue
+            addOnChangeListener { _, value, fromUser ->
+                if (fromUser) {
+                    val offset = value.percentage
+                    textEndGuideline.setGuidelinePercent(1 - offset)
+                    textStartGuideline.setGuidelinePercent(offset)
+                    updateInfoOffsetText()
+                }
+            }
+        }
+        txtOffsetYSlider.apply {
+            value = textBox.offsetY.sliderValue
+            addOnChangeListener { _, value, fromUser ->
+                if (fromUser) {
+                    textTopGuideline.setGuidelinePercent(value.percentage)
+                    updateInfoOffsetText()
+                }
+            }
+        }
+        updateInfoOffsetText()
+
+        // Text Size
+        infoTextSizeSlider.apply {
+            value = textBox.fontSize.toFloat()
+            addOnChangeListener { _, value, _ ->
+                updateFontSizeText()
+                setFontSize(value.toInt())
+            }
+        }
+        updateFontSizeText()
+
+        // Text Color
+        infoTextColorValue.doOnTextChanged { color, _, _, _ ->
+            infoTextView.setTextColor(color.toString().parseColor())
+        }
+    }
+
+    private fun updateFontSizeText() {
+        binding.infoTextSize.text =
+            "Font size: %s sp".format(binding.infoTextSizeSlider.value)
+    }
+
+    private fun FragmentTestQrCodePosterBinding.setFontSize(maxFontSize: Int) {
+        val minFontSize = maxFontSize - 6
+        TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(
+            infoTextView,
+            minFontSize,
+            maxFontSize,
+            1,
+            TypedValue.COMPLEX_UNIT_SP
+        )
+        infoTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, maxFontSize.toFloat())
+    }
+
+    private fun FragmentTestQrCodePosterBinding.bindToolbar() {
+        toolbar.setOnMenuItemClickListener {
+            itemId = it.itemId
+            viewModel.createPDF(binding.qrCodePoster)
+            true
+        }
+    }
+
+    private fun printFile(file: File) {
+        val printingManger = context?.getSystemService<PrintManager>()
+        Timber.i("PrintingManager=$printingManger")
+        if (printingManger == null) {
+            Toast.makeText(requireContext(), R.string.errors_generic_headline, Toast.LENGTH_LONG).show()
+            return
+        }
+
+        try {
+            val job = printingManger.print(
+                getString(R.string.app_name),
+                PrintingAdapter(file),
+                PrintAttributes.Builder()
+                    .setMediaSize(PrintAttributes.MediaSize.ISO_A3)
+                    .build()
+            )
+
+            Timber.d("JobState=%s", job.info.state)
+        } catch (e: Exception) {
+            Timber.d(e, "Printing job failed")
+            e.report(ExceptionCategory.INTERNAL)
+        }
+    }
+
+    private fun updateQrCodeOffsetText() {
+        with(binding) {
+            qrCodeOffsets.text = "Qr Code offsets: X=%.3f, Y=%.3f".format(
+                qrOffsetXSlider.value.percentage,
+                qrOffsetYSlider.value.percentage
+            )
+        }
+    }
+
+    private fun updateInfoOffsetText() {
+        with(binding) {
+            infoTextOffsets.text = "Text offsets: X=%.3f, Y=%.3f".format(
+                txtOffsetXSlider.value.percentage,
+                txtOffsetYSlider.value.percentage
+            )
+        }
+    }
+
+    private val Float.percentage get() = this / 1000
+
+    private val Float.sliderValue get() = this * 1000
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/poster/QrCodePosterTestFragmentModule.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/poster/QrCodePosterTestFragmentModule.kt
new file mode 100644
index 0000000000000000000000000000000000000000..871e9145d64a740fe20b77525813dc9174aca507
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/poster/QrCodePosterTestFragmentModule.kt
@@ -0,0 +1,18 @@
+package de.rki.coronawarnapp.test.presencetracing.ui.poster
+
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.IntoMap
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey
+
+@Module
+abstract class QrCodePosterTestFragmentModule {
+    @Binds
+    @IntoMap
+    @CWAViewModelKey(QrCodePosterTestViewModel::class)
+    abstract fun qrCodePosterTestFragmentModule(
+        factory: QrCodePosterTestViewModel.Factory
+    ): CWAViewModelFactory<out CWAViewModel>
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/poster/QrCodePosterTestViewModel.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/poster/QrCodePosterTestViewModel.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f4cf799fa56161f0b5171622d89d8cca564f7e66
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/presencetracing/ui/poster/QrCodePosterTestViewModel.kt
@@ -0,0 +1,138 @@
+package de.rki.coronawarnapp.test.presencetracing.ui.poster
+
+import android.graphics.Bitmap
+import android.graphics.pdf.PdfDocument
+import android.view.View
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import de.rki.coronawarnapp.eventregistration.checkins.qrcode.PosterTemplateProvider
+import de.rki.coronawarnapp.eventregistration.checkins.qrcode.QrCodeGenerator
+import de.rki.coronawarnapp.eventregistration.checkins.qrcode.Template
+import de.rki.coronawarnapp.eventregistration.storage.repo.TraceLocationRepository
+import de.rki.coronawarnapp.exception.ExceptionCategory
+import de.rki.coronawarnapp.exception.reporting.report
+import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
+import de.rki.coronawarnapp.util.files.FileSharing
+import de.rki.coronawarnapp.util.ui.SingleLiveEvent
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
+import timber.log.Timber
+import java.io.File
+import java.io.FileOutputStream
+import java.lang.ref.WeakReference
+
+class QrCodePosterTestViewModel @AssistedInject constructor(
+    @Assisted private val traceLocationId: Long,
+    private val dispatcher: DispatcherProvider,
+    private val qrCodeGenerator: QrCodeGenerator,
+    private val posterTemplateProvider: PosterTemplateProvider,
+    private val traceLocationRepository: TraceLocationRepository,
+    private val fileSharing: FileSharing
+) : CWAViewModel(dispatcher) {
+
+    private val posterLiveData = MutableLiveData<Poster>()
+    val poster: LiveData<Poster> = posterLiveData
+    val sharingIntent = SingleLiveEvent<FileSharing.FileIntentProvider>()
+    val qrCodeBitmap = SingleLiveEvent<Bitmap>()
+    private var isRunning = false
+
+    init {
+        generatePoster()
+    }
+
+    /**
+     * Create a new PDF file and result is delivered by [sharingIntent]
+     * as a sharing [FileSharing.ShareIntentProvider]
+     */
+    @Suppress("BlockingMethodInNonBlockingContext")
+    fun createPDF(view: View) = launch(context = dispatcher.IO) {
+        try {
+            val weakViewRef = WeakReference(view) // Accessing view in background thread
+            val directory = File(view.context.cacheDir, "poster").apply { if (!exists()) mkdirs() }
+            val file = File(directory, "cwa-qr-code.pdf")
+
+            val weakView = weakViewRef.get() ?: return@launch // View is not existing anymore
+            val pageInfo = PdfDocument.PageInfo.Builder(weakView.width, weakView.height, 1).create()
+
+            PdfDocument().apply {
+                startPage(pageInfo).apply {
+                    weakView.draw(canvas)
+                    finishPage(this)
+                }
+
+                FileOutputStream(file).use {
+                    writeTo(it)
+                    close()
+                }
+            }
+
+            sharingIntent.postValue(fileSharing.getFileIntentProvider(file, traceLocation().description))
+        } catch (e: Exception) {
+            Timber.d(e, "Creating pdf failed")
+            e.report(ExceptionCategory.INTERNAL)
+        }
+    }
+
+    fun generateQrCode(length: Int) = launch(context = dispatcher.IO) {
+        try {
+            if (isRunning) return@launch
+            isRunning = true
+            val traceLocation = traceLocation()
+            val qrCode = qrCodeGenerator.createQrCode(
+                input = traceLocation.locationUrl,
+                length = length,
+                margin = 0
+            )
+            qrCodeBitmap.postValue(qrCode)
+        } catch (e: Exception) {
+            Timber.e(e)
+            e.report(ExceptionCategory.INTERNAL)
+        } finally {
+            isRunning = false
+        }
+    }
+
+    private fun generatePoster() = launch(context = dispatcher.IO) {
+        try {
+            val traceLocation = traceLocation()
+            val template = posterTemplateProvider.template()
+            Timber.d("template=$template")
+            val qrCode = qrCodeGenerator.createQrCode(
+                input = traceLocation.locationUrl,
+                length = template.qrCodeLength,
+                margin = 0
+            )
+
+            val textInfo = buildString {
+                append(traceLocation.description)
+                appendLine()
+                append(traceLocation.address)
+            }
+            posterLiveData.postValue(
+                Poster(qrCode, template, textInfo)
+            )
+        } catch (e: Exception) {
+            Timber.d(e, "Generating poster failed")
+            posterLiveData.postValue(Poster())
+            e.report(ExceptionCategory.INTERNAL)
+        }
+    }
+
+    private suspend fun traceLocation() = traceLocationRepository.traceLocationForId(traceLocationId)
+
+    @AssistedFactory
+    interface Factory : CWAViewModelFactory<QrCodePosterTestViewModel> {
+        fun create(
+            traceLocationId: Long
+        ): QrCodePosterTestViewModel
+    }
+
+    data class Poster(
+        val qrCode: Bitmap? = null,
+        val template: Template? = null,
+        val infoText: String = ""
+    )
+}
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt
index ed246e65b60fc63a60c27263933ca1ee8315a5c0..d8968b77d5260df6292fb3eb131ad0e9685fa404 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt
@@ -104,6 +104,7 @@ class TestRiskLevelCalculationFragmentCWAViewModel @AssistedInject constructor(
         .appendLine("Number of Days With Low Risk: $numberOfDaysWithLowRisk")
         .toString()
 
+    @Suppress("DEPRECATION")
     val backendParameters = appConfigProvider
         .currentConfig
         .map { it.rawConfig.riskCalculationParameters.toString() }
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/ui/main/MainActivityTestModule.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/ui/main/MainActivityTestModule.kt
index 9728bc8fd07c67ac0dec8dfe6185f066692b91e9..e4a3ea0afa6b77501ace2c87fe364335253996e6 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/ui/main/MainActivityTestModule.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/ui/main/MainActivityTestModule.kt
@@ -14,22 +14,22 @@ import de.rki.coronawarnapp.test.debugoptions.ui.DebugOptionsFragment
 import de.rki.coronawarnapp.test.debugoptions.ui.DebugOptionsFragmentModule
 import de.rki.coronawarnapp.test.deltaonboarding.ui.DeltaOnboardingFragmentModule
 import de.rki.coronawarnapp.test.deltaonboarding.ui.DeltaonboardingFragment
-import de.rki.coronawarnapp.test.eventregistration.ui.EventRegistrationTestFragment
-import de.rki.coronawarnapp.test.eventregistration.ui.EventRegistrationTestFragmentModule
+import de.rki.coronawarnapp.test.presencetracing.ui.PresenceTracingTestFragment
+import de.rki.coronawarnapp.test.presencetracing.ui.PresenceTracingTestFragmentModule
 import de.rki.coronawarnapp.test.keydownload.ui.KeyDownloadTestFragment
 import de.rki.coronawarnapp.test.keydownload.ui.KeyDownloadTestFragmentModule
 import de.rki.coronawarnapp.test.menu.ui.TestMenuFragment
 import de.rki.coronawarnapp.test.menu.ui.TestMenuFragmentModule
 import de.rki.coronawarnapp.test.playground.ui.PlaygroundFragment
 import de.rki.coronawarnapp.test.playground.ui.PlaygroundModule
+import de.rki.coronawarnapp.test.presencetracing.ui.poster.QrCodePosterTestFragment
+import de.rki.coronawarnapp.test.presencetracing.ui.poster.QrCodePosterTestFragmentModule
 import de.rki.coronawarnapp.test.risklevel.ui.TestRiskLevelCalculationFragment
 import de.rki.coronawarnapp.test.risklevel.ui.TestRiskLevelCalculationFragmentModule
 import de.rki.coronawarnapp.test.submission.ui.SubmissionTestFragment
 import de.rki.coronawarnapp.test.submission.ui.SubmissionTestFragmentModule
 import de.rki.coronawarnapp.test.tasks.ui.TestTaskControllerFragment
 import de.rki.coronawarnapp.test.tasks.ui.TestTaskControllerFragmentModule
-import de.rki.coronawarnapp.ui.eventregistration.organizer.details.QrCodeDetailFragment
-import de.rki.coronawarnapp.ui.eventregistration.organizer.details.QrCodeDetailFragmentModule
 
 @Module
 abstract class MainActivityTestModule {
@@ -70,9 +70,9 @@ abstract class MainActivityTestModule {
     @ContributesAndroidInjector(modules = [DeltaOnboardingFragmentModule::class])
     abstract fun deltaOnboarding(): DeltaonboardingFragment
 
-    @ContributesAndroidInjector(modules = [EventRegistrationTestFragmentModule::class])
-    abstract fun eventRegistration(): EventRegistrationTestFragment
+    @ContributesAndroidInjector(modules = [PresenceTracingTestFragmentModule::class])
+    abstract fun eventRegistration(): PresenceTracingTestFragment
 
-    @ContributesAndroidInjector(modules = [QrCodeDetailFragmentModule::class])
-    abstract fun showEventDetail(): QrCodeDetailFragment
+    @ContributesAndroidInjector(modules = [QrCodePosterTestFragmentModule::class])
+    abstract fun showEventDetail(): QrCodePosterTestFragment
 }
diff --git a/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_deltaonboarding.xml b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_deltaonboarding.xml
index 374995566303f641149887fb280e156f3eec5f80..b1305ae31eaabe74c88dd174a649dcb4787db6be 100644
--- a/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_deltaonboarding.xml
+++ b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_deltaonboarding.xml
@@ -146,5 +146,32 @@
 
         </androidx.constraintlayout.widget.ConstraintLayout>
 
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/debug_container4"
+            style="@style/Card"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_margin="@dimen/spacing_tiny">
+
+            <TextView
+                android:id="@+id/event_creation_title"
+                style="@style/headline6"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="Event Creation Onboarding"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent" />
+
+            <com.google.android.material.switchmaterial.SwitchMaterial
+                android:id="@+id/switch_attendee_onboarding"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/spacing_small"
+                android:text="Attendee onboarding finished"
+                app:layout_constraintTop_toBottomOf="@id/event_creation_title" />
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
     </LinearLayout>
 </androidx.core.widget.NestedScrollView>
diff --git a/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_eventregistration.xml b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_presence_tracing.xml
similarity index 99%
rename from Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_eventregistration.xml
rename to Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_presence_tracing.xml
index 1e4441e000d99e3810c34fcc01a9b9c9c4dd31ff..dba2acc1b028e69527c54e05b6eb93271f194782 100644
--- a/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_eventregistration.xml
+++ b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_presence_tracing.xml
@@ -16,6 +16,7 @@
             style="@style/Card"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
             android:layout_marginHorizontal="@dimen/spacing_tiny"
             android:orientation="vertical">
 
diff --git a/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_qr_code_poster.xml b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_qr_code_poster.xml
new file mode 100644
index 0000000000000000000000000000000000000000..590b0a48c28bc6f1771a2a1063778e0c93b67f41
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/res/layout/fragment_test_qr_code_poster.xml
@@ -0,0 +1,277 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:ignore="HardcodedText">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@android:color/white">
+
+        <com.google.android.material.appbar.MaterialToolbar
+            android:id="@+id/toolbar"
+            style="@style/CWAToolbar.BackArrow"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:elevation="2dp"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:menu="@menu/menu_trace_location_qr_code_poster"
+            app:title="@string/trace_location_organiser_poster_title" />
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/qr_code_poster"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/toolbar">
+
+            <ImageView
+                android:id="@+id/poster_image"
+                android:layout_width="0dp"
+                android:layout_height="0dp"
+                android:adjustViewBounds="true"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent"
+                tools:layout_constraintDimensionRatio="595:841" />
+
+            <ImageView
+                android:id="@+id/qr_code_image"
+                android:layout_width="0dp"
+                android:layout_height="0dp"
+                android:scaleType="fitXY"
+                app:layout_constraintDimensionRatio="1:1"
+                app:layout_constraintEnd_toEndOf="@id/end_guideline"
+                app:layout_constraintStart_toStartOf="@id/start_guideline"
+                app:layout_constraintTop_toTopOf="@id/top_guideline"
+                tools:src="@drawable/ic_qrcode"
+                tools:tint="@android:color/black" />
+
+            <androidx.constraintlayout.widget.Guideline
+                android:id="@+id/start_guideline"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                app:layout_constraintGuide_percent="0.16" />
+
+            <androidx.constraintlayout.widget.Guideline
+                android:id="@+id/end_guideline"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                app:layout_constraintGuide_percent="0.84" />
+
+            <androidx.constraintlayout.widget.Guideline
+                android:id="@+id/top_guideline"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                app:layout_constraintGuide_percent="0.095" />
+
+            <androidx.constraintlayout.widget.Guideline
+                android:id="@+id/text_start_guideline"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                app:layout_constraintGuide_percent="0.132" />
+
+            <androidx.constraintlayout.widget.Guideline
+                android:id="@+id/text_end_guideline"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                app:layout_constraintGuide_percent="0.87" />
+
+            <androidx.constraintlayout.widget.Guideline
+                android:id="@+id/text_top_guideline"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                app:layout_constraintGuide_percent="0.61" />
+
+            <TextView
+                android:id="@+id/info_text_view"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:maxLines="2"
+                app:layout_constraintEnd_toEndOf="@id/text_end_guideline"
+                app:layout_constraintStart_toStartOf="@id/text_start_guideline"
+                app:layout_constraintTop_toTopOf="@id/text_top_guideline"
+                tools:ignore="SmallSp"
+                tools:text="Vereinsaktivität: Jahrestreffen der deutschen SAP Anwendergruppe\nHauptstr 3, 69115 Heidelberg"
+                tools:textColor="#000000"
+                tools:textSize="10sp" />
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+        <com.google.android.material.progressindicator.LinearProgressIndicator
+            android:id="@+id/progress_bar"
+            android:layout_width="150dp"
+            android:layout_height="wrap_content"
+            android:indeterminate="true"
+            app:hideAnimationBehavior="inward"
+            app:indicatorColor="@color/colorAccent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <ScrollView
+        android:id="@+id/offsets_panel"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        app:behavior_peekHeight="60dp"
+        app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
+
+        <LinearLayout
+            style="@style/Card"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+
+            <FrameLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginBottom="10dp"
+                android:orientation="horizontal"
+                android:paddingBottom="20dp">
+
+                <ImageView
+                    android:id="@+id/tooltip"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="end|center"
+                    android:background="?selectableItemBackgroundBorderless"
+                    app:srcCompat="@drawable/ic_info" />
+
+                <View
+                    android:layout_width="100dp"
+                    android:layout_height="5dp"
+                    android:layout_gravity="center"
+                    android:background="@color/colorAccent" />
+
+            </FrameLayout>
+
+            <TextView
+                android:id="@+id/qr_code_offsets"
+                style="@style/body2"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="QR Code offsets" />
+
+            <com.google.android.material.slider.Slider
+                android:id="@+id/qrOffsetXSlider"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginVertical="5dp"
+                android:stepSize="1"
+                android:valueFrom="0"
+                android:valueTo="1000"
+                app:labelBehavior="gone" />
+
+            <com.google.android.material.slider.Slider
+                android:id="@+id/qrOffsetYSlider"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginVertical="5dp"
+                android:stepSize="1"
+                android:valueFrom="0"
+                android:valueTo="1000"
+                app:labelBehavior="gone" />
+
+            <TextView
+                android:id="@+id/qr_code_length"
+                style="@style/body2"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:text="Qr Code length" />
+
+            <com.google.android.material.slider.Slider
+                android:id="@+id/qrLengthSlider"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginVertical="5dp"
+                android:stepSize="100"
+                android:valueFrom="500"
+                android:valueTo="2000"
+                app:labelBehavior="gone" />
+
+            <View
+                android:layout_width="match_parent"
+                android:layout_height="5dp"
+                android:layout_marginVertical="10dp"
+                android:background="#BE818181" />
+
+            <TextView
+                android:id="@+id/info_text_offsets"
+                style="@style/body2"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:text="Text offsets" />
+
+            <com.google.android.material.slider.Slider
+                android:id="@+id/txtOffsetXSlider"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginVertical="5dp"
+                android:stepSize="1"
+                android:valueFrom="0"
+                android:valueTo="1000"
+                app:labelBehavior="gone" />
+
+            <com.google.android.material.slider.Slider
+                android:id="@+id/txtOffsetYSlider"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginVertical="5dp"
+                android:stepSize="1"
+                android:valueFrom="0"
+                android:valueTo="1000"
+                app:labelBehavior="gone" />
+
+            <TextView
+                android:id="@+id/info_text_size"
+                style="@style/body2"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:text="Font size" />
+
+            <com.google.android.material.slider.Slider
+                android:id="@+id/infoTextSizeSlider"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginVertical="5dp"
+                android:stepSize="1"
+                android:valueFrom="10"
+                android:valueTo="30"
+                app:labelBehavior="gone" />
+
+            <TextView
+                style="@style/body2"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:text="Font Color" />
+
+            <com.google.android.material.textfield.TextInputEditText
+                android:id="@+id/info_text_color_value"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginVertical="5dp"
+                android:hint="#000000 - FallbackColor=#000000" />
+        </LinearLayout>
+    </ScrollView>
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/deviceForTesters/res/navigation/test_nav_graph.xml b/Corona-Warn-App/src/deviceForTesters/res/navigation/test_nav_graph.xml
index 1586ca6972c5d45da2f811603c2bce38e0fcf812..a8cdc52cfa9795a8acb3cced1acab554f81ed1d9 100644
--- a/Corona-Warn-App/src/deviceForTesters/res/navigation/test_nav_graph.xml
+++ b/Corona-Warn-App/src/deviceForTesters/res/navigation/test_nav_graph.xml
@@ -47,8 +47,8 @@
             android:id="@+id/action_test_menu_fragment_to_deltaonboardingFragment"
             app:destination="@id/test_deltaonboarding_fragment" />
         <action
-            android:id="@+id/action_test_menu_fragment_to_eventRegistrationTestFragment"
-            app:destination="@id/eventRegistrationTestFragment" />
+            android:id="@+id/action_test_menu_fragment_to_presenceTracingTestFragment"
+            app:destination="@id/presenceTracingTestFragment" />
     </fragment>
 
     <fragment
@@ -128,19 +128,19 @@
         android:label="DeltaonboardingFragment"
         tools:layout="@layout/fragment_test_deltaonboarding" />
     <fragment
-        android:id="@+id/eventRegistrationTestFragment"
-        android:name="de.rki.coronawarnapp.test.eventregistration.ui.EventRegistrationTestFragment"
-        android:label="EventRegistrationTestFragment"
-        tools:layout="@layout/fragment_test_eventregistration">
+        android:id="@+id/presenceTracingTestFragment"
+        android:name="de.rki.coronawarnapp.test.presencetracing.ui.PresenceTracingTestFragment"
+        android:label="PresenceTracingTestFragment"
+        tools:layout="@layout/fragment_test_presence_tracing">
         <action
-            android:id="@+id/action_eventRegistrationTestFragment_to_qrCodePosterFragmentTest"
-            app:destination="@id/qrCodePosterFragmentTest" />
+            android:id="@+id/action_presenceTracingTestFragment_to_qrCodePosterTestFragment"
+            app:destination="@id/qrCodePosterTestFragment" />
     </fragment>
     <fragment
-        android:id="@+id/qrCodePosterFragmentTest"
-        android:name="de.rki.coronawarnapp.ui.eventregistration.organizer.poster.QrCodePosterFragment"
-        android:label="qr_code_poster_fragment"
-        tools:layout="@layout/qr_code_poster_fragment">
+        android:id="@+id/qrCodePosterTestFragment"
+        android:name="de.rki.coronawarnapp.test.presencetracing.ui.poster.QrCodePosterTestFragment"
+        android:label="QrCodePosterTestFragment"
+        tools:layout="@layout/fragment_test_qr_code_poster">
 
         <argument
             android:name="traceLocationId"
diff --git a/Corona-Warn-App/src/main/AndroidManifest.xml b/Corona-Warn-App/src/main/AndroidManifest.xml
index 2cefbd599e3a740713e55a733c3b04b38949d234..4ff4927e20f6d0a5aec02068692448d34c55e148 100644
--- a/Corona-Warn-App/src/main/AndroidManifest.xml
+++ b/Corona-Warn-App/src/main/AndroidManifest.xml
@@ -77,7 +77,7 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
 
-            <intent-filter>
+            <intent-filter android:autoVerify="true">
                 <action android:name="android.intent.action.VIEW" />
 
                 <category android:name="android.intent.category.DEFAULT" />
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryLocation.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryLocation.kt
index e0486049d69e35824cd324a64bdf7ae6a2772472..020bb3f955ec83abfa6992437d69db66c1f4a7bf 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryLocation.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryLocation.kt
@@ -1,5 +1,6 @@
 package de.rki.coronawarnapp.contactdiary.model
 
+import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocationId
 import de.rki.coronawarnapp.util.lists.HasStableId
 import java.util.Locale
 
@@ -8,7 +9,7 @@ interface ContactDiaryLocation : HasStableId {
     var locationName: String
     val phoneNumber: String?
     val emailAddress: String?
-    val traceLocationID: String?
+    val traceLocationID: TraceLocationId?
 }
 
 fun List<ContactDiaryLocation>.sortByNameAndIdASC(): List<ContactDiaryLocation> =
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryLocation.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryLocation.kt
index c121e261124362fec889e560780bd48608339fa2..9ebd6f415d6f0ac8a6d5045215f9d776dc763445 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryLocation.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryLocation.kt
@@ -1,11 +1,13 @@
 package de.rki.coronawarnapp.contactdiary.model
 
+import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocationId
+
 data class DefaultContactDiaryLocation(
     override val locationId: Long = 0L,
     override var locationName: String,
     override val phoneNumber: String? = null,
     override val emailAddress: String? = null,
-    override val traceLocationID: String? = null
+    override val traceLocationID: TraceLocationId? = null
 ) : ContactDiaryLocation {
     override val stableId: Long
         get() = locationId
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationEntity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationEntity.kt
index b09a84c8fb451d495de68e89deaed270168dc704..ba4f25464b0caf198370cd9ad539d02f6e25e840 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationEntity.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationEntity.kt
@@ -5,6 +5,7 @@ import androidx.room.ColumnInfo
 import androidx.room.Entity
 import androidx.room.PrimaryKey
 import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocation
+import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocationId
 import de.rki.coronawarnapp.util.trimToLength
 import kotlinx.parcelize.Parcelize
 
@@ -15,7 +16,7 @@ data class ContactDiaryLocationEntity(
     @ColumnInfo(name = "locationName") override var locationName: String,
     override val phoneNumber: String?,
     override val emailAddress: String?,
-    @ColumnInfo(name = "traceLocationID") override val traceLocationID: String?
+    @ColumnInfo(name = "traceLocationID") override val traceLocationID: TraceLocationId?
 ) : ContactDiaryLocation, Parcelable {
     override val stableId: Long
         get() = locationId
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt
index bb81b52052a6ab2d2583276dd2bb9046d4b162f9..09ca3ef2e455fa1e4ed4e540ad7feea2773f5f08 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt
@@ -60,7 +60,7 @@ class ContactDiaryOverviewViewModel @AssistedInject constructor(
 
     private val riskLevelPerDateFlow = riskLevelStorage.ewDayRiskStates
     private val traceLocationCheckInRiskFlow = riskLevelStorage.traceLocationCheckInRiskStates
-    private val allCheckInsFlow = checkInRepository.allCheckIns
+    private val checkInsWithinRetentionFlow = checkInRepository.checkInsWithinRetention
 
     val listItems = combine(
         flowOf(dates),
@@ -68,7 +68,7 @@ class ContactDiaryOverviewViewModel @AssistedInject constructor(
         personEncountersFlow,
         riskLevelPerDateFlow,
         traceLocationCheckInRiskFlow,
-        allCheckInsFlow
+        checkInsWithinRetentionFlow
     ) { dateList, locationVisists, personEncounters, riskLevelPerDateList, traceLocationCheckInRiskList, checkInList ->
         mutableListOf<DiaryOverviewItem>().apply {
             add(OverviewSubHeaderItem)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/safetynet/AttestationContainer.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/safetynet/AttestationContainer.kt
index dcf91e1f6f93e69204fb752aacc52d38168133aa..c0d63aa1750ad9f55db3913d85c47c95356ff99b 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/safetynet/AttestationContainer.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/safetynet/AttestationContainer.kt
@@ -16,31 +16,31 @@ internal data class AttestationContainer(
             safetyNetJws = report.jwsResult
         }.build()
 
-    override fun requirePass(reqs: SafetyNetRequirements) {
-        Timber.v("requirePass(%s)", reqs)
+    override fun requirePass(requirements: SafetyNetRequirements) {
+        Timber.v("requirePass(%s)", requirements)
 
-        if (reqs.requireBasicIntegrity && !report.basicIntegrity) {
+        if (requirements.requireBasicIntegrity && !report.basicIntegrity) {
             throw SafetyNetException(
                 Type.BASIC_INTEGRITY_REQUIRED,
                 "Requirement 'basicIntegrity' not met (${report.advice})."
             )
         }
 
-        if (reqs.requireCTSProfileMatch && !report.ctsProfileMatch) {
+        if (requirements.requireCTSProfileMatch && !report.ctsProfileMatch) {
             throw SafetyNetException(
                 Type.CTS_PROFILE_MATCH_REQUIRED,
                 "Requirement 'ctsProfileMatch' not met (${report.advice})."
             )
         }
 
-        if (reqs.requireBasicIntegrity && !report.evaluationTypes.contains("BASIC")) {
+        if (requirements.requireBasicIntegrity && !report.evaluationTypes.contains("BASIC")) {
             throw SafetyNetException(
                 Type.EVALUATION_TYPE_BASIC_REQUIRED,
                 "Evaluation type 'BASIC' not met (${report.advice})."
             )
         }
 
-        if (reqs.requireEvaluationTypeHardwareBacked && !report.evaluationTypes.contains("HARDWARE_BACKED")) {
+        if (requirements.requireEvaluationTypeHardwareBacked && !report.evaluationTypes.contains("HARDWARE_BACKED")) {
             throw SafetyNetException(
                 Type.EVALUATION_TYPE_HARDWARE_BACKED_REQUIRED,
                 "Evaluation type 'HARDWARE_BACKED' not met (${report.advice})."
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckIn.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckIn.kt
index 1f755923ad63b8c50438a965499c63fd4c005fda..8fea0b27af22d976d99d8a73a5c379cedd6759ea 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckIn.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckIn.kt
@@ -22,7 +22,8 @@ data class CheckIn(
     val checkInStart: Instant,
     val checkInEnd: Instant,
     val completed: Boolean,
-    val createJournalEntry: Boolean
+    val createJournalEntry: Boolean,
+    val isSubmitted: Boolean = false,
 ) {
     /**
      *  Returns SHA-256 hash of [traceLocationId] which itself may also be SHA-256 hash.
@@ -48,5 +49,6 @@ fun CheckIn.toEntity() = TraceLocationCheckInEntity(
     checkInStart = checkInStart,
     checkInEnd = checkInEnd,
     completed = completed,
-    createJournalEntry = createJournalEntry
+    createJournalEntry = createJournalEntry,
+    isSubmitted = isSubmitted,
 )
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepository.kt
index 3420d4832fce1f9b0765ef075c018eba0d047391..ea9d8b74b00d24032a7f341d41e7d0eee5f9df84 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepository.kt
@@ -2,7 +2,9 @@ package de.rki.coronawarnapp.eventregistration.checkins
 
 import de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase
 import de.rki.coronawarnapp.eventregistration.storage.dao.CheckInDao
+import de.rki.coronawarnapp.eventregistration.storage.entity.TraceLocationCheckInEntity
 import de.rki.coronawarnapp.eventregistration.storage.entity.toCheckIn
+import de.rki.coronawarnapp.util.TimeStamper
 import kotlinx.coroutines.NonCancellable
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.map
@@ -13,7 +15,8 @@ import javax.inject.Singleton
 
 @Singleton
 class CheckInRepository @Inject constructor(
-    traceLocationDatabaseFactory: TraceLocationDatabase.Factory
+    traceLocationDatabaseFactory: TraceLocationDatabase.Factory,
+    private val timeStamper: TimeStamper
 ) {
 
     private val traceLocationDatabase: TraceLocationDatabase by lazy {
@@ -24,10 +27,27 @@ class CheckInRepository @Inject constructor(
         traceLocationDatabase.eventCheckInDao()
     }
 
+    /**
+     * Returns all stored check-ins
+     *
+     * Attention: this could also include check-ins that are older than
+     * the retention period. Therefore, you should probably use [checkInsWithinRetention]
+     */
     val allCheckIns: Flow<List<CheckIn>> = checkInDao
         .allEntries()
         .map { list -> list.map { it.toCheckIn() } }
 
+    /**
+     * Returns check-ins that are within the retention period. Even though we have a worker that deletes all stale
+     * check-ins it's still possible to have stale check-ins in the database because the worker only runs once a day.
+     */
+    val checkInsWithinRetention: Flow<List<CheckIn>> = allCheckIns.map { checkInList ->
+        val now = timeStamper.nowUTC
+        checkInList.filter { checkIn ->
+            checkIn.isWithinRetention(now)
+        }
+    }
+
     suspend fun getCheckInById(checkInId: Long): CheckIn? {
         Timber.d("getCheckInById(checkInId=$checkInId)")
         return checkInDao.entryForId(checkInId)?.toCheckIn()
@@ -45,6 +65,13 @@ class CheckInRepository @Inject constructor(
         checkInDao.updateEntityById(checkInId, update)
     }
 
+    suspend fun markCheckInAsSubmitted(checkInId: Long) {
+        Timber.d("markCheckInAsSubmitted(checkInId=$checkInId)")
+        checkInDao.updateEntity(
+            TraceLocationCheckInEntity.SubmissionUpdate(checkInId = checkInId, isSubmitted = true)
+        )
+    }
+
     suspend fun deleteCheckIns(checkIns: Collection<CheckIn>) = withContext(NonCancellable) {
         Timber.d("deleteCheckIns(checkIns=%s)", checkIns)
         checkInDao.deleteByIds(checkIns.map { it.id })
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRetention.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRetention.kt
new file mode 100644
index 0000000000000000000000000000000000000000..875612a2a0b00a6512964fb347a1d956b245e997
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRetention.kt
@@ -0,0 +1,21 @@
+package de.rki.coronawarnapp.eventregistration.checkins
+
+import de.rki.coronawarnapp.util.TimeAndDateExtensions.seconds
+import org.joda.time.Instant
+import java.util.concurrent.TimeUnit
+
+private const val CHECK_IN_RETENTION_DAYS = 15
+private val CHECK_IN_RETENTION_SECONDS = TimeUnit.DAYS.toSeconds(CHECK_IN_RETENTION_DAYS.toLong())
+
+/**
+ * returns true if the end date of the check-in isn't older than [CHECK_IN_RETENTION_DAYS], otherwise false
+ */
+fun CheckIn.isWithinRetention(now: Instant): Boolean {
+    val retentionThreshold = (now.seconds - CHECK_IN_RETENTION_SECONDS)
+    return checkInEnd.seconds >= retentionThreshold
+}
+
+/**
+ * Returns true if a check-in is stale and therefore can be deleted, otherwise false
+ */
+fun CheckIn.isOutOfRetention(now: Instant) = !isWithinRetention(now)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/DefaultAutoCheckoutLength.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/DefaultAutoCheckoutLength.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0f5c0d6dfa510bfbc46a452678702c0947a39304
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/DefaultAutoCheckoutLength.kt
@@ -0,0 +1,74 @@
+package de.rki.coronawarnapp.eventregistration.checkins.qrcode
+
+import androidx.annotation.VisibleForTesting
+import org.joda.time.Duration
+import org.joda.time.Instant
+import java.util.concurrent.TimeUnit
+import kotlin.math.roundToLong
+
+/**
+ * Evaluates the default auto-checkout length depending on the current time
+ */
+@Suppress("ReturnCount")
+fun TraceLocation.getDefaultAutoCheckoutLengthInMinutes(now: Instant): Int {
+
+    // min valid value is 00:15h
+    val minDefaultAutoCheckOutLengthInMinutes = 15
+
+    // max valid value is 23:45h
+    val maxDefaultAutoCheckOutLengthInMinutes = (TimeUnit.HOURS.toMinutes(23) + 45).toInt()
+
+    // for permanent traceLocations, a defaultCheckInLength is always available
+    if (defaultCheckInLengthInMinutes != null) {
+
+        if (defaultCheckInLengthInMinutes < 15) {
+            return minDefaultAutoCheckOutLengthInMinutes
+        }
+
+        if (defaultCheckInLengthInMinutes > maxDefaultAutoCheckOutLengthInMinutes) {
+            return maxDefaultAutoCheckOutLengthInMinutes
+        }
+
+        return roundToNearest15Minutes(defaultCheckInLengthInMinutes)
+    }
+    // for temporary traceLocations, the defaultCheckInLength could be empty
+    else {
+
+        // For QR-codes generated by CWA, endDate can never be null here. However, a QR code that was created or
+        // modified by a third party could have an endDate that is null.
+        if (endDate == null) {
+            return minDefaultAutoCheckOutLengthInMinutes
+        }
+
+        if (now.isAfter(endDate)) {
+            return minDefaultAutoCheckOutLengthInMinutes
+        }
+
+        val minutesUntilEndDate = Duration(now, endDate).standardMinutes.toInt()
+
+        if (minutesUntilEndDate < minDefaultAutoCheckOutLengthInMinutes) {
+            return minDefaultAutoCheckOutLengthInMinutes
+        }
+
+        if (minutesUntilEndDate > maxDefaultAutoCheckOutLengthInMinutes) {
+            return maxDefaultAutoCheckOutLengthInMinutes
+        }
+
+        return roundToNearest15Minutes(minutesUntilEndDate)
+    }
+}
+
+/**
+ * Rounds to the nearest 15 minute interval.
+ * for more details see AutoCheckoutHelperTest
+ */
+@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+fun roundToNearest15Minutes(minutes: Int): Int {
+    val roundingStepInMinutes = 15
+    return Duration
+        .standardMinutes(
+            (minutes.toFloat() / roundingStepInMinutes)
+                .roundToLong() * roundingStepInMinutes
+        )
+        .standardMinutes.toInt()
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/dao/CheckInDao.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/dao/CheckInDao.kt
index b45d75d1b09df3dd21f4967411f32e9e4f8c7ef4..56ed45b2abe1f75be100a40cb3f8160b840571cf 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/dao/CheckInDao.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/dao/CheckInDao.kt
@@ -37,6 +37,9 @@ interface CheckInDao {
         update(updated)
     }
 
+    @Update(entity = TraceLocationCheckInEntity::class)
+    suspend fun updateEntity(update: TraceLocationCheckInEntity.SubmissionUpdate)
+
     @Query("DELETE FROM checkin")
     suspend fun deleteAll()
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationCheckInEntity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationCheckInEntity.kt
index 2616685c8a0a15690dc2aa1d472b806d31b1019e..8ddcadd2a8b811cfae2b987771a001582c2c8bb0 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationCheckInEntity.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationCheckInEntity.kt
@@ -23,8 +23,16 @@ data class TraceLocationCheckInEntity(
     @ColumnInfo(name = "checkInStart") val checkInStart: Instant,
     @ColumnInfo(name = "checkInEnd") val checkInEnd: Instant,
     @ColumnInfo(name = "completed") val completed: Boolean,
-    @ColumnInfo(name = "createJournalEntry") val createJournalEntry: Boolean
-)
+    @ColumnInfo(name = "createJournalEntry") val createJournalEntry: Boolean,
+    @ColumnInfo(name = "submitted") val isSubmitted: Boolean,
+) {
+
+    @Entity
+    data class SubmissionUpdate(
+        @PrimaryKey @ColumnInfo(name = "id") val checkInId: Long,
+        @ColumnInfo(name = "submitted") val isSubmitted: Boolean,
+    )
+}
 
 fun TraceLocationCheckInEntity.toCheckIn() = CheckIn(
     id = id,
@@ -41,5 +49,6 @@ fun TraceLocationCheckInEntity.toCheckIn() = CheckIn(
     checkInStart = checkInStart,
     checkInEnd = checkInEnd,
     completed = completed,
-    createJournalEntry = createJournalEntry
+    createJournalEntry = createJournalEntry,
+    isSubmitted = isSubmitted
 )
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/repo/DefaultTraceLocationRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/repo/DefaultTraceLocationRepository.kt
index 46a93d873b0be3f72c3247e14814f260ba93723d..b0c5f879dcdd3c5af499bdcce2593283cddef3db 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/repo/DefaultTraceLocationRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/repo/DefaultTraceLocationRepository.kt
@@ -6,6 +6,8 @@ import de.rki.coronawarnapp.eventregistration.checkins.qrcode.toTraceLocations
 import de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase
 import de.rki.coronawarnapp.eventregistration.storage.dao.TraceLocationDao
 import de.rki.coronawarnapp.eventregistration.storage.entity.toTraceLocationEntity
+import de.rki.coronawarnapp.eventregistration.storage.retention.isWithinRetention
+import de.rki.coronawarnapp.util.TimeStamper
 import de.rki.coronawarnapp.util.coroutine.AppScope
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
@@ -18,7 +20,8 @@ import javax.inject.Singleton
 @Singleton
 class DefaultTraceLocationRepository @Inject constructor(
     traceLocationDatabaseFactory: TraceLocationDatabase.Factory,
-    @AppScope private val appScope: CoroutineScope
+    @AppScope private val appScope: CoroutineScope,
+    private val timeStamper: TimeStamper
 ) : TraceLocationRepository {
 
     private val traceLocationDatabase: TraceLocationDatabase by lazy {
@@ -29,16 +32,39 @@ class DefaultTraceLocationRepository @Inject constructor(
         traceLocationDatabase.traceLocationDao()
     }
 
+    /**
+     * Reruns [TraceLocation] for [id]
+     * @throws [IllegalArgumentException] if location not found
+     */
     override suspend fun traceLocationForId(id: Long): TraceLocation {
-        val checkIn = traceLocationDao.entryForId(id)
+        val traceLocationEntity = traceLocationDao.entryForId(id)
             ?: throw IllegalArgumentException("No traceLocation found for ID=$id")
 
-        return checkIn.toTraceLocation()
+        return traceLocationEntity.toTraceLocation()
     }
 
+    /**
+     * Returns all stored trace locations
+     *
+     * Attention: this could also include trace locations that are older than
+     * the retention period. Therefore, you should probably use [traceLocationsWithinRetention]
+     */
     override val allTraceLocations: Flow<List<TraceLocation>>
         get() = traceLocationDao.allEntries().map { it.toTraceLocations() }
 
+    /**
+     * Returns trace locations that are within the retention period. Even though we have a worker that deletes all stale
+     * trace locations it's still possible to have stale trace-locations in the database because the worker only runs
+     * once a day.
+     */
+    override val traceLocationsWithinRetention: Flow<List<TraceLocation>>
+        get() = allTraceLocations.map { traceLocationList ->
+            val now = timeStamper.nowUTC
+            traceLocationList.filter { traceLocation ->
+                traceLocation.isWithinRetention(now)
+            }
+        }
+
     override suspend fun addTraceLocation(traceLocation: TraceLocation): TraceLocation {
         Timber.d("Add trace location: %s", traceLocation)
         val traceLocationEntity = traceLocation.toTraceLocationEntity()
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/repo/TraceLocationRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/repo/TraceLocationRepository.kt
index 8baafc528adfbb6197519b26f96d5958c45a1655..df566a3cc3b8c982984871cfb3c2451fad3dc63d 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/repo/TraceLocationRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/repo/TraceLocationRepository.kt
@@ -5,8 +5,21 @@ import kotlinx.coroutines.flow.Flow
 
 interface TraceLocationRepository {
 
+    /**
+     * Returns all stored trace locations
+     *
+     * Attention: this could also include trace locations that are older than
+     * the retention period. Therefore, you should probably use [traceLocationsWithinRetention]
+     */
     val allTraceLocations: Flow<List<TraceLocation>>
 
+    /**
+     * Returns trace locations that are within the retention period. Even though we have a worker that deletes all stale
+     * trace locations it's still possible to have stale trace-locations in the database because the worker only runs
+     * once a day.
+     */
+    val traceLocationsWithinRetention: Flow<List<TraceLocation>>
+
     suspend fun traceLocationForId(id: Long): TraceLocation
 
     suspend fun addTraceLocation(traceLocation: TraceLocation): TraceLocation
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/retention/CheckInCleaner.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/retention/CheckInCleaner.kt
index b40efe4887783d16930c261fb140c8b68b226bb3..af5e3f80a39252d0c07ccce930c0d8f968a3e092 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/retention/CheckInCleaner.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/retention/CheckInCleaner.kt
@@ -2,11 +2,10 @@ package de.rki.coronawarnapp.eventregistration.storage.retention
 
 import dagger.Reusable
 import de.rki.coronawarnapp.eventregistration.checkins.CheckInRepository
-import de.rki.coronawarnapp.util.TimeAndDateExtensions.seconds
+import de.rki.coronawarnapp.eventregistration.checkins.isOutOfRetention
 import de.rki.coronawarnapp.util.TimeStamper
 import kotlinx.coroutines.flow.first
 import timber.log.Timber
-import java.util.concurrent.TimeUnit
 import javax.inject.Inject
 
 @Reusable
@@ -17,18 +16,15 @@ class CheckInCleaner @Inject constructor(
 
     suspend fun cleanUp() {
         Timber.d("Starting to clean up stale check-ins.")
-        val retentionThreshold = (timeStamper.nowUTC.seconds - RETENTION_SECONDS)
+
+        val now = timeStamper.nowUTC
         val checkInsToDelete = checkInRepository.allCheckIns.first()
-            .filter {
-                it.checkInEnd.seconds < retentionThreshold
-            }
+            .filter { checkIn -> checkIn.isOutOfRetention(now) }
+
         Timber.d("Cleaning up ${checkInsToDelete.size} stale check-ins.")
+
         checkInRepository.deleteCheckIns(checkInsToDelete)
-        Timber.d("Clean up of stale check-ins completed.")
-    }
 
-    companion object {
-        private const val RETENTION_DAYS = 15
-        private val RETENTION_SECONDS = TimeUnit.DAYS.toSeconds(RETENTION_DAYS.toLong())
+        Timber.d("Clean up of stale check-ins completed.")
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/retention/TraceLocationCleaner.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/retention/TraceLocationCleaner.kt
index 6f73ddbf786282539650e6fdbf8cee3d7e74305a..69fac1678fb37a4bce0e309561003d1b68d44c36 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/retention/TraceLocationCleaner.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/retention/TraceLocationCleaner.kt
@@ -2,11 +2,9 @@ package de.rki.coronawarnapp.eventregistration.storage.retention
 
 import dagger.Reusable
 import de.rki.coronawarnapp.eventregistration.storage.repo.TraceLocationRepository
-import de.rki.coronawarnapp.util.TimeAndDateExtensions.seconds
 import de.rki.coronawarnapp.util.TimeStamper
 import kotlinx.coroutines.flow.first
 import timber.log.Timber
-import java.util.concurrent.TimeUnit
 import javax.inject.Inject
 
 @Reusable
@@ -17,19 +15,16 @@ class TraceLocationCleaner @Inject constructor(
 
     suspend fun cleanUp() {
         Timber.d("Starting to clean up stale trace locations.")
-        val retentionThreshold = (timeStamper.nowUTC.seconds - RETENTION_SECONDS)
+
+        val now = timeStamper.nowUTC
         traceLocationRepository.allTraceLocations.first()
-            .filter {
-                it.endDate != null && it.endDate.seconds < retentionThreshold
+            .filter { traceLocation ->
+                traceLocation.isOutOfRetention(now)
             }.forEach {
                 Timber.d("Cleaning up stale trace location: %s", it)
                 traceLocationRepository.deleteTraceLocation(it)
             }
-        Timber.d("Clean up of stale trace locations completed.")
-    }
 
-    companion object {
-        private const val RETENTION_DAYS = 15
-        private val RETENTION_SECONDS = TimeUnit.DAYS.toSeconds(RETENTION_DAYS.toLong())
+        Timber.d("Clean up of stale trace locations completed.")
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/retention/TraceLocationRetention.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/retention/TraceLocationRetention.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b1c854e7f974551e34505eb05c1757e7c1cabdf8
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/retention/TraceLocationRetention.kt
@@ -0,0 +1,27 @@
+package de.rki.coronawarnapp.eventregistration.storage.retention
+
+import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocation
+import de.rki.coronawarnapp.util.TimeAndDateExtensions.seconds
+import org.joda.time.Instant
+import java.util.concurrent.TimeUnit
+
+private const val TRACE_LOCATION_RETENTION_DAYS = 15
+private val TRACE_LOCATION_RETENTION_SECONDS = TimeUnit.DAYS.toSeconds(TRACE_LOCATION_RETENTION_DAYS.toLong())
+
+/**
+ * returns true if a trace location either has no end date or has an end date that isn't older than
+ * [TRACE_LOCATION_RETENTION_DAYS], otherwise false
+ */
+fun TraceLocation.isWithinRetention(now: Instant): Boolean {
+    val retentionThreshold = (now.seconds - TRACE_LOCATION_RETENTION_SECONDS)
+    return if (endDate == null) {
+        true
+    } else {
+        endDate.seconds >= retentionThreshold
+    }
+}
+
+/**
+ * Returns true if a trace location is stale and therefore can be deleted, otherwise false
+ */
+fun TraceLocation.isOutOfRetention(now: Instant) = !isWithinRetention(now)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/TestResultAvailableNotificationService.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/TestResultAvailableNotificationService.kt
index 2c17160e7eabb7fbd73ed80a5502d416d4caa742..a6d942933d7aa3a595e3e5efa3a69d00337a53db 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/TestResultAvailableNotificationService.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/TestResultAvailableNotificationService.kt
@@ -23,7 +23,12 @@ class TestResultAvailableNotificationService @Inject constructor(
 ) {
 
     suspend fun showTestResultAvailableNotification(testResult: TestResult) {
-        if (foregroundState.isInForeground.first()) return
+        Timber.d("showTestResultAvailableNotification(testResult=%s)", testResult)
+
+        if (foregroundState.isInForeground.first()) {
+            Timber.d("App in foreground, skipping notification.")
+            return
+        }
 
         if (!cwaSettings.isNotificationsTestEnabled.value) {
             Timber.i("Don't show test result available notification because user doesn't want to be informed")
@@ -42,6 +47,7 @@ class TestResultAvailableNotificationService @Inject constructor(
             setContentIntent(pendingIntent)
         }.build()
 
+        Timber.i("Showing TestResultAvailable notification!")
         notificationHelper.sendNotification(
             notificationId = NotificationConstants.TEST_RESULT_AVAILABLE_NOTIFICATION_ID,
             notification = notification,
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/CheckOutHandler.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/CheckOutHandler.kt
index 917e8c0eca407e43d98fd7cc1c3c96f8b4123e3c..4852be4a722be3c850ad18fbe2bc0784f1e9e668 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/CheckOutHandler.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/CheckOutHandler.kt
@@ -1,18 +1,18 @@
 package de.rki.coronawarnapp.presencetracing.checkins.checkout
 
-import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
+import dagger.Reusable
+import de.rki.coronawarnapp.eventregistration.checkins.CheckIn
 import de.rki.coronawarnapp.eventregistration.checkins.CheckInRepository
 import de.rki.coronawarnapp.util.TimeStamper
 import org.joda.time.Instant
 import timber.log.Timber
 import javax.inject.Inject
-import javax.inject.Singleton
 
-@Singleton
+@Reusable
 class CheckOutHandler @Inject constructor(
     private val repository: CheckInRepository,
     private val timeStamper: TimeStamper,
-    private val diaryRepository: ContactDiaryRepository,
+    private val contactJournalCheckInEntryCreator: ContactJournalCheckInEntryCreator
 ) {
     /**
      * Throw **[IllegalArgumentException]** if the check-in does not exist.
@@ -21,18 +21,16 @@ class CheckOutHandler @Inject constructor(
     suspend fun checkOut(checkInId: Long, checkOutAt: Instant = timeStamper.nowUTC) {
         Timber.d("checkOut(checkInId=$checkInId, checkOutAt=%s)", checkOutAt)
 
-        var createJournalEntry = false
+        var checkIn: CheckIn? = null
         repository.updateCheckIn(checkInId) {
-            createJournalEntry = it.createJournalEntry
             it.copy(
                 checkInEnd = checkOutAt,
                 completed = true
-            )
+            ).also { c -> checkIn = c }
         }
 
-        if (createJournalEntry) {
-            Timber.d("Creating journal entry for $checkInId")
-            // TODO Create journal entry
+        if (checkIn?.createJournalEntry == true) {
+            contactJournalCheckInEntryCreator.createEntry(checkIn!!)
         }
 
         // Remove auto-checkout timer?
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/ContactJournalCheckInEntryCreator.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/ContactJournalCheckInEntryCreator.kt
new file mode 100644
index 0000000000000000000000000000000000000000..e553c983471c6c5c523868b2bf95a80a760bf070
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/ContactJournalCheckInEntryCreator.kt
@@ -0,0 +1,104 @@
+package de.rki.coronawarnapp.presencetracing.checkins.checkout
+
+import androidx.annotation.VisibleForTesting
+import dagger.Reusable
+import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocation
+import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocationVisit
+import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryLocation
+import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryLocationVisit
+import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
+import de.rki.coronawarnapp.eventregistration.checkins.CheckIn
+import de.rki.coronawarnapp.eventregistration.checkins.split.splitByMidnightUTC
+import de.rki.coronawarnapp.util.TimeAndDateExtensions.toLocalDateUtc
+import de.rki.coronawarnapp.util.TimeAndDateExtensions.toUserTimeZone
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.firstOrNull
+import org.joda.time.Duration
+import org.joda.time.Seconds
+import org.joda.time.format.DateTimeFormat
+import timber.log.Timber
+import javax.inject.Inject
+import kotlin.math.roundToLong
+
+@Reusable
+class ContactJournalCheckInEntryCreator @Inject constructor(
+    private val diaryRepository: ContactDiaryRepository
+) {
+
+    suspend fun createEntry(checkIn: CheckIn) {
+        Timber.d("Creating journal entry for %s", checkIn)
+
+        // 1. Create location if missing
+        val location: ContactDiaryLocation = diaryRepository.locations.first()
+            .find { it.traceLocationID == checkIn.traceLocationId } ?: checkIn.toLocation()
+
+        // 2. Split CheckIn by Midnight UTC
+        val splitCheckIns = checkIn.splitByMidnightUTC()
+        Timber.d("Split %s into %s ", this, splitCheckIns)
+
+        // 3. Create LocationVisit if missing
+        splitCheckIns
+            .createMissingLocationVisits(location)
+            .forEach { diaryRepository.addLocationVisit(it) }
+    }
+
+    private suspend fun CheckIn.toLocation(): ContactDiaryLocation {
+        val location = DefaultContactDiaryLocation(
+            locationName = locationName(),
+            traceLocationID = traceLocationId
+        )
+        Timber.d("Created new location %s and adding it to contact journal db", location)
+        return diaryRepository.addLocation(location) // Get location from db cause we need the id autogenerated by db
+    }
+
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    fun CheckIn.locationName(): String {
+        val nameParts = mutableListOf(description, address)
+
+        if (traceLocationStart != null && traceLocationEnd != null) {
+            if (traceLocationStart.millis > 0 && traceLocationEnd.millis > 0) {
+                val formattedStartDate = traceLocationStart.toUserTimeZone().toString(DateTimeFormat.shortDateTime())
+                val formattedEndDate = traceLocationEnd.toUserTimeZone().toString(DateTimeFormat.shortDateTime())
+                nameParts.add("$formattedStartDate - $formattedEndDate")
+            }
+        }
+
+        return nameParts.joinToString(separator = ", ")
+    }
+
+    private fun CheckIn.toLocationVisit(location: ContactDiaryLocation): ContactDiaryLocationVisit {
+        // Use Seconds for more precision
+        val durationInMinutes = Seconds.secondsBetween(checkInStart, checkInEnd).seconds / 60.0
+        val duration = (durationInMinutes / 15).roundToLong() * 15
+        return DefaultContactDiaryLocationVisit(
+            date = checkInStart.toLocalDateUtc(),
+            contactDiaryLocation = location,
+            duration = Duration.standardMinutes(duration),
+            checkInID = id
+        )
+    }
+
+    private suspend fun List<CheckIn>.createMissingLocationVisits(location: ContactDiaryLocation):
+        List<ContactDiaryLocationVisit> {
+            Timber.d(
+                "createMissingLocationVisits(location=%s) for %s",
+                location,
+                this.joinToString(prefix = System.lineSeparator(), separator = System.lineSeparator())
+            )
+            val existingLocationVisits = diaryRepository.locationVisits.firstOrNull() ?: emptyList()
+            // Existing location visits shall not be updated, so just drop them
+            return filter {
+                existingLocationVisits.none { visit ->
+                    visit.date == it.checkInStart.toLocalDateUtc() &&
+                        visit.contactDiaryLocation.locationId == location.locationId
+                }
+            }
+                .map { it.toLocationVisit(location) }
+                .also {
+                    Timber.d(
+                        "Created locations visits: %s",
+                        it.joinToString(prefix = System.lineSeparator(), separator = System.lineSeparator())
+                    )
+                }
+        }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/auto/AutoCheckOut.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/auto/AutoCheckOut.kt
index 2a27ff6dbc40c3377b74805eb21b24a6ceee52e7..b0b8d2190fda0913ad902bdba9c00576c2d55c4f 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/auto/AutoCheckOut.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/auto/AutoCheckOut.kt
@@ -10,7 +10,6 @@ import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.firstOrNull
 import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.sync.Mutex
@@ -40,15 +39,10 @@ class AutoCheckOut @Inject constructor(
     fun setupMonitor() {
         repository.allCheckIns
             .onStart { Timber.tag(TAG).v("Monitoring check-ins.") }
-            .map { checkins ->
-                Timber.tag(TAG).v("CheckIns changed")
-                val completed = checkins.filter { it.completed }.map { it.id }
-                val notCompleted = checkins.filter { !it.completed }.map { it.id }
-                completed to notCompleted
-            }
             .distinctUntilChanged()
             .onEach {
-                Timber.tag(TAG).i("Check-in was added or removed, refreshing alarm.")
+                Timber.tag(TAG).i("Check-ins changed, checking for overdue items, refreshing alarm.")
+                processOverDueCheckouts()
                 refreshAlarm()
             }
             .launchIn(appScope)
@@ -93,7 +87,7 @@ class AutoCheckOut @Inject constructor(
             val nowUTC = timeStamper.nowUTC
             val snapshot = repository.allCheckIns.firstOrNull() ?: emptyList()
             snapshot
-                .filter { !it.completed && nowUTC.isAfter(it.checkInEnd) }
+                .filter { !it.completed && (nowUTC.isAfter(it.checkInEnd) || nowUTC.isEqual(it.checkInEnd)) }
                 .sortedBy { it.checkInEnd }
         }.also {
             Timber.tag(TAG).d("${it.size} checkins are overdue for auto checkout: %s", it)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/PtRiskLevelResult.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/PtRiskLevelResult.kt
index 62b25b76061904b9d6a11001752fdce79f8f3dda..541496f3bac86227cc1fe7204d8289961871def4 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/PtRiskLevelResult.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/PtRiskLevelResult.kt
@@ -1,15 +1,20 @@
 package de.rki.coronawarnapp.presencetracing.risk
 
+import de.rki.coronawarnapp.presencetracing.risk.calculation.CheckInWarningOverlap
 import de.rki.coronawarnapp.presencetracing.risk.calculation.PresenceTracingDayRisk
 import de.rki.coronawarnapp.risk.RiskState
 import org.joda.time.Instant
 import org.joda.time.LocalDate
 
+/**
+ * @param presenceTracingDayRisk Only available for the last calculation, if successful, otherwise null
+ * @param checkInWarningOverlaps Only available for the last calculation, if successful, otherwise null
+ */
 data class PtRiskLevelResult(
     val calculatedAt: Instant,
     val riskState: RiskState,
-    // only available for the last calculation if successful, otherwise null
-    val presenceTracingDayRisk: List<PresenceTracingDayRisk>? = null
+    val presenceTracingDayRisk: List<PresenceTracingDayRisk>? = null,
+    private val checkInWarningOverlaps: List<CheckInWarningOverlap>? = null,
 ) {
 
     val wasSuccessfullyCalculated: Boolean
@@ -39,4 +44,7 @@ data class PtRiskLevelResult(
             RiskState.LOW_RISK -> numberOfDaysWithLowRisk
             else -> 0
         }
+
+    val checkInOverlapCount: Int
+        get() = checkInWarningOverlaps?.size ?: 0
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/calculation/CheckInWarningMatcher.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/calculation/CheckInWarningMatcher.kt
index 8c318df97711ea7ca4108ee90bcce03a155b7540..530ebc138071c5f2d9dead90fb658c773a659339 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/calculation/CheckInWarningMatcher.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/calculation/CheckInWarningMatcher.kt
@@ -15,6 +15,7 @@ import kotlinx.coroutines.withContext
 import org.joda.time.Instant
 import timber.log.Timber
 import java.lang.reflect.Modifier.PRIVATE
+import java.util.concurrent.TimeUnit
 import javax.inject.Inject
 import kotlin.coroutines.CoroutineContext
 
@@ -25,6 +26,8 @@ class CheckInWarningMatcher @Inject constructor(
         checkIns: List<CheckIn>,
         warningPackages: List<TraceWarningPackage>
     ): Result {
+        Timber.tag(TAG).d("Processing ${checkIns.size} checkins and ${warningPackages.size} warning pkgs.")
+
         val splitCheckIns = checkIns.flatMap { it.splitByMidnightUTC() }
 
         val matchLists: List<List<MatchesPerPackage>?> = runMatchingLaunchers(
@@ -34,13 +37,12 @@ class CheckInWarningMatcher @Inject constructor(
         )
 
         val successful = if (matchLists.contains(null)) {
-            Timber.e("Calculation partially failed.")
+            Timber.tag(TAG).e("Calculation partially failed: %s", matchLists)
             false
         } else {
-            Timber.d("Matching was successful.")
+            Timber.tag(TAG).d("Matching was successful.")
             true
         }
-
         return Result(
             successful = successful,
             processedPackages = matchLists.filterNotNull().flatten()
@@ -67,11 +69,11 @@ class CheckInWarningMatcher @Inject constructor(
                 try {
                     packageChunk.map {
                         val overlaps = findMatches(list, it)
-                        Timber.d("%d overlaps for %s", overlaps.size, it.packageId)
+                        Timber.tag(TAG).d("%d overlaps for %s", overlaps.size, it.packageId)
                         MatchesPerPackage(warningPackage = it, overlaps = overlaps)
                     }
                 } catch (e: Throwable) {
-                    Timber.e(e, "Failed to process packages $packageChunk")
+                    Timber.tag(TAG).e(e, "Failed to process packages $packageChunk")
                     null
                 }
             }
@@ -105,9 +107,9 @@ internal suspend fun findMatches(
                 .mapNotNull { checkIn ->
                     checkIn.calculateOverlap(warning, warningPackage.packageId).also { overlap ->
                         if (overlap == null) {
-                            Timber.v("No match found for $checkIn and $warning")
+                            Timber.tag(TAG).v("No match found for $checkIn and $warning")
                         } else {
-                            Timber.w("Overlap was found $overlap")
+                            Timber.tag(TAG).w("Overlap was found $overlap")
                         }
                     }
                 }
@@ -129,7 +131,12 @@ internal fun CheckIn.calculateOverlap(
     val overlapMillis = overlapEndMillis - overlapStartMillis
 
     if (overlapMillis <= 0) {
-        Timber.i("No overlap (%dms) with match %s (%s)", overlapMillis, description, traceLocationIdHash)
+        Timber.tag(TAG).i("Match without overlap (%dms) (%s, %s)", overlapMillis, description, traceLocationIdHash)
+        return null
+    }
+
+    if (isSubmitted) {
+        Timber.tag(TAG).d("Overlap with our own CheckIn (%s and %s)", this, warning)
         return null
     }
 
@@ -141,3 +148,8 @@ internal fun CheckIn.calculateOverlap(
         endTime = Instant.ofEpochMilli(overlapEndMillis)
     )
 }
+
+// converts number of 10min intervals into milliseconds
+internal fun Int.tenMinIntervalToMillis() = this * TimeUnit.MINUTES.toMillis(10L)
+
+private const val TAG = "CheckInWarningMatcher"
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/calculation/PresenceTracingConversions.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/calculation/PresenceTracingConversions.kt
deleted file mode 100644
index 4e529779dc78875644dda7905f5d250866b606f0..0000000000000000000000000000000000000000
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/calculation/PresenceTracingConversions.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package de.rki.coronawarnapp.presencetracing.risk.calculation
-
-import de.rki.coronawarnapp.risk.RiskState
-import de.rki.coronawarnapp.server.protocols.internal.v2.RiskCalculationParametersOuterClass.NormalizedTimeToRiskLevelMapping.RiskLevel
-import java.util.concurrent.TimeUnit
-
-// converts number of 10min intervals into milliseconds
-internal fun Int.tenMinIntervalToMillis() = this * TimeUnit.MINUTES.toMillis(10L)
-
-fun RiskLevel.mapToRiskState(): RiskState {
-    return when (this) {
-        RiskLevel.UNSPECIFIED, RiskLevel.UNRECOGNIZED -> RiskState.CALCULATION_FAILED
-        RiskLevel.LOW -> RiskState.LOW_RISK
-        RiskLevel.HIGH -> RiskState.INCREASED_RISK
-    }
-}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/calculation/PresenceTracingRiskMapper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/calculation/PresenceTracingRiskMapper.kt
index 1cebd0aec5de5430225dbe41568f31b4e326b5a4..06b72ed4620c465999247db75079fae56aef49ee 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/calculation/PresenceTracingRiskMapper.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/calculation/PresenceTracingRiskMapper.kt
@@ -4,6 +4,7 @@ import de.rki.coronawarnapp.appconfig.AppConfigProvider
 import de.rki.coronawarnapp.appconfig.PresenceTracingRiskCalculationParamContainer
 import de.rki.coronawarnapp.risk.DefaultRiskLevels.Companion.inRange
 import de.rki.coronawarnapp.risk.RiskState
+import de.rki.coronawarnapp.risk.mapToRiskState
 import kotlinx.coroutines.flow.first
 import timber.log.Timber
 import javax.inject.Inject
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTask.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTask.kt
index e0d9556af8f02e0ee7577eeebdcbee4a9c0f4a5b..8000745d6440e0e416ca6b65233d6e31106c01fe 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTask.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTask.kt
@@ -12,7 +12,6 @@ import de.rki.coronawarnapp.presencetracing.warning.storage.TraceWarningReposito
 import de.rki.coronawarnapp.task.Task
 import de.rki.coronawarnapp.task.TaskCancellationException
 import de.rki.coronawarnapp.task.TaskFactory
-import de.rki.coronawarnapp.task.common.DefaultProgress
 import de.rki.coronawarnapp.util.TimeStamper
 import kotlinx.coroutines.channels.ConflatedBroadcastChannel
 import kotlinx.coroutines.flow.Flow
@@ -31,10 +30,10 @@ class PresenceTracingWarningTask @Inject constructor(
     private val presenceTracingRiskRepository: PresenceTracingRiskRepository,
     private val traceWarningRepository: TraceWarningRepository,
     private val checkInsRepository: CheckInRepository,
-) : Task<DefaultProgress, PresenceTracingWarningTask.Result> {
+) : Task<PresenceTracingWarningTaskProgress, PresenceTracingWarningTask.Result> {
 
-    private val internalProgress = ConflatedBroadcastChannel<DefaultProgress>()
-    override val progress: Flow<DefaultProgress> = internalProgress.asFlow()
+    private val internalProgress = ConflatedBroadcastChannel<PresenceTracingWarningTaskProgress>()
+    override val progress: Flow<PresenceTracingWarningTaskProgress> = internalProgress.asFlow()
 
     private var isCanceled = false
 
@@ -59,15 +58,24 @@ class PresenceTracingWarningTask @Inject constructor(
 
     private suspend fun doWork(): Result {
         val nowUTC = timeStamper.nowUTC
+        checkCancel()
 
-        Timber.tag(TAG).d("Running package sync.")
-        syncTool.syncPackages()
+        Timber.tag(TAG).d("Syncing packages.")
+        internalProgress.send(PresenceTracingWarningTaskProgress.Downloading())
 
-        checkCancel()
+        val syncResult = syncTool.syncPackages()
+
+        if (syncResult.successful) {
+            Timber.tag(TAG).d("TraceWarningPackage sync successful: %s", syncResult)
+        } else {
+            Timber.tag(TAG).w("WarningPackage sync failed: %s", syncResult)
+            presenceTracingRiskRepository.reportCalculation(successful = false)
+            return Result(calculatedAt = nowUTC)
+        }
 
         presenceTracingRiskRepository.deleteStaleData()
 
-        val checkIns = checkInsRepository.allCheckIns.firstOrNull() ?: emptyList()
+        val checkIns = checkInsRepository.checkInsWithinRetention.firstOrNull() ?: emptyList()
         Timber.tag(TAG).d("There are %d check-ins to match against.", checkIns.size)
 
         if (checkIns.isEmpty()) {
@@ -91,6 +99,8 @@ class PresenceTracingWarningTask @Inject constructor(
         }
 
         Timber.tag(TAG).d("Running check-in matcher.")
+        internalProgress.send(PresenceTracingWarningTaskProgress.Calculating())
+
         val matcherResult = checkInWarningMatcher.process(
             checkIns = checkIns,
             warningPackages = unprocessedPackages,
@@ -141,13 +151,13 @@ class PresenceTracingWarningTask @Inject constructor(
     class Factory @Inject constructor(
         private val taskByDagger: Provider<PresenceTracingWarningTask>,
         private val appConfigProvider: AppConfigProvider
-    ) : TaskFactory<DefaultProgress, Task.Result> {
+    ) : TaskFactory<PresenceTracingWarningTaskProgress, Task.Result> {
 
         override suspend fun createConfig(): TaskFactory.Config = Config(
             executionTimeout = appConfigProvider.getAppConfig().overallDownloadTimeout
         )
 
-        override val taskProvider: () -> Task<DefaultProgress, Task.Result> = {
+        override val taskProvider: () -> Task<PresenceTracingWarningTaskProgress, Task.Result> = {
             taskByDagger.get()
         }
     }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTaskProgress.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTaskProgress.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a7c9869954c5a4435f65ffcb772b09648bd64a85
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTaskProgress.kt
@@ -0,0 +1,16 @@
+package de.rki.coronawarnapp.presencetracing.risk.execution
+
+import de.rki.coronawarnapp.task.Task
+import de.rki.coronawarnapp.util.ui.CachedString
+import de.rki.coronawarnapp.util.ui.LazyString
+
+sealed class PresenceTracingWarningTaskProgress : Task.Progress {
+
+    data class Downloading(
+        override val primaryMessage: LazyString = CachedString { "" }
+    ) : PresenceTracingWarningTaskProgress()
+
+    data class Calculating(
+        override val primaryMessage: LazyString = CachedString { "" }
+    ) : PresenceTracingWarningTaskProgress()
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/storage/PresenceTracingRiskRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/storage/PresenceTracingRiskRepository.kt
index daf5c60bcd39437e7d54a410654397d5855bbbc9..9dbccbc3e1b0c6c2a191cccde25f7eff674f2d82 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/storage/PresenceTracingRiskRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/storage/PresenceTracingRiskRepository.kt
@@ -128,9 +128,15 @@ class PresenceTracingRiskRepository @Inject constructor(
                 if (!lastSuccessfulFound && entity.riskState != RiskState.CALCULATION_FAILED) {
                     lastSuccessfulFound = true
                     // add risk per day to the last successful result
-                    entity.toCheckInWarningOverlap(presenceTracingDayRisk.first())
+                    entity.toRiskLevelResult(
+                        presenceTracingDayRisks = presenceTracingDayRisk.first(),
+                        checkInWarningOverlaps = checkInWarningOverlaps.first(),
+                    )
                 } else {
-                    entity.toCheckInWarningOverlap(null)
+                    entity.toRiskLevelResult(
+                        presenceTracingDayRisks = null,
+                        checkInWarningOverlaps = null,
+                    )
                 }
             }
     }
@@ -144,16 +150,22 @@ class PresenceTracingRiskRepository @Inject constructor(
                 if (!lastSuccessfulFound && entity.riskState != RiskState.CALCULATION_FAILED) {
                     lastSuccessfulFound = true
                     // add risk per day to the last successful result
-                    entity.toCheckInWarningOverlap(presenceTracingDayRisk.first())
+                    entity.toRiskLevelResult(
+                        presenceTracingDayRisks = presenceTracingDayRisk.first(),
+                        checkInWarningOverlaps = checkInWarningOverlaps.first(),
+                    )
                 } else {
-                    entity.toCheckInWarningOverlap(null)
+                    entity.toRiskLevelResult(
+                        presenceTracingDayRisks = null,
+                        checkInWarningOverlaps = null,
+                    )
                 }
             }
     }
 
     private fun addResult(result: PtRiskLevelResult) {
         Timber.i("Saving risk calculation from ${result.calculatedAt} with result ${result.riskState}.")
-        riskLevelResultDao.insert(result.toTraceTimeIntervalMatchEntity())
+        riskLevelResultDao.insert(result.toRiskLevelEntity())
     }
 
     suspend fun clearAllTables() {
@@ -242,15 +254,17 @@ data class PresenceTracingRiskLevelResultEntity(
     @ColumnInfo(name = "riskStateCode") val riskState: RiskState
 )
 
-private fun PresenceTracingRiskLevelResultEntity.toCheckInWarningOverlap(
-    presenceTracingDayRisk: List<PresenceTracingDayRisk>?
+private fun PresenceTracingRiskLevelResultEntity.toRiskLevelResult(
+    presenceTracingDayRisks: List<PresenceTracingDayRisk>?,
+    checkInWarningOverlaps: List<CheckInWarningOverlap>?
 ) = PtRiskLevelResult(
     calculatedAt = Instant.ofEpochMilli((calculatedAtMillis)),
     riskState = riskState,
-    presenceTracingDayRisk = presenceTracingDayRisk
+    presenceTracingDayRisk = presenceTracingDayRisks,
+    checkInWarningOverlaps = checkInWarningOverlaps,
 )
 
-private fun PtRiskLevelResult.toTraceTimeIntervalMatchEntity() = PresenceTracingRiskLevelResultEntity(
+private fun PtRiskLevelResult.toRiskLevelEntity() = PresenceTracingRiskLevelResultEntity(
     calculatedAtMillis = calculatedAt.millis,
     riskState = riskState
 )
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/warning/download/TraceWarningPackageDownloader.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/warning/download/TraceWarningPackageDownloader.kt
index 581df13ed6c0afec399e579fc8a42a67da801d47..466d98764ac22f19d1b371292e3c64a9005d0c82 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/warning/download/TraceWarningPackageDownloader.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/warning/download/TraceWarningPackageDownloader.kt
@@ -18,6 +18,7 @@ import kotlinx.coroutines.withContext
 import kotlinx.coroutines.withTimeout
 import org.joda.time.Duration
 import timber.log.Timber
+import java.io.File
 import javax.inject.Inject
 
 @Reusable
@@ -32,9 +33,7 @@ class TraceWarningPackageDownloader @Inject constructor(
         val successful: Boolean,
         val newPackages: Collection<TraceWarningPackageMetadata>
     ) {
-        override fun toString(): String {
-            return "DownloadResult(successful=$successful, newPackages.size=${newPackages.size})"
-        }
+        override fun toString(): String = "DownloadResult(successful=$successful, newPackages.size=${newPackages.size})"
     }
 
     suspend fun launchDownloads(
@@ -42,6 +41,8 @@ class TraceWarningPackageDownloader @Inject constructor(
         hourIntervals: List<HourInterval>,
         downloadTimeout: Duration
     ): DownloadResult {
+        Timber.tag(TAG).d("Launching %d downloads ($location): %s", hourIntervals.size, hourIntervals)
+
         val launcher: CoroutineScope.(HourInterval) -> Deferred<TraceWarningPackageMetadata?> = { hourInterval ->
             async {
                 val metadata = repository.createMetadata(location, hourInterval)
@@ -51,8 +52,6 @@ class TraceWarningPackageDownloader @Inject constructor(
             }
         }
 
-        Timber.tag(TAG).d("Launching %d downloads.", hourIntervals.size)
-
         val launchedDownloads: Collection<Deferred<TraceWarningPackageMetadata?>> =
             hourIntervals.map { warningPackageId ->
                 withContext(context = dispatcherProvider.IO) {
@@ -81,12 +80,17 @@ class TraceWarningPackageDownloader @Inject constructor(
             hourInterval = metaData.hourInterval
         )
 
+        val saveTo = repository.getPathForMetaData(metaData)
+
         if (!downloadInfo.isEmptyPkg) {
             val fileMap = downloadInfo.readBody().unzip().readIntoMap()
             val rawProtoBuf = getValidatedBinary(metaData, fileMap)
-            writeProtoBufToFile(metaData, rawProtoBuf)
+            writeProtoBufToFile(metaData, rawProtoBuf, saveTo)
         } else {
             Timber.tag(TAG).v("Empty package for %s", metaData)
+            if (saveTo.exists() && saveTo.delete()) {
+                Timber.tag(TAG).w("Download file exists for a package that should be empty, deleting: %s", saveTo)
+            }
         }
 
         Timber.tag(TAG).v("Download finished: %s -> %s", metaData, downloadInfo)
@@ -102,13 +106,13 @@ class TraceWarningPackageDownloader @Inject constructor(
     private fun writeProtoBufToFile(
         metaData: TraceWarningPackageMetadata,
         rawProtoBuf: ByteArray,
+        saveTo: File,
     ) {
         if (rawProtoBuf.isEmpty()) {
             Timber.tag(TAG).d("rawProtoBuf was empty for  %s", metaData.packageId)
             return
         }
 
-        val saveTo = repository.getPathForMetaData(metaData)
         if (saveTo.exists()) {
             Timber.tag(TAG).w("File existed, overwriting: %s", saveTo)
             if (saveTo.delete()) {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/warning/download/TraceWarningPackageSyncTool.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/warning/download/TraceWarningPackageSyncTool.kt
index ea2d87f227017e3399c5c4b12468448f47914ec4..4e2f9e118ae1fb0842a1783269d69ed6d0175381 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/warning/download/TraceWarningPackageSyncTool.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/warning/download/TraceWarningPackageSyncTool.kt
@@ -41,7 +41,7 @@ class TraceWarningPackageSyncTool @Inject constructor(
     internal suspend fun syncPackagesForLocation(location: LocationCode): SyncResult {
         Timber.tag(TAG).d("syncTraceWarningPackages(location=%s)", location)
 
-        val oldestCheckIn = checkInRepository.allCheckIns.first().minByOrNull { it.checkInStart }.also {
+        val oldestCheckIn = checkInRepository.checkInsWithinRetention.first().minByOrNull { it.checkInStart }.also {
             Timber.tag(TAG).d("Our oldest check-in is %s", it)
         }
 
@@ -63,9 +63,13 @@ class TraceWarningPackageSyncTool @Inject constructor(
             return SyncResult(successful = false)
         }
 
-        val firstRelevantInterval: HourInterval = max(
-            oldestCheckIn.checkInStart.deriveHourInterval(),
-            intervalDiscovery.oldest
+        val oldestCheckInInterval = oldestCheckIn.checkInStart.deriveHourInterval()
+        val firstRelevantInterval: HourInterval = max(oldestCheckInInterval, intervalDiscovery.oldest)
+        Timber.tag(TAG).d(
+            "Oldest-server=%s & Oldest-local=%s => first-relevant=%s",
+            intervalDiscovery.oldest,
+            oldestCheckInInterval,
+            firstRelevantInterval
         )
 
         cleanUpIrrelevantPackages(location, firstRelevantInterval)
@@ -77,7 +81,7 @@ class TraceWarningPackageSyncTool @Inject constructor(
 
         val missingHourIntervals = determineIntervalsToDownload(
             location = location,
-            firstRelevant = oldestCheckIn.checkInStart.deriveHourInterval(),
+            firstRelevant = firstRelevantInterval,
             lastRelevant = intervalDiscovery.latest
         )
 
@@ -148,12 +152,17 @@ class TraceWarningPackageSyncTool @Inject constructor(
         firstRelevant: HourInterval,
         lastRelevant: HourInterval
     ): List<HourInterval> {
-        val metadatas = repository.getMetaDataForLocation(location)
-
-        return (firstRelevant..lastRelevant).filter { interval ->
-            // If there is no metadata, it's unknown, so we want to download it
-            metadatas.none { it.hourInterval == interval }
-        }
+        val metadatas = repository.getMetaDataForLocation(location).filter { it.isDownloaded }
+        Timber.tag(TAG).d("We already have downloads for %s", metadatas.joinToString(", ") { it.packageId })
+
+        return (firstRelevant..lastRelevant)
+            .filter { interval ->
+                // If there is no metadata, it's unknown, so we want to download it
+                metadatas.none { it.hourInterval == interval }
+            }
+            .also {
+                Timber.tag(TAG).d("Missing intervals for %s are %s", location, it)
+            }
     }
 
     private suspend fun requireStorageSpaceFor(size: Int): DeviceStorage.CheckResult {
@@ -167,7 +176,10 @@ class TraceWarningPackageSyncTool @Inject constructor(
     data class SyncResult(
         val successful: Boolean,
         val newPackages: Collection<TraceWarningPackageMetadata> = emptyList()
-    )
+    ) {
+        override fun toString(): String =
+            "SyncResult(successful=$successful, newPackages=${newPackages.joinToString(",") { it.packageId }})"
+    }
 
     companion object {
         private const val TAG = "TraceWarningSyncTool"
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/warning/download/server/TraceWarningPackageDownload.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/warning/download/server/TraceWarningPackageDownload.kt
index 02e5d44480f76ebbcd58e5a1621bbd2783b1ce25..d729af13c4cd12f5c35218a423e6d2a3ff97e677 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/warning/download/server/TraceWarningPackageDownload.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/warning/download/server/TraceWarningPackageDownload.kt
@@ -10,7 +10,7 @@ data class TraceWarningPackageDownload(val response: Response<ResponseBody>) {
 
     val etag by lazy { headers.values("ETag").singleOrNull() }
 
-    val isEmptyPkg by lazy { headers.values("cwa-empty-pkg").singleOrNull() == "1" }
+    val isEmptyPkg by lazy { headers.values("Content-Length").singleOrNull() == "0" }
 
     fun readBody(): InputStream = requireNotNull(response.body()) { "Response body was null" }.byteStream()
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/receiver/ExposureStateUpdateReceiver.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/receiver/ExposureStateUpdateReceiver.kt
index 72a049c16999f42880d6a0d159cf2501ecda5088..6005f4f3c77ec5fff21ed95b590dc8bab43deeb8 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/receiver/ExposureStateUpdateReceiver.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/receiver/ExposureStateUpdateReceiver.kt
@@ -51,6 +51,7 @@ class ExposureStateUpdateReceiver : BroadcastReceiver() {
 
         scope.launch(context = scope.coroutineContext) {
             try {
+                @Suppress("DEPRECATION")
                 intent.getStringExtra(EXTRA_TOKEN)?.let {
                     Timber.tag(TAG).w("Received unknown token from ENF: %s", it)
                 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/CombinedEwPtRisk.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/CombinedEwPtRisk.kt
index b4e6305fb069fdd90d9136baa9a2549a2250023a..1e2a96561f7506bb77d98c6e253feececd26b436 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/CombinedEwPtRisk.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/CombinedEwPtRisk.kt
@@ -13,8 +13,8 @@ data class CombinedEwPtDayRisk(
 )
 
 data class CombinedEwPtRiskLevelResult(
-    val ptRiskLevelResult: PtRiskLevelResult,
-    val ewRiskLevelResult: EwRiskLevelResult
+    private val ptRiskLevelResult: PtRiskLevelResult,
+    private val ewRiskLevelResult: EwRiskLevelResult
 ) {
 
     val riskState: RiskState by lazy {
@@ -56,6 +56,15 @@ data class CombinedEwPtRiskLevelResult(
             else -> null
         }
     }
+
+    /**
+     * The combination of matched exposure windows and overlaps.
+     * If we have matches > 0, but are still in a low risk state,
+     * the UI displays additional information in the risk details screen.
+     */
+    val matchedRiskCount: Int by lazy {
+        ewRiskLevelResult.matchedKeyCount + ptRiskLevelResult.checkInOverlapCount
+    }
 }
 
 data class LastCombinedRiskResults(
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskState.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskState.kt
index e71d6f7a47b0ebce7445f3615ba4d8777a60af21..facbcb948aa9fc58660aeca8428744b9114b55ff 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskState.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskState.kt
@@ -1,7 +1,17 @@
 package de.rki.coronawarnapp.risk
 
+import de.rki.coronawarnapp.server.protocols.internal.v2.RiskCalculationParametersOuterClass.NormalizedTimeToRiskLevelMapping.RiskLevel
+
 enum class RiskState {
     LOW_RISK,
     INCREASED_RISK,
     CALCULATION_FAILED
 }
+
+fun RiskLevel.mapToRiskState(): RiskState {
+    return when (this) {
+        RiskLevel.UNSPECIFIED, RiskLevel.UNRECOGNIZED -> RiskState.CALCULATION_FAILED
+        RiskLevel.LOW -> RiskState.LOW_RISK
+        RiskLevel.HIGH -> RiskState.INCREASED_RISK
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/BaseRiskLevelStorage.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/BaseRiskLevelStorage.kt
index d5d0d71f03319705140b0a456969d7e9c2289b4f..af277a073144c8f1a9aa075768c14e2c18a4013c 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/BaseRiskLevelStorage.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/BaseRiskLevelStorage.kt
@@ -5,7 +5,6 @@ import com.google.android.gms.nearby.exposurenotification.ExposureWindow
 import de.rki.coronawarnapp.presencetracing.risk.PtRiskLevelResult
 import de.rki.coronawarnapp.presencetracing.risk.TraceLocationCheckInRisk
 import de.rki.coronawarnapp.presencetracing.risk.calculation.PresenceTracingDayRisk
-import de.rki.coronawarnapp.presencetracing.risk.calculation.mapToRiskState
 import de.rki.coronawarnapp.presencetracing.risk.storage.PresenceTracingRiskRepository
 import de.rki.coronawarnapp.risk.CombinedEwPtDayRisk
 import de.rki.coronawarnapp.risk.CombinedEwPtRiskLevelResult
@@ -13,6 +12,7 @@ import de.rki.coronawarnapp.risk.EwRiskLevelResult
 import de.rki.coronawarnapp.risk.EwRiskLevelTaskResult
 import de.rki.coronawarnapp.risk.LastCombinedRiskResults
 import de.rki.coronawarnapp.risk.RiskState
+import de.rki.coronawarnapp.risk.mapToRiskState
 import de.rki.coronawarnapp.risk.result.EwAggregatedRiskResult
 import de.rki.coronawarnapp.risk.result.ExposureWindowDayRisk
 import de.rki.coronawarnapp.risk.storage.internal.RiskResultDatabase
@@ -256,10 +256,13 @@ internal fun combineRisk(
     }
 }
 
-internal fun combine(left: RiskState?, right: RiskState?): RiskState {
-    return if (left == RiskState.INCREASED_RISK || right == RiskState.INCREASED_RISK) RiskState.INCREASED_RISK
-    else if (left == RiskState.LOW_RISK || right == RiskState.LOW_RISK) RiskState.LOW_RISK
-    else RiskState.CALCULATION_FAILED
+internal fun combine(vararg states: RiskState?): RiskState {
+    if (states.any { it == RiskState.CALCULATION_FAILED }) return RiskState.CALCULATION_FAILED
+    if (states.any { it == RiskState.INCREASED_RISK }) return RiskState.INCREASED_RISK
+
+    require(states.filterNotNull().all { it == RiskState.LOW_RISK })
+
+    return RiskState.LOW_RISK
 }
 
 internal fun max(left: Instant, right: Instant): Instant {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/TracingRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/TracingRepository.kt
index 49488cc0e03fd3dd3dcb9f3add4fcc5edb6b154d..6f9fdeed6e2231cc1f4f7bba4c3ea874a405d299 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/TracingRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/TracingRepository.kt
@@ -1,11 +1,14 @@
 package de.rki.coronawarnapp.storage
 
+import android.annotation.SuppressLint
 import android.content.Context
 import de.rki.coronawarnapp.diagnosiskeys.download.DownloadDiagnosisKeysTask
 import de.rki.coronawarnapp.nearby.ENFClient
 import de.rki.coronawarnapp.nearby.InternalExposureNotificationClient
 import de.rki.coronawarnapp.nearby.modules.detectiontracker.ExposureDetectionTracker
 import de.rki.coronawarnapp.nearby.modules.detectiontracker.lastSubmission
+import de.rki.coronawarnapp.presencetracing.risk.execution.PresenceTracingWarningTask
+import de.rki.coronawarnapp.presencetracing.risk.execution.PresenceTracingWarningTaskProgress
 import de.rki.coronawarnapp.risk.RiskLevelTask
 import de.rki.coronawarnapp.task.TaskController
 import de.rki.coronawarnapp.task.TaskInfo
@@ -21,7 +24,7 @@ import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.firstOrNull
 import kotlinx.coroutines.launch
 import org.joda.time.Duration
 import timber.log.Timber
@@ -45,26 +48,49 @@ class TracingRepository @Inject constructor(
     private val backgroundModeStatus: BackgroundModeStatus
 ) {
 
+    @SuppressLint("BinaryOperationInTimber")
     val tracingProgress: Flow<TracingProgress> = combine(
-        taskController.tasks.map { it.isDownloadDiagnosisKeysTaskRunning() },
+        taskController.tasks,
         enfClient.isPerformingExposureDetection(),
-        taskController.tasks.map { it.isRiskLevelTaskRunning() }
-    ) { isDownloading, isExposureDetecting, isRiskLeveling ->
+    ) { taskInfos, isExposureDetecting ->
+
+        val isEWDownloading = taskInfos.isEWDownloadingPackages()
+        val isEWCalculatingRisk = taskInfos.isEWCalculatingRisk()
+
+        val isPTDownloading = taskInfos.isPTDownloadingPackages()
+        val isPTCalculatingRisk = taskInfos.isPTCalculatingRisk()
+
         when {
-            isDownloading -> TracingProgress.Downloading
-            isExposureDetecting || isRiskLeveling -> TracingProgress.ENFIsCalculating
+            isEWDownloading || isPTDownloading -> TracingProgress.Downloading
+            isExposureDetecting || isEWCalculatingRisk || isPTCalculatingRisk -> TracingProgress.IsCalculating
             else -> TracingProgress.Idle
+        }.also {
+            Timber.tag(TAG).v(
+                "TracingProgress: $it, isExposureDetecting=$isExposureDetecting, " +
+                    "isEWDownloading=$isEWDownloading, isEWCalculatingRisk=$isEWCalculatingRisk, " +
+                    "isPTDownloading=$isPTDownloading, isPTCalculatingRisk=$isPTCalculatingRisk"
+            )
         }
     }
 
-    private fun List<TaskInfo>.isRiskLevelTaskRunning() = any {
-        it.taskState.isActive && it.taskState.request.type == RiskLevelTask::class
+    private suspend fun List<TaskInfo>.isPTDownloadingPackages() = any {
+        it.taskState.isActive && it.taskState.request.type == PresenceTracingWarningTask::class &&
+            it.progress.firstOrNull() is PresenceTracingWarningTaskProgress.Downloading
     }
 
-    private fun List<TaskInfo>.isDownloadDiagnosisKeysTaskRunning() = any {
+    private suspend fun List<TaskInfo>.isPTCalculatingRisk() = any {
+        it.taskState.isActive && it.taskState.request.type == PresenceTracingWarningTask::class &&
+            it.progress.firstOrNull() is PresenceTracingWarningTaskProgress.Calculating
+    }
+
+    private fun List<TaskInfo>.isEWDownloadingPackages() = any {
         it.taskState.isActive && it.taskState.request.type == DownloadDiagnosisKeysTask::class
     }
 
+    private fun List<TaskInfo>.isEWCalculatingRisk() = any {
+        it.taskState.isActive && it.taskState.request.type == RiskLevelTask::class
+    }
+
     /**
      * Refresh the diagnosis keys. For that isRefreshing is set to true which is displayed in the ui.
      * Afterwards the RetrieveDiagnosisKeysTransaction and the RiskLevelTransaction are started.
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/task/SubmissionTask.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/task/SubmissionTask.kt
index a860a2edb3b0e5692ea03bcb94157c091882638f..5f801d507b6da853a6d4ec7602f0766e263bd0da 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/task/SubmissionTask.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/task/SubmissionTask.kt
@@ -2,6 +2,7 @@ package de.rki.coronawarnapp.submission.task
 
 import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey
 import de.rki.coronawarnapp.appconfig.AppConfigProvider
+import de.rki.coronawarnapp.bugreporting.reportProblem
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
 import de.rki.coronawarnapp.eventregistration.checkins.CheckInRepository
 import de.rki.coronawarnapp.eventregistration.checkins.CheckInsTransformer
@@ -142,7 +143,7 @@ class SubmissionTask @Inject constructor(
         )
         Timber.tag(TAG).d("Transformed keys with symptoms %s from %s to %s", symptoms, keys, transformedKeys)
 
-        val checkIns = checkInsRepository.allCheckIns.first()
+        val checkIns = checkInsRepository.checkInsWithinRetention.first()
         val transformedCheckIns = checkInsTransformer.transform(checkIns, symptoms)
 
         Timber.tag(TAG).d("Transformed CheckIns from: %s to: %s", checkIns, transformedCheckIns)
@@ -165,9 +166,17 @@ class SubmissionTask @Inject constructor(
 
         Timber.tag(TAG).d("Submission successful, deleting submission data.")
         tekHistoryStorage.clear()
-        checkInsRepository.clear()
         submissionSettings.symptoms.update { null }
 
+        Timber.tag(TAG).d("Marking %d submitted CheckIns.", checkIns.size)
+        checkIns.forEach { checkIn ->
+            try {
+                checkInsRepository.markCheckInAsSubmitted(checkIn.id)
+            } catch (e: Exception) {
+                e.reportProblem(TAG, "CheckIn $checkIn could not be marked as submitted")
+            }
+        }
+
         autoSubmission.updateMode(AutoSubmission.Mode.DISABLED)
 
         setSubmissionFinished()
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/ui/homecards/SubmissionStateProvider.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/ui/homecards/SubmissionStateProvider.kt
index d94e448b7c7e0789219c48b7f1344edf27a82801..54f584682f70f72917c1c9805010ea5b3774e093 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/ui/homecards/SubmissionStateProvider.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/ui/homecards/SubmissionStateProvider.kt
@@ -45,7 +45,7 @@ class SubmissionStateProvider @Inject constructor(
             eval.isResultNegative() -> TestNegative
             eval.isSubmissionDone() -> SubmissionDone(testRegisteredOn = testRegistrationDate)
             eval.isPending() -> TestPending
-            else -> if (CWADebug.isDeviceForTestersBuild) throw IllegalStateException() else TestPending
+            else -> if (CWADebug.isDeviceForTestersBuild) throw IllegalStateException(eval.toString()) else TestPending
         }
     }
         .onStart { Timber.v("SubmissionStateProvider FLOW start") }
@@ -123,5 +123,10 @@ class SubmissionStateProvider @Inject constructor(
                 }
                 else -> false
             }
+
+        override fun toString() =
+            "Evaluation(deviceUiState=$deviceUiState, " +
+                "isDeviceRegistered=$isDeviceRegistered, " +
+                "hasTestResultBeenSeen=$hasTestResultBeenSeen)"
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/TracingProgress.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/TracingProgress.kt
index aa4416de0b312c310b2623548007880b4f582d02..955d17a6a6c56d4550a857fafebfc055fd5bf71d 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/TracingProgress.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/TracingProgress.kt
@@ -2,9 +2,15 @@ package de.rki.coronawarnapp.tracing
 
 sealed class TracingProgress {
 
-    object Idle : TracingProgress()
+    object Idle : TracingProgress() {
+        override fun toString(): String = "TracingProgress.Idle"
+    }
 
-    object Downloading : TracingProgress()
+    object Downloading : TracingProgress() {
+        override fun toString(): String = "TracingProgress.Downloading"
+    }
 
-    object ENFIsCalculating : TracingProgress()
+    object IsCalculating : TracingProgress() {
+        override fun toString(): String = "TracingProgress.IsCalculating"
+    }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/states/TracingState.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/states/TracingState.kt
index a12be64f0bd184ca6149d1d56e8e598d1382f6b2..58cf7f5372fe8b00a875ead825d7347ae7343e20 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/states/TracingState.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/states/TracingState.kt
@@ -226,13 +226,13 @@ data class TracingInProgress(
 
     fun getProgressCardHeadline(c: Context): String = when (tracingProgress) {
         TracingProgress.Downloading -> R.string.risk_card_progress_download_headline
-        TracingProgress.ENFIsCalculating -> R.string.risk_card_progress_calculation_headline
+        TracingProgress.IsCalculating -> R.string.risk_card_progress_calculation_headline
         TracingProgress.Idle -> null
     }?.let { c.getString(it) } ?: ""
 
     fun getProgressCardBody(c: Context): String = when (tracingProgress) {
         TracingProgress.Downloading -> R.string.risk_card_progress_download_body
-        TracingProgress.ENFIsCalculating -> R.string.risk_card_progress_calculation_body
+        TracingProgress.IsCalculating -> R.string.risk_card_progress_calculation_body
         TracingProgress.Idle -> null
     }?.let { c.getString(it) } ?: ""
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/ui/details/TracingDetailsItemProvider.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/ui/details/TracingDetailsItemProvider.kt
index f47238e681de2d5ec7077d10bf0ba2e1d60aa649..7537905dc3a80932bd577072e9899170b12124e1 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/ui/details/TracingDetailsItemProvider.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/ui/details/TracingDetailsItemProvider.kt
@@ -47,7 +47,7 @@ class TracingDetailsItemProvider @Inject constructor(
         mutableListOf<DetailsItem>().apply {
             if (status != Status.TRACING_INACTIVE &&
                 latestCalc.riskState == RiskState.LOW_RISK &&
-                latestCalc.ewRiskLevelResult.matchedKeyCount > 0
+                latestCalc.matchedRiskCount > 0
             ) {
                 add(AdditionalInfoLowRiskBox.Item)
             }
@@ -81,7 +81,7 @@ class TracingDetailsItemProvider @Inject constructor(
                 }
                 latestCalc.riskState == RiskState.LOW_RISK -> DetailsLowRiskBox.Item(
                     riskState = latestCalc.riskState,
-                    matchedKeyCount = latestCalc.ewRiskLevelResult.matchedKeyCount
+                    matchedRiskCount = latestCalc.matchedRiskCount
                 )
                 latestCalc.riskState == RiskState.INCREASED_RISK -> DetailsIncreasedRiskBox.Item(
                     riskState = latestCalc.riskState,
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/ui/details/items/riskdetails/DetailsLowRiskBox.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/ui/details/items/riskdetails/DetailsLowRiskBox.kt
index 574698d978b25369e7610465708645e40beb0f21..d3c84c6c04e994cc07c6b3dc07136817159041fa 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/ui/details/items/riskdetails/DetailsLowRiskBox.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/ui/details/items/riskdetails/DetailsLowRiskBox.kt
@@ -33,7 +33,8 @@ class DetailsLowRiskBox(
         payloads: List<Any>
     ) -> Unit = { item, _ ->
         info = item
-        if (item.matchedKeyCount > 0) {
+        // Low risk, but matched risk item? More info! Don't worry!
+        if (item.matchedRiskCount > 0) {
             riskDetailsInformationLowriskBodyUrl.visibility = View.VISIBLE
             riskDetailsInformationLowriskBodyUrl.convertToHyperlink(
                 context.getString(R.string.risk_details_explanation_faq_link)
@@ -46,13 +47,13 @@ class DetailsLowRiskBox(
 
     data class Item(
         val riskState: RiskState,
-        val matchedKeyCount: Int
+        val matchedRiskCount: Int
     ) : RiskDetailsStateItem {
 
         fun getRiskDetailsRiskLevelBody(c: Context): String {
             // TODO consider pt encounters?
             return c.getString(
-                if (matchedKeyCount > 0) R.string.risk_details_information_body_low_risk_with_encounter
+                if (matchedRiskCount > 0) R.string.risk_details_information_body_low_risk_with_encounter
                 else R.string.risk_details_information_body_low_risk
             )
         }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/EventRegistrationUIModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/EventRegistrationUIModule.kt
index e6f0123e69c4734517875010ea148e6006d78206..07b90907c3e3a2d6e3e9141c29603f5e9ba9f4fb 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/EventRegistrationUIModule.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/EventRegistrationUIModule.kt
@@ -16,6 +16,8 @@ import de.rki.coronawarnapp.ui.eventregistration.organizer.category.TraceLocatio
 import de.rki.coronawarnapp.ui.eventregistration.organizer.category.TraceLocationCategoryFragmentModule
 import de.rki.coronawarnapp.ui.eventregistration.organizer.create.TraceLocationCreateFragment
 import de.rki.coronawarnapp.ui.eventregistration.organizer.create.TraceLocationCreateFragmentModule
+import de.rki.coronawarnapp.ui.eventregistration.organizer.details.QrCodeDetailFragment
+import de.rki.coronawarnapp.ui.eventregistration.organizer.details.QrCodeDetailFragmentModule
 import de.rki.coronawarnapp.ui.eventregistration.organizer.list.TraceLocationsFragment
 import de.rki.coronawarnapp.ui.eventregistration.organizer.list.TraceLocationsFragmentModule
 import de.rki.coronawarnapp.ui.eventregistration.organizer.poster.QrCodePosterFragment
@@ -55,4 +57,7 @@ internal abstract class EventRegistrationUIModule {
 
     @ContributesAndroidInjector(modules = [QrCodePosterFragmentModule::class])
     abstract fun qrCodePosterFragment(): QrCodePosterFragment
+
+    @ContributesAndroidInjector(modules = [QrCodeDetailFragmentModule::class])
+    abstract fun showEventDetail(): QrCodeDetailFragment
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInEvent.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInEvent.kt
index be14a1abc59bc5fa0d162fd4638e7c4f23105ffe..5af35e5be9608b289d8430ec27353589a67d2d08 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInEvent.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInEvent.kt
@@ -11,7 +11,7 @@ sealed class CheckInEvent {
 
     data class ConfirmCheckIn(val verifiedTraceLocation: VerifiedTraceLocation) : CheckInEvent()
 
-    data class EditCheckIn(val checkInId: Long) : CheckInEvent()
+    data class EditCheckIn(val checkInId: Long, val position: Int) : CheckInEvent()
 
     data class ConfirmSwipeItem(val checkIn: CheckIn, val position: Int) : CheckInEvent()
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsFragment.kt
index b39c06703c9b30c4dd27fd5f0a4802e59f545375..4a99d53591edb92a549e77939ecd19b82604adb6 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsFragment.kt
@@ -17,12 +17,14 @@ import androidx.navigation.fragment.findNavController
 import androidx.navigation.fragment.navArgs
 import androidx.recyclerview.widget.DefaultItemAnimator
 import com.google.android.material.transition.Hold
+import com.google.android.material.transition.MaterialSharedAxis
 import de.rki.coronawarnapp.BuildConfig
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.TraceLocationAttendeeCheckinsFragmentBinding
 import de.rki.coronawarnapp.eventregistration.checkins.CheckIn
 import de.rki.coronawarnapp.ui.eventregistration.attendee.checkins.items.CameraPermissionVH
 import de.rki.coronawarnapp.ui.eventregistration.attendee.checkins.items.CheckInsItem
+import de.rki.coronawarnapp.ui.eventregistration.attendee.edit.EditCheckInFragmentArgs
 import de.rki.coronawarnapp.util.di.AutoInject
 import de.rki.coronawarnapp.util.list.isSwipeable
 import de.rki.coronawarnapp.util.list.onSwipeItem
@@ -58,11 +60,6 @@ class CheckInsFragment : Fragment(R.layout.trace_location_attendee_checkins_frag
     private val binding: TraceLocationAttendeeCheckinsFragmentBinding by viewBindingLazy()
     private val checkInsAdapter = CheckInsAdapter()
 
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-        exitTransition = Hold()
-    }
-
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
         setupMenu(binding.toolbar)
@@ -91,11 +88,14 @@ class CheckInsFragment : Fragment(R.layout.trace_location_attendee_checkins_frag
 
     private fun onNavigationEvent(event: CheckInEvent?) {
         when (event) {
-            is CheckInEvent.ConfirmCheckIn -> doNavigate(
-                CheckInsFragmentDirections.actionCheckInsFragmentToConfirmCheckInFragment(
-                    verifiedTraceLocation = event.verifiedTraceLocation
+            is CheckInEvent.ConfirmCheckIn -> {
+                setupAxisTransition()
+                doNavigate(
+                    CheckInsFragmentDirections.actionCheckInsFragmentToConfirmCheckInFragment(
+                        verifiedTraceLocation = event.verifiedTraceLocation
+                    )
                 )
-            )
+            }
 
             is CheckInEvent.ConfirmSwipeItem -> showRemovalConfirmation(event.checkIn, event.position)
 
@@ -103,15 +103,24 @@ class CheckInsFragment : Fragment(R.layout.trace_location_attendee_checkins_frag
 
             is CheckInEvent.ConfirmRemoveAll -> showRemovalConfirmation(null, null)
 
-            is CheckInEvent.EditCheckIn -> doNavigate(
-                CheckInsFragmentDirections.actionCheckInsFragmentToEditCheckInFragment(
-                    editCheckInId = event.checkInId
+            is CheckInEvent.EditCheckIn -> {
+                setupHoldTransition()
+                val navigatorExtras = binding.checkInsList.layoutManager
+                    ?.findViewByPosition(event.position)?.run {
+                        FragmentNavigatorExtras(this to transitionName)
+                    }
+                findNavController().navigate(
+                    R.id.action_checkInsFragment_to_editCheckInFragment,
+                    EditCheckInFragmentArgs(event.checkInId).toBundle(),
+                    null,
+                    navigatorExtras
                 )
-            )
+            }
 
-            is CheckInEvent.ShowInformation ->
+            is CheckInEvent.ShowInformation -> {
+                setupAxisTransition()
                 doNavigate(CheckInsFragmentDirections.actionCheckInsFragmentToCheckInOnboardingFragment(false))
-
+            }
             is CheckInEvent.OpenDeviceSettings -> openDeviceSettings()
         }
     }
@@ -142,6 +151,7 @@ class CheckInsFragment : Fragment(R.layout.trace_location_attendee_checkins_frag
     private fun bindFAB() {
         binding.scanCheckinQrcodeFab.apply {
             setOnClickListener {
+                setupHoldTransition()
                 findNavController().navigate(
                     R.id.action_checkInsFragment_to_scanCheckInQrCodeFragment,
                     null,
@@ -152,6 +162,16 @@ class CheckInsFragment : Fragment(R.layout.trace_location_attendee_checkins_frag
         }
     }
 
+    private fun setupHoldTransition() {
+        exitTransition = Hold()
+        reenterTransition = Hold()
+    }
+
+    private fun setupAxisTransition() {
+        exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
+        reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
+    }
+
     private fun bindRecycler() {
         binding.checkInsList.apply {
             adapter = checkInsAdapter
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModel.kt
index e78ae163bec10c1d32b585fc1482ed5ea204597f..cad63ea577b336f62629b952f6668ac15b133842 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModel.kt
@@ -41,6 +41,7 @@ class CheckInsViewModel @AssistedInject constructor(
 
     val events = SingleLiveEvent<CheckInEvent>()
     val errorEvent = SingleLiveEvent<Throwable>()
+    private val cameraItem by lazy { cameraPermissionItem() }
 
     init {
         deepLink?.let {
@@ -56,13 +57,13 @@ class CheckInsViewModel @AssistedInject constructor(
 
     val checkins: LiveData<List<CheckInsItem>> = combine(
         intervalFlow(1000),
-        checkInsRepository.allCheckIns,
+        checkInsRepository.checkInsWithinRetention,
         cameraPermissionProvider.deniedPermanently
     ) { _, checkIns, denied ->
         mutableListOf<CheckInsItem>().apply {
             // Camera permission item
             if (denied) {
-                add(cameraPermissionItem())
+                add(cameraItem)
             }
             // CheckIns items
             addAll(mapCheckIns(checkIns))
@@ -105,7 +106,9 @@ class CheckInsViewModel @AssistedInject constructor(
             when {
                 !checkin.completed -> ActiveCheckInVH.Item(
                     checkin = checkin,
-                    onCardClicked = { events.postValue(CheckInEvent.EditCheckIn(it.id)) },
+                    onCardClicked = { checkIn, position ->
+                        events.postValue(CheckInEvent.EditCheckIn(checkIn.id, position))
+                    },
                     onRemoveItem = { events.postValue(CheckInEvent.ConfirmRemoveItem(it)) },
                     onCheckout = { doCheckOutNow(it) },
                     onSwipeItem = { checkIn, position ->
@@ -114,7 +117,9 @@ class CheckInsViewModel @AssistedInject constructor(
                 )
                 else -> PastCheckInVH.Item(
                     checkin = checkin,
-                    onCardClicked = { events.postValue(CheckInEvent.EditCheckIn(it.id)) },
+                    onCardClicked = { checkIn, position ->
+                        events.postValue(CheckInEvent.EditCheckIn(checkIn.id, position))
+                    },
                     onRemoveItem = { events.postValue(CheckInEvent.ConfirmRemoveItem(it)) },
                     onSwipeItem = { checkIn, position ->
                         events.postValue(CheckInEvent.ConfirmSwipeItem(checkIn, position))
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/items/ActiveCheckInVH.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/items/ActiveCheckInVH.kt
index 8b2576d1e692a848d11cf23c3595e6ca4ac3ab21..dce82fc756c047ceedd73a1533318fcc2c203892 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/items/ActiveCheckInVH.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/items/ActiveCheckInVH.kt
@@ -9,9 +9,9 @@ import de.rki.coronawarnapp.util.TimeAndDateExtensions.toUserTimeZone
 import de.rki.coronawarnapp.util.list.SwipeConsumer
 import de.rki.coronawarnapp.util.lists.diffutil.HasPayloadDiffer
 import org.joda.time.Duration
+import org.joda.time.DurationFieldType
 import org.joda.time.Instant
 import org.joda.time.PeriodType
-import org.joda.time.format.DateTimeFormat
 import org.joda.time.format.PeriodFormat
 import org.joda.time.format.PeriodFormatterBuilder
 
@@ -37,27 +37,35 @@ class ActiveCheckInVH(parent: ViewGroup) :
 
         val checkInStartUserTZ = curItem.checkin.checkInStart.toUserTimeZone()
 
-        val checkinDuration = Duration(checkInStartUserTZ, Instant.now())
-        highlightDuration.text = highlightDurationForamtter.print(checkinDuration.toPeriod())
+        highlightDuration.text = kotlin.run {
+            val currentDuration = Duration(checkInStartUserTZ, Instant.now())
+            val saneDuration = if (currentDuration.isShorterThan(Duration.ZERO)) {
+                Duration.ZERO
+            } else {
+                currentDuration
+            }
+            highlightDurationFormatter.print(saneDuration.toPeriod())
+        }
 
         description.text = curItem.checkin.description
         address.text = curItem.checkin.address
-        val startDate = checkInStartUserTZ.toLocalDate()
-        traceLocationCardHighlightView.setCaption(startDate.toString(DateTimeFormat.mediumDate()))
 
         checkoutInfo.text = run {
-            val checkoutAt = curItem.checkin.checkInEnd
-            val checkoutIn = Duration(Instant.now(), checkoutAt).let {
+            val checkoutIn = Duration(curItem.checkin.checkInStart, curItem.checkin.checkInEnd).let {
                 val periodType = when {
-                    it.isLongerThan(Duration.standardHours(1)) -> PeriodType.hours()
+                    it.isLongerThan(Duration.standardHours(1)) -> PeriodType.forFields(
+                        arrayOf(DurationFieldType.hours(), DurationFieldType.minutes())
+                    )
                     it.isLongerThan(Duration.standardDays(1)) -> PeriodType.days()
                     else -> PeriodType.minutes()
                 }
                 it.toPeriod(periodType)
             }
 
+            val startDate = checkInStartUserTZ.toLocalDate()
             context.getString(
-                R.string.trace_location_checkins_card_automatic_checkout_info,
+                R.string.trace_location_checkins_card_automatic_checkout_info_format,
+                startDate.toString("dd.MM.yy"),
                 checkInStartUserTZ.toLocalTime().toString("HH:mm"),
                 hourPeriodFormatter.print(checkoutIn)
             )
@@ -72,12 +80,15 @@ class ActiveCheckInVH(parent: ViewGroup) :
 
         checkoutAction.setOnClickListener { curItem.onCheckout(curItem.checkin) }
 
-        itemView.setOnClickListener { curItem.onCardClicked(curItem.checkin) }
+        itemView.apply {
+            setOnClickListener { curItem.onCardClicked(curItem.checkin, adapterPosition) }
+            transitionName = item.checkin.id.toString()
+        }
     }
 
     data class Item(
         val checkin: CheckIn,
-        val onCardClicked: (CheckIn) -> Unit,
+        val onCardClicked: (CheckIn, Int) -> Unit,
         val onRemoveItem: (CheckIn) -> Unit,
         val onCheckout: (CheckIn) -> Unit,
         val onSwipeItem: (CheckIn, Int) -> Unit,
@@ -90,7 +101,7 @@ class ActiveCheckInVH(parent: ViewGroup) :
     }
 
     companion object {
-        private val highlightDurationForamtter = PeriodFormatterBuilder().apply {
+        private val highlightDurationFormatter = PeriodFormatterBuilder().apply {
             printZeroAlways()
             minimumPrintedDigits(2)
             appendHours()
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/items/PastCheckInVH.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/items/PastCheckInVH.kt
index 7613181df503d685c44a4d591abf0222a9a09b9c..4ae061dcb109ee351fb2f8d3560018981e1386b8 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/items/PastCheckInVH.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/items/PastCheckInVH.kt
@@ -46,12 +46,15 @@ class PastCheckInVH(parent: ViewGroup) :
             }
         }
 
-        itemView.setOnClickListener { curItem.onCardClicked(curItem.checkin) }
+        itemView.apply {
+            setOnClickListener { curItem.onCardClicked(curItem.checkin, adapterPosition) }
+            transitionName = item.checkin.id.toString()
+        }
     }
 
     data class Item(
         val checkin: CheckIn,
-        val onCardClicked: (CheckIn) -> Unit,
+        val onCardClicked: (CheckIn, Int) -> Unit,
         val onRemoveItem: (CheckIn) -> Unit,
         val onSwipeItem: (CheckIn, Int) -> Unit,
     ) : CheckInsItem, HasPayloadDiffer, SwipeConsumer {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/confirm/ConfirmCheckInFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/confirm/ConfirmCheckInFragment.kt
index a411d1b2ea41b78288cff2c99248ab6113d8c069..5b9767a72dcf21e160b669bcbaea5cad6c0ceab3 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/confirm/ConfirmCheckInFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/confirm/ConfirmCheckInFragment.kt
@@ -6,6 +6,7 @@ import androidx.core.view.isGone
 import androidx.fragment.app.Fragment
 import androidx.navigation.fragment.navArgs
 import com.google.android.material.appbar.AppBarLayout
+import com.google.android.material.transition.MaterialSharedAxis
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.FragmentConfirmCheckInBinding
 import de.rki.coronawarnapp.ui.durationpicker.DurationPicker
@@ -31,6 +32,13 @@ class ConfirmCheckInFragment : Fragment(R.layout.fragment_confirm_check_in), Aut
         }
     )
 
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
+        returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
+    }
+
     private val binding: FragmentConfirmCheckInBinding by viewBindingLazy()
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -51,7 +59,7 @@ class ConfirmCheckInFragment : Fragment(R.layout.fragment_confirm_check_in), Aut
                 viewModel.createJournalEntryToggled(isChecked)
             }
 
-            confirmCheckinSettingsCardCheckoutTime.setOnClickListener {
+            confirmCheckinSettingsCardCheckoutTimeRow.setOnClickListener {
                 viewModel.dateSelectorClicked()
             }
 
@@ -83,6 +91,7 @@ class ConfirmCheckInFragment : Fragment(R.layout.fragment_confirm_check_in), Aut
                     uiState.eventInFutureDateText,
                     uiState.eventInFutureTimeText
                 )
+                confirmCheckinConfirmButton.isEnabled = uiState.confirmButtonEnabled
             }
         }
 
@@ -99,7 +108,6 @@ class ConfirmCheckInFragment : Fragment(R.layout.fragment_confirm_check_in), Aut
     ) {
         val durationPicker = DurationPicker.Builder()
             .duration(defaultValue ?: "00:00")
-            .minutes()
             .title(getString(R.string.duration_dialog_title))
             .build()
         durationPicker.show(parentFragmentManager, DURATION_PICKER_TAG)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/confirm/ConfirmCheckInViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/confirm/ConfirmCheckInViewModel.kt
index 840682e97c68268d05e0cfc5ce38376f7c1a3eba..a8654db5b89c460c92f3ac006d3f383fa238bce6 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/confirm/ConfirmCheckInViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/confirm/ConfirmCheckInViewModel.kt
@@ -8,6 +8,7 @@ import de.rki.coronawarnapp.eventregistration.checkins.CheckIn
 import de.rki.coronawarnapp.eventregistration.checkins.CheckInRepository
 import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocation
 import de.rki.coronawarnapp.eventregistration.checkins.qrcode.VerifiedTraceLocation
+import de.rki.coronawarnapp.eventregistration.checkins.qrcode.getDefaultAutoCheckoutLengthInMinutes
 import de.rki.coronawarnapp.ui.durationpicker.toContactDiaryFormat
 import de.rki.coronawarnapp.ui.durationpicker.toReadableDuration
 import de.rki.coronawarnapp.ui.eventregistration.organizer.category.adapter.category.mapTraceLocationToTitleRes
@@ -28,9 +29,10 @@ class ConfirmCheckInViewModel @AssistedInject constructor(
 ) : CWAViewModel() {
     private val traceLocation = MutableStateFlow(verifiedTraceLocation.traceLocation)
     private val createJournalEntry = MutableStateFlow(true)
-    private val checkInLength = MutableStateFlow(
+
+    private val autoCheckOutLength = MutableStateFlow(
         Duration.standardMinutes(
-            verifiedTraceLocation.traceLocation.defaultCheckInLengthInMinutes?.toLong() ?: 0L
+            verifiedTraceLocation.traceLocation.getDefaultAutoCheckoutLengthInMinutes(timeStamper.nowUTC).toLong()
         )
     )
 
@@ -40,14 +42,15 @@ class ConfirmCheckInViewModel @AssistedInject constructor(
     val uiState = combine(
         traceLocation,
         createJournalEntry,
-        checkInLength
+        autoCheckOutLength
     ) { traceLocation, createEntry, checkInLength ->
         UiState(
             traceLocation = traceLocation,
             createJournalEntry = createEntry,
             checkInEndOffset = checkInLength,
             eventInPastVisible = traceLocation.isAfterEndTime(timeStamper.nowUTC),
-            eventInFutureVisible = traceLocation.isBeforeStartTime(timeStamper.nowUTC)
+            eventInFutureVisible = traceLocation.isBeforeStartTime(timeStamper.nowUTC),
+            confirmButtonEnabled = checkInLength.standardMinutes > 0
         )
     }.asLiveData()
 
@@ -62,7 +65,7 @@ class ConfirmCheckInViewModel @AssistedInject constructor(
                 verifiedTraceLocation.toCheckIn(
                     checkInStart = now,
                     createJournalEntry = createJournalEntry.value,
-                    checkInEnd = now + checkInLength.value
+                    checkInEnd = now + autoCheckOutLength.value
                 )
             )
             events.postValue(ConfirmCheckInNavigation.ConfirmNavigation)
@@ -74,18 +77,16 @@ class ConfirmCheckInViewModel @AssistedInject constructor(
     }
 
     fun dateSelectorClicked() {
-        openDatePickerEvent.value = checkInLength.value.toContactDiaryFormat()
+        openDatePickerEvent.value = autoCheckOutLength.value.toContactDiaryFormat()
     }
 
     fun durationUpdated(duration: Duration) {
-        checkInLength.value = duration
+        autoCheckOutLength.value = duration
     }
 
     private fun VerifiedTraceLocation.toCheckIn(
         checkInStart: Instant,
-        checkInEnd: Instant = checkInStart.plus(
-            Duration.standardMinutes(traceLocation.defaultCheckInLengthInMinutes?.toLong() ?: 3L)
-        ),
+        checkInEnd: Instant,
         completed: Boolean = false,
         createJournalEntry: Boolean = true
     ): CheckIn {
@@ -120,7 +121,8 @@ class ConfirmCheckInViewModel @AssistedInject constructor(
         private val checkInEndOffset: Duration,
         val createJournalEntry: Boolean,
         val eventInPastVisible: Boolean,
-        val eventInFutureVisible: Boolean
+        val eventInFutureVisible: Boolean,
+        val confirmButtonEnabled: Boolean
     ) {
         val description get() = traceLocation.description
         val typeRes get() = mapTraceLocationToTitleRes(traceLocation.type)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/edit/EditCheckInFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/edit/EditCheckInFragment.kt
index 0e822c842aca62574fad8ef7c5078b89262a2f97..4f5471d1952764b0b9c54cf3487a93316e08c6f4 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/edit/EditCheckInFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/edit/EditCheckInFragment.kt
@@ -10,6 +10,7 @@ import com.google.android.material.appbar.AppBarLayout
 import com.google.android.material.datepicker.MaterialDatePicker
 import com.google.android.material.timepicker.MaterialTimePicker
 import com.google.android.material.timepicker.TimeFormat
+import com.google.android.material.transition.MaterialContainerTransform
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.FragmentEditCheckInBinding
 import de.rki.coronawarnapp.util.di.AutoInject
@@ -36,6 +37,13 @@ class EditCheckInFragment : Fragment(R.layout.fragment_edit_check_in), AutoInjec
         }
     )
 
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        sharedElementEnterTransition = MaterialContainerTransform()
+        sharedElementReturnTransition = MaterialContainerTransform()
+    }
+
     private val binding: FragmentEditCheckInBinding by viewBindingLazy()
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -71,6 +79,7 @@ class EditCheckInFragment : Fragment(R.layout.fragment_edit_check_in), AutoInjec
             editCheckinConfirmButton.setOnClickListener {
                 viewModel.onSaveClicked()
             }
+            root.transitionName = navArgs.editCheckInId.toString()
         }
 
         viewModel.events.observe2(this) { navEvent ->
@@ -94,7 +103,9 @@ class EditCheckInFragment : Fragment(R.layout.fragment_edit_check_in), AutoInjec
 
                 editCheckinDurationEditHintCard.isGone = !uiState.diaryWarningVisible
 
-                editCheckinConfirmButton.isEnabled = uiState.canSaveChanges
+                editCheckinConfirmButton.isEnabled = uiState.saveButtonEnabled
+
+                editCheckinWrongInputWarning.isGone = !uiState.wrongInputErrorShown
             }
         }
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/edit/EditCheckInViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/edit/EditCheckInViewModel.kt
index a266e7e6d8ab74f5f64edcefa1e50e96e7963c4b..7cfc15b894c9aeb71ae03e455d3deed3ebb896f6 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/edit/EditCheckInViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/edit/EditCheckInViewModel.kt
@@ -14,6 +14,7 @@ import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.filterNotNull
+import org.joda.time.Days
 import org.joda.time.Instant
 import org.joda.time.LocalDate
 import org.joda.time.LocalTime
@@ -33,10 +34,10 @@ class EditCheckInViewModel @AssistedInject constructor(
             val checkIn = checkInRepository.checkInForId(editCheckInId ?: 0)
 
             if (checkInStartTime.value == null) {
-                checkInStartTime.value = checkIn.checkInStart
+                checkInStartTime.value = checkIn.checkInStart.toDateTime().toInstant()
             }
             if (checkInEndTime.value == null) {
-                checkInEndTime.value = checkIn.checkInEnd
+                checkInEndTime.value = checkIn.checkInEnd.toDateTime().toInstant()
             }
 
             checkInFlow.value = checkIn
@@ -50,13 +51,13 @@ class EditCheckInViewModel @AssistedInject constructor(
 
     val uiState = combine(
         checkInFlow.filterNotNull(),
-        checkInStartTime,
-        checkInEndTime
+        checkInStartTime.filterNotNull(),
+        checkInEndTime.filterNotNull()
     ) { checkIn, checkInStartTime, checkInEndTime ->
         UiState(
             checkIn = checkIn,
-            checkInStartInstant = checkInStartTime ?: checkIn.checkInStart,
-            checkInEndInstant = checkInEndTime ?: checkIn.checkInEnd
+            checkInStartInstant = checkInStartTime,
+            checkInEndInstant = checkInEndTime
         )
     }.asLiveData()
 
@@ -144,7 +145,15 @@ class EditCheckInViewModel @AssistedInject constructor(
         val checkInStartTime: String get() = checkInStartInstant.toDateTime().toString(timeFormatter)
         val checkInEndDate: String get() = checkInEndInstant.toDateTime().toString(dateFormatter)
         val checkInEndTime: String get() = checkInEndInstant.toDateTime().toString(timeFormatter)
-        val canSaveChanges: Boolean get() = checkInStartInstant.isBefore(checkInEndInstant)
+        val saveButtonEnabled: Boolean get() = isInputValid()
+        val wrongInputErrorShown: Boolean get() = !saveButtonEnabled
+
+        private fun isInputValid(): Boolean {
+            val startBeforeEnd = checkInStartInstant.isBefore(checkInEndInstant)
+            val lessThan24h = Days.daysBetween(checkInStartInstant, checkInEndInstant).days < 1
+
+            return startBeforeEnd and lessThan24h
+        }
     }
 
     sealed class DateTimePickerEvent {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/onboarding/CheckInOnboardingFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/onboarding/CheckInOnboardingFragment.kt
index c66e18b87292ea60bd1ecf994c8588fe33770faf..1a9eb4cd3eb753544367c454dbdc177f2c9f16c3 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/onboarding/CheckInOnboardingFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/onboarding/CheckInOnboardingFragment.kt
@@ -4,12 +4,14 @@ import android.os.Bundle
 import android.view.View
 import androidx.fragment.app.Fragment
 import androidx.navigation.fragment.navArgs
+import com.google.android.material.transition.MaterialSharedAxis
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.FragmentTraceLocationOnboardingBinding
 import de.rki.coronawarnapp.util.ContextExtensions.getDrawableCompat
 import de.rki.coronawarnapp.util.di.AutoInject
 import de.rki.coronawarnapp.util.ui.doNavigate
 import de.rki.coronawarnapp.util.ui.observe2
+import de.rki.coronawarnapp.util.ui.popBackStack
 import de.rki.coronawarnapp.util.ui.viewBindingLazy
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
 import de.rki.coronawarnapp.util.viewmodel.cwaViewModels
@@ -23,9 +25,20 @@ class CheckInOnboardingFragment : Fragment(R.layout.fragment_trace_location_onbo
     private val binding: FragmentTraceLocationOnboardingBinding by viewBindingLazy()
     private val args by navArgs<CheckInOnboardingFragmentArgs>()
 
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
+        returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
+    }
+
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
 
+        if (viewModel.isOnboardingComplete && args.uri != null) {
+            doNavigate(CheckInOnboardingFragmentDirections.actionCheckInOnboardingFragmentToCheckInsFragment(args.uri))
+        }
+
         with(binding) {
             checkInOnboardingAcknowledge.setOnClickListener { viewModel.onAcknowledged() }
             // TODO if consent is already given: should the text be changed?
@@ -36,7 +49,7 @@ class CheckInOnboardingFragment : Fragment(R.layout.fragment_trace_location_onbo
                 checkInOnboardingToolbar.apply {
                     navigationIcon = context.getDrawableCompat(R.drawable.ic_close)
                     navigationContentDescription = getString(R.string.accessibility_close)
-                    setNavigationOnClickListener { viewModel.onBackButtonPress() }
+                    setNavigationOnClickListener { popBackStack() }
                 }
             }
         }
@@ -45,7 +58,7 @@ class CheckInOnboardingFragment : Fragment(R.layout.fragment_trace_location_onbo
             doNavigate(
                 when (navEvent) {
                     CheckInOnboardingNavigation.AcknowledgedNavigation ->
-                        CheckInOnboardingFragmentDirections.actionCheckInOnboardingFragmentToCheckInsFragment()
+                        CheckInOnboardingFragmentDirections.actionCheckInOnboardingFragmentToCheckInsFragment(args.uri)
                     CheckInOnboardingNavigation.DataProtectionNavigation ->
                         CheckInOnboardingFragmentDirections.actionCheckInOnboardingFragmentToPrivacyFragment()
                 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/category/adapter/category/TraceLocationCategory.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/category/adapter/category/TraceLocationCategory.kt
index 31f49804d9db7fed35bad84e2e5799f301b78d1d..ffcb22118b5d722e610c063325d14e7dd7b5120f 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/category/adapter/category/TraceLocationCategory.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/category/adapter/category/TraceLocationCategory.kt
@@ -19,6 +19,7 @@ import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass
 import de.rki.coronawarnapp.ui.eventregistration.organizer.category.adapter.CategoryItem
 import de.rki.coronawarnapp.ui.eventregistration.organizer.category.adapter.category.TraceLocationUIType.EVENT
 import de.rki.coronawarnapp.ui.eventregistration.organizer.category.adapter.category.TraceLocationUIType.LOCATION
+import kotlinx.parcelize.IgnoredOnParcel
 import kotlinx.parcelize.Parcelize
 
 @Parcelize
@@ -28,7 +29,7 @@ data class TraceLocationCategory(
     @StringRes val title: Int,
     @StringRes val subtitle: Int? = null
 ) : CategoryItem, Parcelable {
-    override val stableId = hashCode().toLong()
+    @IgnoredOnParcel override val stableId = hashCode().toLong()
 }
 
 enum class TraceLocationUIType {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/create/TraceLocationCreateFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/create/TraceLocationCreateFragment.kt
index 69f0567110f5a16412582ac7cdda392f09351ae2..385d826151839cd32662301c8d045d8eef15e153 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/create/TraceLocationCreateFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/create/TraceLocationCreateFragment.kt
@@ -25,7 +25,6 @@ import de.rki.coronawarnapp.util.ui.popBackStack
 import de.rki.coronawarnapp.util.ui.viewBindingLazy
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
 import de.rki.coronawarnapp.util.viewmodel.cwaViewModelsAssisted
-import org.joda.time.DateTimeZone
 import org.joda.time.Duration
 import org.joda.time.LocalDate
 import org.joda.time.LocalDateTime
@@ -47,6 +46,7 @@ class TraceLocationCreateFragment : Fragment(R.layout.trace_location_create_frag
         }
     )
 
+    @Suppress("NestedBlockDepth")
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
 
@@ -121,8 +121,8 @@ class TraceLocationCreateFragment : Fragment(R.layout.trace_location_create_frag
                     placeInputEdit.setText(it.address)
                 }
                 viewModel.apply {
-                    begin = LocalDateTime(it.startDate)
-                    end = LocalDateTime(it.endDate)
+                    begin = it.startDate?.let { time -> LocalDateTime(time) }
+                    end = it.endDate?.let { time -> LocalDateTime(time) }
                     checkInLength = Duration.standardMinutes(it.defaultCheckInLengthInMinutes?.toLong() ?: 0L)
                 }
             }
@@ -159,14 +159,14 @@ class TraceLocationCreateFragment : Fragment(R.layout.trace_location_create_frag
         MaterialDatePicker
             .Builder
             .datePicker()
-            .setSelection(defaultValue?.toDateTime(DateTimeZone.UTC)?.millis)
+            .setSelection(defaultValue?.toDateTime()?.millis)
             .apply {
                 if (minConstraint != null) {
                     setCalendarConstraints(
                         CalendarConstraints.Builder()
                             .setValidator(
                                 DateValidatorPointForward
-                                    .from(minConstraint.withMillisOfDay(0).toDateTime(DateTimeZone.UTC).millis)
+                                    .from(minConstraint.withMillisOfDay(0).toDateTime().millis)
                             )
                             .build()
                     )
@@ -202,7 +202,7 @@ class TraceLocationCreateFragment : Fragment(R.layout.trace_location_create_frag
 
     private fun showDurationPicker() {
         DurationPicker.Builder()
-            .duration(viewModel.checkInLength?.toContactDiaryFormat() ?: "")
+            .duration(viewModel.checkInLength.toContactDiaryFormat())
             .title(getString(R.string.tracelocation_organizer_add_event_length_of_stay))
             .build()
             .apply {
@@ -216,7 +216,7 @@ class TraceLocationCreateFragment : Fragment(R.layout.trace_location_create_frag
     override fun onSaveInstanceState(outState: Bundle) {
         super.onSaveInstanceState(
             outState.apply {
-                putLong(LENGTH_OF_STAY, viewModel.checkInLength?.standardMinutes ?: 0L)
+                putLong(LENGTH_OF_STAY, viewModel.checkInLength.standardMinutes)
                 putSerializable(BEGIN, viewModel.begin)
                 putSerializable(END, viewModel.end)
             }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/create/TraceLocationCreateViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/create/TraceLocationCreateViewModel.kt
index 55a2af7908ad3c6ac7486287e62fb4af892c8a0a..da0c661715bac8e462d43a71c31ca012a5012c24 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/create/TraceLocationCreateViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/create/TraceLocationCreateViewModel.kt
@@ -19,7 +19,6 @@ import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
 import de.rki.coronawarnapp.util.ui.SingleLiveEvent
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
-import org.joda.time.DateTimeZone
 import org.joda.time.Duration
 import org.joda.time.LocalDateTime
 import timber.log.Timber
@@ -64,8 +63,8 @@ class TraceLocationCreateViewModel @AssistedInject constructor(
             type = category.type,
             description = description,
             address = address,
-            startDate = begin?.toDateTime(DateTimeZone.UTC)?.toInstant(),
-            endDate = end?.toDateTime(DateTimeZone.UTC)?.toInstant(),
+            startDate = begin?.toDateTime()?.toInstant(),
+            endDate = end?.toDateTime()?.toInstant(),
             defaultCheckInLengthInMinutes = checkInLength.standardMinutes.toInt()
         )
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/details/QrCodeDetailFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/details/QrCodeDetailFragment.kt
index bd2763bc00c30b84cdc58a650948906d7fa478dd..82521d81b8aa135937772bd9b30e7343f5632cdd 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/details/QrCodeDetailFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/details/QrCodeDetailFragment.kt
@@ -12,6 +12,7 @@ import androidx.navigation.fragment.navArgs
 import com.google.android.material.appbar.AppBarLayout
 import com.google.android.material.appbar.AppBarLayout.OnOffsetChangedListener
 import com.google.android.material.transition.MaterialContainerTransform
+import com.google.android.material.transition.MaterialSharedAxis
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.TraceLocationOrganizerQrCodeDetailFragmentBinding
 import de.rki.coronawarnapp.util.ContextExtensions.getDrawableCompat
@@ -72,25 +73,29 @@ class QrCodeDetailFragment : Fragment(R.layout.trace_location_organizer_qr_code_
             }
 
             qrCodePrintButton.setOnClickListener {
+                exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
+                reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
+
                 viewModel.onPrintQrCode()
             }
-        }
 
-        viewModel.qrCodeBitmap.observe2(this) {
-            binding.progressBar.hide()
-            binding.qrCodeImage.apply {
-                val resourceId = RoundedBitmapDrawableFactory.create(resources, it)
-                resourceId.cornerRadius = it.width * 0.1f
-                setImageDrawable(resourceId)
+            qrCodeCloneButton.setOnClickListener {
+                viewModel.duplicateTraceLocation()
             }
+
+            root.transitionName = navArgs.traceLocationId.toString()
         }
 
         viewModel.routeToScreen.observe2(this) {
             when (it) {
                 QrCodeDetailNavigationEvents.NavigateBack -> popBackStack()
 
-                QrCodeDetailNavigationEvents.NavigateToDuplicateFragment -> { /* TODO */
-                }
+                is QrCodeDetailNavigationEvents.NavigateToDuplicateFragment -> doNavigate(
+                    QrCodeDetailFragmentDirections.actionQrCodeDetailFragmentToTraceLocationCreateFragment(
+                        it.category,
+                        it.traceLocation
+                    )
+                )
 
                 is QrCodeDetailNavigationEvents.NavigateToQrCodePosterFragment -> doNavigate(
                     QrCodeDetailFragmentDirections.actionQrCodeDetailFragmentToQrCodePosterFragment(it.locationId)
@@ -128,6 +133,15 @@ class QrCodeDetailFragment : Fragment(R.layout.trace_location_organizer_qr_code_
                 } else {
                     eventDate.isGone = true
                 }
+
+                uiState.bitmap?.let {
+                    binding.progressBar.hide()
+                    binding.qrCodeImage.apply {
+                        val resourceId = RoundedBitmapDrawableFactory.create(resources, it)
+                        resourceId.cornerRadius = it.width * 0.1f
+                        setImageDrawable(resourceId)
+                    }
+                }
             }
         }
     }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/details/QrCodeDetailNavigationEvents.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/details/QrCodeDetailNavigationEvents.kt
index 68027a1fd55345d94dd670307491137c2f9b8a04..1939ed098a96a614fb192fb6771ee661c6cbb9de 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/details/QrCodeDetailNavigationEvents.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/details/QrCodeDetailNavigationEvents.kt
@@ -1,7 +1,11 @@
 package de.rki.coronawarnapp.ui.eventregistration.organizer.details
 
+import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocation
+import de.rki.coronawarnapp.ui.eventregistration.organizer.category.adapter.category.TraceLocationCategory
+
 sealed class QrCodeDetailNavigationEvents {
     object NavigateBack : QrCodeDetailNavigationEvents()
     data class NavigateToQrCodePosterFragment(val locationId: Long) : QrCodeDetailNavigationEvents()
-    object NavigateToDuplicateFragment : QrCodeDetailNavigationEvents()
+    data class NavigateToDuplicateFragment(val traceLocation: TraceLocation, val category: TraceLocationCategory) :
+        QrCodeDetailNavigationEvents()
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/details/QrCodeDetailViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/details/QrCodeDetailViewModel.kt
index 739078b1e3d5e2716236e7fca68f3bf355c1d141..30f3363daca6adda72f5a868f791d1e571166590 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/details/QrCodeDetailViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/details/QrCodeDetailViewModel.kt
@@ -3,7 +3,6 @@ package de.rki.coronawarnapp.ui.eventregistration.organizer.details
 import android.graphics.Bitmap
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.asLiveData
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
@@ -12,15 +11,14 @@ import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocation
 import de.rki.coronawarnapp.eventregistration.storage.repo.DefaultTraceLocationRepository
 import de.rki.coronawarnapp.exception.ExceptionCategory
 import de.rki.coronawarnapp.exception.reporting.report
+import de.rki.coronawarnapp.ui.eventregistration.organizer.category.adapter.category.traceLocationCategories
 import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
 import de.rki.coronawarnapp.util.ui.SingleLiveEvent
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.filterNotNull
 import org.joda.time.Instant
 import timber.log.Timber
+import java.lang.Exception
 
 class QrCodeDetailViewModel @AssistedInject constructor(
     @Assisted private val traceLocationId: Long,
@@ -29,74 +27,38 @@ class QrCodeDetailViewModel @AssistedInject constructor(
     private val traceLocationRepository: DefaultTraceLocationRepository
 ) : CWAViewModel() {
 
-    private val traceLocationFlow = MutableStateFlow<TraceLocation?>(null)
-    private val titleFlow = MutableStateFlow<String?>(null)
-    private val subtitleFlow = MutableStateFlow<String?>(null)
-    private val startTimeFlow = MutableStateFlow<Instant?>(null)
-    private val endTimeFlow = MutableStateFlow<Instant?>(null)
-    private val bitmapLiveData = MutableLiveData<Bitmap>()
+    private var traceLocation: TraceLocation? = null
+    private val mutableUiState = MutableLiveData<UiState>()
+    val uiState: LiveData<UiState>
+        get() = mutableUiState
+    val routeToScreen: SingleLiveEvent<QrCodeDetailNavigationEvents> = SingleLiveEvent()
 
     init {
-
         launch {
-            val traceLocation = traceLocationRepository.traceLocationForId(traceLocationId)
-
-            if (titleFlow.value == null) {
-                titleFlow.value = traceLocation.description
-            }
-
-            if (subtitleFlow.value == null) {
-                subtitleFlow.value = traceLocation.address
-            }
-
-            if (startTimeFlow.value == null) {
-                startTimeFlow.value = traceLocation.startDate
-            }
-
-            if (endTimeFlow.value == null) {
-                endTimeFlow.value = traceLocation.endDate
-            }
-
-            traceLocationFlow.value = traceLocation
-
-            createQrCode(traceLocation)
+            loadTraceLocation()
         }
     }
 
-    val uiState = combine(
-        traceLocationFlow.filterNotNull(),
-        startTimeFlow,
-        endTimeFlow
-    ) { traceLocation, startTime, endTime ->
-        UiState(
-            traceLocation = traceLocation,
-            startInstant = startTime ?: traceLocation.startDate,
-            endInstant = endTime ?: traceLocation.endDate
-        )
-    }.asLiveData()
-
-    data class UiState(
-        private val traceLocation: TraceLocation,
-        private val startInstant: Instant?,
-        private val endInstant: Instant?
-    ) {
-        val description: String get() = traceLocation.description
-        val address: String get() = traceLocation.address
-        val startDateTime: Instant? get() = startInstant
-        val endDateTime: Instant? get() = endInstant
+    private suspend fun loadTraceLocation() {
+        try {
+            traceLocation = traceLocationRepository.traceLocationForId(traceLocationId).also {
+                mutableUiState.postValue(UiState(it))
+                createQrCode(it)
+            }
+        } catch (exception: Exception) {
+            Timber.d(exception, "No location found")
+            exception.report(ExceptionCategory.INTERNAL)
+        }
     }
 
-    val qrCodeBitmap: LiveData<Bitmap> = bitmapLiveData
-    val routeToScreen: SingleLiveEvent<QrCodeDetailNavigationEvents> = SingleLiveEvent()
-
     /**
-     * Creates a QR Code [Bitmap] ,result is delivered by [qrCodeBitmap]
+     * Creates a QR Code [Bitmap] ,result is delivered by [uiState]
      */
     private fun createQrCode(traceLocation: TraceLocation) = launch(context = dispatcher.IO) {
         try {
             val input = traceLocation.locationUrl
             Timber.d("input=$input")
-            bitmapLiveData.postValue(qrCodeGenerator.createQrCode(input))
+            mutableUiState.postValue(UiState(traceLocation, qrCodeGenerator.createQrCode(input)))
         } catch (e: Exception) {
             Timber.d(e, "Qr code creation failed")
             e.report(ExceptionCategory.INTERNAL)
@@ -113,6 +75,27 @@ class QrCodeDetailViewModel @AssistedInject constructor(
         )
     }
 
+    fun duplicateTraceLocation() {
+        traceLocation?.let {
+            val category = traceLocationCategories.find { category -> category.type == it.type }
+            if (category == null) {
+                Timber.e("Category not found, traceLocation = $traceLocation")
+            } else {
+                routeToScreen.postValue(QrCodeDetailNavigationEvents.NavigateToDuplicateFragment(it, category))
+            }
+        }
+    }
+
+    data class UiState(
+        private val traceLocation: TraceLocation,
+        val bitmap: Bitmap? = null
+    ) {
+        val description: String get() = traceLocation.description
+        val address: String get() = traceLocation.address
+        val startDateTime: Instant? get() = traceLocation.startDate
+        val endDateTime: Instant? get() = traceLocation.endDate
+    }
+
     @AssistedFactory
     interface Factory : CWAViewModelFactory<QrCodeDetailViewModel> {
         fun create(
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/list/TraceLocationEvent.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/list/TraceLocationEvent.kt
index 5909c982933269feaeeb47a6fa3d1f3aebc0e2f8..a4576f0ae318ae641605d530e667d128c0bae926 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/list/TraceLocationEvent.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/list/TraceLocationEvent.kt
@@ -6,6 +6,8 @@ sealed class TraceLocationEvent {
 
     data class DuplicateItem(val traceLocation: TraceLocation) : TraceLocationEvent()
 
+    data class SelfCheckIn(val traceLocation: TraceLocation) : TraceLocationEvent()
+
     data class ConfirmDeleteItem(val traceLocation: TraceLocation) : TraceLocationEvent()
 
     data class ConfirmSwipeItem(val traceLocation: TraceLocation, val position: Int) : TraceLocationEvent()
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/list/TraceLocationsFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/list/TraceLocationsFragment.kt
index 1847e8f7b3912ec7198198b0986705753f2e1952..32fccb915730437caa226c162b27f14acfd248d6 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/list/TraceLocationsFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/list/TraceLocationsFragment.kt
@@ -7,12 +7,15 @@ import androidx.appcompat.app.AlertDialog
 import androidx.appcompat.widget.Toolbar
 import androidx.core.view.isGone
 import androidx.fragment.app.Fragment
+import androidx.navigation.NavOptions
 import androidx.navigation.fragment.FragmentNavigatorExtras
 import androidx.navigation.fragment.findNavController
 import com.google.android.material.transition.Hold
+import com.google.android.material.transition.MaterialSharedAxis
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.TraceLocationOrganizerTraceLocationsListFragmentBinding
 import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocation
+import de.rki.coronawarnapp.ui.eventregistration.attendee.checkins.CheckInsFragment
 import de.rki.coronawarnapp.ui.eventregistration.organizer.category.adapter.category.traceLocationCategories
 import de.rki.coronawarnapp.ui.eventregistration.organizer.details.QrCodeDetailFragmentArgs
 import de.rki.coronawarnapp.util.DialogHelper
@@ -40,7 +43,9 @@ class TraceLocationsFragment : Fragment(R.layout.trace_location_organizer_trace_
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
-        exitTransition = Hold()
+
+        enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
+        returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
     }
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -82,11 +87,9 @@ class TraceLocationsFragment : Fragment(R.layout.trace_location_organizer_trace_
                     showDeleteSingleDialog(it.traceLocation, it.position)
                 }
                 is TraceLocationEvent.StartQrCodeDetailFragment -> {
-
+                    setupHoldTransition()
                     val navigatorExtras = binding.recyclerView.findViewHolderForAdapterPosition(it.position)?.itemView
                         ?.run {
-                            // Set it on the fly to avoid confusion of recycler's items
-                            this.transitionName = "trace_location_container_transition"
                             FragmentNavigatorExtras(this to this.transitionName)
                         }
 
@@ -98,18 +101,33 @@ class TraceLocationsFragment : Fragment(R.layout.trace_location_organizer_trace_
                     )
                 }
                 is TraceLocationEvent.DuplicateItem -> {
+                    setupAxisTransition()
                     openCreateEventFragment(it.traceLocation)
                 }
-                is TraceLocationEvent.StartQrCodePosterFragment -> doNavigate(
-                    TraceLocationsFragmentDirections.actionTraceLocationsFragmentToQrCodePosterFragment(
-                        it.traceLocation.id
+                is TraceLocationEvent.StartQrCodePosterFragment -> {
+                    setupAxisTransition()
+                    doNavigate(
+
+                        TraceLocationsFragmentDirections.actionTraceLocationsFragmentToQrCodePosterFragment(
+                            it.traceLocation.id
+                        )
                     )
-                )
+                }
+
+                is TraceLocationEvent.SelfCheckIn -> {
+                    findNavController().navigate(
+                        CheckInsFragment.createCheckInUri(it.traceLocation.locationUrl),
+                        NavOptions.Builder()
+                            .setPopUpTo(R.id.checkInsFragment, true)
+                            .build()
+                    )
+                }
             }
         }
 
         binding.qrCodeFab.apply {
             setOnClickListener {
+                setupHoldTransition()
                 findNavController().navigate(
                     R.id.action_traceLocationsFragment_to_traceLocationCategoryFragment,
                     null,
@@ -120,6 +138,16 @@ class TraceLocationsFragment : Fragment(R.layout.trace_location_organizer_trace_
         }
     }
 
+    private fun setupHoldTransition() {
+        exitTransition = Hold()
+        reenterTransition = Hold()
+    }
+
+    private fun setupAxisTransition() {
+        exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
+        reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
+    }
+
     override fun onResume() {
         super.onResume()
         binding.contentContainer.sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT)
@@ -130,6 +158,7 @@ class TraceLocationsFragment : Fragment(R.layout.trace_location_organizer_trace_
         setOnMenuItemClickListener {
             when (it.itemId) {
                 R.id.menu_information -> {
+                    setupAxisTransition()
                     findNavController().navigate(
                         R.id.action_traceLocationOrganizerListFragment_to_traceLocationInfoFragment
                     )
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/list/TraceLocationsViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/list/TraceLocationsViewModel.kt
index d4167ccd56634c989b0e015f00cffb71b9aeebaa..e00d80c9b5d4e9293c70382f3fda8a941c0de911 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/list/TraceLocationsViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/list/TraceLocationsViewModel.kt
@@ -4,36 +4,44 @@ import androidx.lifecycle.LiveData
 import androidx.lifecycle.asLiveData
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
+import de.rki.coronawarnapp.eventregistration.checkins.CheckInRepository
 import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocation
 import de.rki.coronawarnapp.eventregistration.storage.repo.TraceLocationRepository
 import de.rki.coronawarnapp.ui.eventregistration.organizer.list.items.TraceLocationItem
 import de.rki.coronawarnapp.ui.eventregistration.organizer.list.items.TraceLocationVH
-import de.rki.coronawarnapp.util.TimeStamper
 import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
 import de.rki.coronawarnapp.util.ui.SingleLiveEvent
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
 import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.map
 
 class TraceLocationsViewModel @AssistedInject constructor(
     dispatcherProvider: DispatcherProvider,
+    checkInsRepository: CheckInRepository,
     private val traceLocationRepository: TraceLocationRepository,
-    private val timeStamper: TimeStamper
 ) : CWAViewModel(dispatcherProvider = dispatcherProvider) {
 
     val events = SingleLiveEvent<TraceLocationEvent>()
 
-    val traceLocations: LiveData<List<TraceLocationItem>> = traceLocationRepository.allTraceLocations
+    val traceLocations: LiveData<List<TraceLocationItem>> = traceLocationRepository.traceLocationsWithinRetention
         .map { traceLocations ->
-            traceLocations
-                .filter { it.endDate == null || it.endDate.isAfter(timeStamper.nowUTC.toDateTime().minusDays(15)) }
-                .sortedBy { it.description }
+            traceLocations.sortedBy { it.description }
         }
-        .map { traceLocations ->
+        .combine(checkInsRepository.allCheckIns) { traceLocations, checkIns ->
             traceLocations.map { traceLocation ->
+                Pair(
+                    traceLocation,
+                    checkIns.firstOrNull { traceLocation.locationId == it.traceLocationId && !it.completed } == null
+                )
+            }
+        }
+        .map { traceLocations ->
+            traceLocations.map { item ->
                 TraceLocationVH.Item(
-                    traceLocation = traceLocation,
-                    onCheckIn = { /* TODO */ },
+                    traceLocation = item.first,
+                    canCheckIn = item.second,
+                    onCheckIn = { events.postValue(TraceLocationEvent.SelfCheckIn(it)) },
                     onDuplicate = { events.postValue(TraceLocationEvent.DuplicateItem(it)) },
                     onShowPrint = { events.postValue(TraceLocationEvent.StartQrCodePosterFragment(it)) },
                     onDeleteItem = { events.postValue(TraceLocationEvent.ConfirmDeleteItem(it)) },
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/list/items/TraceLocationVH.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/list/items/TraceLocationVH.kt
index da8cca4747fd735671ea02fdfed288116addb87a..7a1f9a80aa342f55f77f772262c52328be1c6564 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/list/items/TraceLocationVH.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/list/items/TraceLocationVH.kt
@@ -2,6 +2,7 @@ package de.rki.coronawarnapp.ui.eventregistration.organizer.list.items
 
 import android.view.ViewGroup
 import androidx.core.view.isGone
+import androidx.core.view.isVisible
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.TraceLocationOrganizerTraceLocationsItemBinding
 import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocation
@@ -34,11 +35,11 @@ class TraceLocationVH(parent: ViewGroup) :
 
             duration.isGone = false
             duration.text = if (startTime.toLocalDate() == endTime.toLocalDate()) {
-                icon.setCaption(startTime.toString("dd.MM.yy"))
                 context.getString(
-                    R.string.trace_location_organizer_list_item_duration,
-                    startTime.toLocalTime().toString("HH:mm"),
-                    endTime.toLocalTime().toString("HH:mm")
+                    R.string.trace_location_organizer_list_item_duration_same_day,
+                    startTime.toString("dd.MM.yy"),
+                    startTime.toString("HH:mm"),
+                    endTime.toString("HH:mm")
                 )
             } else {
                 icon.setCaption(null)
@@ -62,12 +63,17 @@ class TraceLocationVH(parent: ViewGroup) :
             }
         }
 
+        checkinAction.isVisible = item.canCheckIn
         checkinAction.setOnClickListener { item.onCheckIn(item.traceLocation) }
-        itemView.setOnClickListener { item.onCardClicked(item.traceLocation, adapterPosition) }
+        itemView.apply {
+            setOnClickListener { item.onCardClicked(item.traceLocation, adapterPosition) }
+            transitionName = item.traceLocation.id.toString()
+        }
     }
 
     data class Item(
         val traceLocation: TraceLocation,
+        val canCheckIn: Boolean,
         val onCheckIn: (TraceLocation) -> Unit,
         val onDuplicate: (TraceLocation) -> Unit,
         val onShowPrint: (TraceLocation) -> Unit,
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/poster/QrCodePosterFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/poster/QrCodePosterFragment.kt
index b5840444875465bb97ae4112c546b037c8686b89..1a526d2770b001a4af2011ce29b83b7476a7eb17 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/poster/QrCodePosterFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/poster/QrCodePosterFragment.kt
@@ -12,6 +12,7 @@ import androidx.core.content.getSystemService
 import androidx.core.widget.TextViewCompat
 import androidx.fragment.app.Fragment
 import androidx.navigation.fragment.navArgs
+import com.google.android.material.transition.MaterialSharedAxis
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.QrCodePosterFragmentBinding
 import de.rki.coronawarnapp.exception.ExceptionCategory
@@ -44,6 +45,13 @@ class QrCodePosterFragment : Fragment(R.layout.qr_code_poster_fragment), AutoInj
 
     private val binding: QrCodePosterFragmentBinding by viewBindingLazy()
 
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
+        returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
+    }
+
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/qrinfo/TraceLocationQRInfoFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/qrinfo/TraceLocationQRInfoFragment.kt
index 1474fe53afc7a68b2c02942654624992747acb58..f454e6d41507365359bd1cb60c002d432e01e4c1 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/qrinfo/TraceLocationQRInfoFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/organizer/qrinfo/TraceLocationQRInfoFragment.kt
@@ -5,6 +5,7 @@ import android.view.View
 import androidx.core.net.toUri
 import androidx.fragment.app.Fragment
 import androidx.navigation.fragment.findNavController
+import com.google.android.material.transition.MaterialSharedAxis
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.TraceLocationOrganizerQrCodeInfoFragmentBinding
 import de.rki.coronawarnapp.ui.eventregistration.organizer.TraceLocationOrganizerSettings
@@ -26,6 +27,13 @@ class TraceLocationQRInfoFragment : Fragment(R.layout.trace_location_organizer_q
     @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
     private val vm: TraceLocationQRInfoViewModel by cwaViewModels { viewModelFactory }
 
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
+        returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
+    }
+
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
         binding.apply {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivityViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivityViewModel.kt
index 4b534fb0eda9941b9cda93f24b1e6a24c7617f6f..7b8d11a2af4cee4a59ee4afdb404fc07d4302109 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivityViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivityViewModel.kt
@@ -42,7 +42,7 @@ class MainActivityViewModel @AssistedInject constructor(
     private val mutableIsTraceLocationOnboardingDone = MutableLiveData<Boolean>()
     val isTraceLocationOnboardingDone: LiveData<Boolean> = mutableIsTraceLocationOnboardingDone
 
-    val activeCheckIns = checkInRepository.allCheckIns
+    val activeCheckIns = checkInRepository.checkInsWithinRetention
         .map { checkins -> checkins.filter { !it.completed }.size }
         .asLiveData(context = dispatcherProvider.Default)
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DataReset.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DataReset.kt
index 28d72a5afa6bf54b0aa7bb9dacd06d60a0dc853f..efbc89f6af264e192cf7cf28b39f953de9e2da43 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DataReset.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DataReset.kt
@@ -16,6 +16,7 @@ import de.rki.coronawarnapp.eventregistration.checkins.CheckInRepository
 import de.rki.coronawarnapp.eventregistration.storage.repo.TraceLocationRepository
 import de.rki.coronawarnapp.main.CWASettings
 import de.rki.coronawarnapp.nearby.modules.detectiontracker.ExposureDetectionTracker
+import de.rki.coronawarnapp.presencetracing.warning.storage.TraceWarningRepository
 import de.rki.coronawarnapp.risk.storage.RiskLevelStorage
 import de.rki.coronawarnapp.statistics.source.StatisticsProvider
 import de.rki.coronawarnapp.storage.OnboardingSettings
@@ -57,7 +58,8 @@ class DataReset @Inject constructor(
     private val submissionSettings: SubmissionSettings,
     private val traceLocationRepository: TraceLocationRepository,
     private val checkInRepository: CheckInRepository,
-    private val traceLocationSettings: TraceLocationSettings
+    private val traceLocationSettings: TraceLocationSettings,
+    private val traceWarningRepository: TraceWarningRepository,
 ) {
 
     private val mutex = Mutex()
@@ -96,6 +98,7 @@ class DataReset @Inject constructor(
 
         bugReportingSettings.clear()
 
+        traceWarningRepository.clear()
         traceLocationRepository.deleteAllTraceLocations()
         checkInRepository.clear()
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/database/CommonConverters.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/database/CommonConverters.kt
index 92a26a40aa5248039f8ec83ac3422ec7ea9b874a..4c30c5eb0baa94bba40db9ee9e4061f6b0237b17 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/database/CommonConverters.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/database/CommonConverters.kt
@@ -4,7 +4,9 @@ import androidx.room.TypeConverter
 import com.google.gson.Gson
 import com.google.gson.reflect.TypeToken
 import de.rki.coronawarnapp.diagnosiskeys.server.LocationCode
+import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocationId
 import de.rki.coronawarnapp.util.serialization.fromJson
+import okio.ByteString.Companion.decodeBase64
 import org.joda.time.Instant
 import org.joda.time.LocalDate
 import org.joda.time.LocalTime
@@ -68,4 +70,10 @@ class CommonConverters {
 
     @TypeConverter
     fun fromLocationCode(code: LocationCode?): String? = code?.identifier
+
+    @TypeConverter
+    fun toTraceLocationId(value: String?): TraceLocationId? = value?.decodeBase64()
+
+    @TypeConverter
+    fun fromTraceLocationId(traceLocationId: TraceLocationId?): String? = traceLocationId?.base64()
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/device/DefaultSystemInfoProvider.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/device/DefaultSystemInfoProvider.kt
index 5a8fccf5f9f309fadafdfb33c012833a41e394ad..8712735b3f2a5a97fb687de0711533f6c5a1dd18 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/device/DefaultSystemInfoProvider.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/device/DefaultSystemInfoProvider.kt
@@ -1,12 +1,11 @@
 package de.rki.coronawarnapp.util.device
 
-import android.content.Context
 import android.content.res.Resources
 import android.os.Build
 import java.util.Locale
 import javax.inject.Inject
 
-class DefaultSystemInfoProvider @Inject constructor(context: Context) : SystemInfoProvider {
+class DefaultSystemInfoProvider @Inject constructor() : SystemInfoProvider {
 
     override val locale: Locale
         get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterInformationLegalHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterInformationLegalHelper.kt
index 6a8e220b8486603651dae1ec54f7ad6f67ef1a33..72bdddee2b38640b442ac4aee9d0cb728a6690d7 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterInformationLegalHelper.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterInformationLegalHelper.kt
@@ -2,7 +2,6 @@
 
 package de.rki.coronawarnapp.util.formatter
 
-import android.content.Context
 import android.view.View
 import de.rki.coronawarnapp.ui.information.InformationLegalPresentation
 import de.rki.coronawarnapp.util.device.DefaultSystemInfoProvider
@@ -15,10 +14,9 @@ import de.rki.coronawarnapp.util.device.DefaultSystemInfoProvider
  */
 
 fun formatVisibilityLanguageBased(
-    context: Context,
     isContactFormView: Boolean?
 ): Int {
-    InformationLegalPresentation(DefaultSystemInfoProvider(context)).apply {
+    InformationLegalPresentation(DefaultSystemInfoProvider()).apply {
         if (!showBackupLinkToContactForm) {
             return if (isContactFormView == true) {
                 View.VISIBLE
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/DiagnosisTestResultRetrievalPeriodicWorker.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/DiagnosisTestResultRetrievalPeriodicWorker.kt
index 348777db1e7947374017e72c7a262459deeee0a5..0b719ddd8021c35549a621f4c051c423cdf07c26 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/DiagnosisTestResultRetrievalPeriodicWorker.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/DiagnosisTestResultRetrievalPeriodicWorker.kt
@@ -95,6 +95,8 @@ class DiagnosisTestResultRetrievalPeriodicWorker @AssistedInject constructor(
             tracingSettings.initialPollingForTestResultTimeStamp,
             currentMillis
         )
+        Timber.tag(TAG).d("Calculated days: %d", calculateDays)
+
         if (calculateDays >= BackgroundConstants.POLLING_VALIDITY_MAX_DAYS) {
             Timber.tag(TAG)
                 .d(" $id Maximum of ${BackgroundConstants.POLLING_VALIDITY_MAX_DAYS} days for polling exceeded.")
diff --git a/Corona-Warn-App/src/main/res/layout/fragment_confirm_check_in.xml b/Corona-Warn-App/src/main/res/layout/fragment_confirm_check_in.xml
index b179c9fcb9fb183b95db937bf6908e7f289ee40b..4473a4a36525220e724360fd058d988259918a9c 100644
--- a/Corona-Warn-App/src/main/res/layout/fragment_confirm_check_in.xml
+++ b/Corona-Warn-App/src/main/res/layout/fragment_confirm_check_in.xml
@@ -206,9 +206,9 @@
                         android:background="?android:attr/listDivider" />
 
                     <androidx.constraintlayout.widget.ConstraintLayout
+                        android:id="@+id/confirm_checkin_settings_card_checkout_time_row"
                         android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:orientation="horizontal">
+                        android:layout_height="wrap_content">
 
                         <TextView
                             style="@style/body2"
@@ -262,4 +262,4 @@
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent" />
 
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/Corona-Warn-App/src/main/res/layout/fragment_edit_check_in.xml b/Corona-Warn-App/src/main/res/layout/fragment_edit_check_in.xml
index 89f49d4ca8894f916057eb240bc49c8f5f93f857..c81751a1d61be0f975de25004fc941fcc2f3bb90 100644
--- a/Corona-Warn-App/src/main/res/layout/fragment_edit_check_in.xml
+++ b/Corona-Warn-App/src/main/res/layout/fragment_edit_check_in.xml
@@ -223,7 +223,6 @@
                     style="@style/Card.NoElevation"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:layout_marginBottom="24dp"
                     android:layout_marginHorizontal="@dimen/spacing_normal"
                     android:layout_marginTop="@dimen/spacing_tiny">
 
@@ -234,6 +233,17 @@
                         android:text="@string/edit_checkin_duration_edit_hint_card_text" />
                 </LinearLayout>
 
+                <TextView
+                    android:id="@+id/edit_checkin_wrong_input_warning"
+                    style="@style/body2"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginHorizontal="@dimen/spacing_normal"
+                    android:layout_marginTop="@dimen/spacing_tiny"
+                    android:text="@string/edit_checkin_wrong_input_warning_text"
+                    android:textColor="@color/colorTextSemanticRed"
+                    android:visibility="gone" />
+
             </LinearLayout>
 
         </androidx.core.widget.NestedScrollView>
diff --git a/Corona-Warn-App/src/main/res/layout/fragment_settings_tracing.xml b/Corona-Warn-App/src/main/res/layout/fragment_settings_tracing.xml
index de95af0364cb3e978990aa01ff4e975c10982a87..95ba2919e5222e310134520cb6fb1d7e250f2d40 100644
--- a/Corona-Warn-App/src/main/res/layout/fragment_settings_tracing.xml
+++ b/Corona-Warn-App/src/main/res/layout/fragment_settings_tracing.xml
@@ -177,6 +177,7 @@
                         android:id="@+id/settings_tracing_status_bluetooth"
                         gone="@{!settingsTracingState.isBluetoothCardVisible()}"
                         layout="@layout/include_tracing_status_card"
+                        android:layout_marginBottom="@dimen/spacing_small"
                         android:layout_width="0dp"
                         android:layout_height="wrap_content"
                         app:body="@{@string/settings_tracing_status_bluetooth_body}"
@@ -193,6 +194,7 @@
                         android:layout_width="0dp"
                         android:layout_height="wrap_content"
                         android:focusable="false"
+                        android:layout_marginTop="@dimen/spacing_small"
                         android:text="@string/risk_details_headline_period_logged"
                         app:layout_constraintEnd_toStartOf="@id/guideline_end"
                         app:layout_constraintStart_toStartOf="@id/guideline_start"
@@ -213,7 +215,6 @@
                     <TextView
                         android:id="@id/risk_details_period_logged_body_notice"
                         style="@style/subtitle"
-                        gone="@{!settingsTracingState.isTracingStatusTextVisible()}"
                         android:layout_width="0dp"
                         android:layout_height="wrap_content"
                         android:layout_marginTop="@dimen/spacing_normal"
@@ -226,7 +227,6 @@
                     <TextView
                         android:id="@+id/risk_details_period_logged_days"
                         style="@style/subtitle"
-                        gone="@{!settingsTracingState.isTracingStatusTextVisible()}"
                         android:layout_width="0dp"
                         android:layout_height="wrap_content"
                         android:layout_marginTop="@dimen/spacing_normal"
diff --git a/Corona-Warn-App/src/main/res/layout/fragment_trace_location_onboarding.xml b/Corona-Warn-App/src/main/res/layout/fragment_trace_location_onboarding.xml
index 8100354a0dc61451dc5d49bc5adf28237a694085..3d8399ed798a5a067a043be3e65539c5df86eccb 100644
--- a/Corona-Warn-App/src/main/res/layout/fragment_trace_location_onboarding.xml
+++ b/Corona-Warn-App/src/main/res/layout/fragment_trace_location_onboarding.xml
@@ -2,7 +2,8 @@
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:background="@color/colorBackground">
 
     <com.google.android.material.appbar.MaterialToolbar
         android:id="@+id/check_in_onboarding_toolbar"
@@ -19,36 +20,36 @@
         style="@style/buttonPrimary"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:text="@string/trace_location_onboarding_body_confirm"
         android:layout_marginHorizontal="24dp"
         android:layout_marginBottom="24dp"
+        android:text="@string/trace_location_onboarding_body_confirm"
+        app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent"/>
+        app:layout_constraintStart_toStartOf="parent" />
 
     <androidx.core.widget.NestedScrollView
         android:id="@+id/check_in_onboarding_scroll_view"
         android:layout_width="match_parent"
         android:layout_height="0dp"
         android:layout_marginBottom="20dp"
-        app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_toolbar"
-        app:layout_constraintBottom_toTopOf="@+id/check_in_onboarding_acknowledge" >
+        app:layout_constraintBottom_toTopOf="@+id/check_in_onboarding_acknowledge"
+        app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_toolbar">
 
         <androidx.constraintlayout.widget.ConstraintLayout
             android:layout_width="match_parent"
-            android:layout_height="wrap_content" >
+            android:layout_height="wrap_content">
 
             <ImageView
                 android:id="@+id/check_in_onboarding_image"
                 android:layout_width="0dp"
                 android:layout_height="190dp"
-                android:src="@drawable/trace_location_onboarding"
                 android:layout_marginHorizontal="24dp"
                 android:layout_marginTop="4dp"
                 android:contentDescription="@string/trace_location_onboarding_content_description"
-                app:layout_constraintTop_toTopOf="parent"
+                android:src="@drawable/trace_location_onboarding"
                 app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintStart_toStartOf="parent" />
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent" />
 
             <TextView
                 android:id="@+id/check_in_onboarding_title"
@@ -56,11 +57,11 @@
                 android:layout_width="0dp"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center"
-                android:layout_marginTop="24dp"
                 android:layout_marginHorizontal="24dp"
+                android:layout_marginTop="24dp"
                 android:text="@string/trace_location_onboarding_title2"
-                app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_image" />
 
             <TextView
@@ -68,11 +69,11 @@
                 style="@style/subtitleMedium"
                 android:layout_width="0dp"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="22dp"
                 android:layout_marginHorizontal="24dp"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintEnd_toEndOf="parent"
+                android:layout_marginTop="22dp"
                 android:text="@string/trace_location_onboarding_subheadline"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_title" />
 
             <ImageView
@@ -83,8 +84,8 @@
                 android:layout_marginTop="@dimen/spacing_large"
                 android:importantForAccessibility="no"
                 android:src="@drawable/ic_qr_tracing_static"
-                app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_subtitle"
-                app:layout_constraintStart_toStartOf="parent" />
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_subtitle" />
 
             <TextView
                 android:id="@+id/check_in_onboarding_warning"
@@ -93,9 +94,9 @@
                 android:layout_height="wrap_content"
                 android:layout_marginHorizontal="16dp"
                 android:text="@string/trace_location_onboarding_body_warning"
-                app:layout_constraintTop_toTopOf="@id/check_in_warning_image"
+                app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toEndOf="@id/check_in_warning_image"
-                app:layout_constraintEnd_toEndOf="parent" />
+                app:layout_constraintTop_toTopOf="@id/check_in_warning_image" />
 
             <ImageView
                 android:id="@+id/check_in_stay_image"
@@ -105,8 +106,8 @@
                 android:layout_marginTop="@dimen/spacing_medium"
                 android:importantForAccessibility="no"
                 android:src="@drawable/ic_qr_time"
-                app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_warning"
-                app:layout_constraintStart_toStartOf="parent" />
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_warning" />
 
             <TextView
                 android:id="@+id/check_in_onboarding_stay"
@@ -115,17 +116,17 @@
                 android:layout_height="wrap_content"
                 android:layout_marginHorizontal="16dp"
                 android:text="@string/trace_location_onboarding_body_stay"
-                app:layout_constraintTop_toTopOf="@id/check_in_stay_image"
+                app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toEndOf="@id/check_in_warning_image"
-                app:layout_constraintEnd_toEndOf="parent" />
+                app:layout_constraintTop_toTopOf="@id/check_in_stay_image" />
 
             <androidx.constraintlayout.widget.ConstraintLayout
                 android:id="@+id/check_in_onboarding_card_container"
                 style="@style/cardTracing"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="24dp"
                 android:layout_marginHorizontal="24dp"
+                android:layout_marginTop="24dp"
                 android:background="#F5F5F5"
                 android:orientation="vertical"
                 app:layout_constraintEnd_toEndOf="parent"
@@ -146,20 +147,20 @@
                     style="@style/subtitle"
                     android:layout_width="0dp"
                     android:layout_height="wrap_content"
-                    android:text="@string/trace_location_onboarding_body_intro"
                     android:layout_marginTop="4dp"
-                    app:layout_constraintStart_toStartOf="parent"
+                    android:text="@string/trace_location_onboarding_body_intro"
                     app:layout_constraintEnd_toEndOf="parent"
+                    app:layout_constraintStart_toStartOf="parent"
                     app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_card_title" />
 
                 <ImageView
                     android:id="@+id/check_in_onboarding_bulletpoint1"
                     android:layout_width="8dp"
                     android:layout_height="8dp"
-                    android:src="@drawable/bullet_point"
                     android:layout_marginTop="24dp"
-                    app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_card_subtitle"
-                    app:layout_constraintStart_toStartOf="parent" />
+                    android:src="@drawable/bullet_point"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_card_subtitle" />
 
                 <TextView
                     android:id="@+id/check_in_onboarding_body2"
@@ -169,8 +170,8 @@
                     android:layout_marginStart="15dp"
                     android:layout_marginTop="16dp"
                     android:focusable="true"
-                    android:textStyle="bold"
                     android:text="@string/trace_location_onboarding_body_consent2"
+                    android:textStyle="bold"
                     app:layout_constraintEnd_toEndOf="parent"
                     app:layout_constraintStart_toEndOf="@id/check_in_onboarding_bulletpoint1"
                     app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_card_subtitle" />
@@ -192,10 +193,10 @@
                     android:id="@+id/check_in_onboarding_bulletpoint2"
                     android:layout_width="8dp"
                     android:layout_height="8dp"
-                    android:src="@drawable/bullet_point"
                     android:layout_marginTop="22dp"
-                    app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_body3"
-                    app:layout_constraintStart_toStartOf="parent" />
+                    android:src="@drawable/bullet_point"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_body3" />
 
                 <TextView
                     android:id="@+id/check_in_onboarding_body4"
@@ -205,8 +206,8 @@
                     android:layout_marginStart="15dp"
                     android:layout_marginTop="16dp"
                     android:focusable="true"
-                    android:textStyle="bold"
                     android:text="@string/trace_location_onboarding_body_consent4"
+                    android:textStyle="bold"
                     app:layout_constraintEnd_toEndOf="parent"
                     app:layout_constraintStart_toEndOf="@id/check_in_onboarding_bulletpoint2"
                     app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_body3" />
@@ -215,10 +216,10 @@
                     android:id="@+id/check_in_onboarding_bulletpoint3"
                     android:layout_width="8dp"
                     android:layout_height="8dp"
-                    android:src="@drawable/bullet_point"
                     android:layout_marginTop="22dp"
-                    app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_body4"
-                    app:layout_constraintStart_toStartOf="parent" />
+                    android:src="@drawable/bullet_point"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_body4" />
 
                 <TextView
                     android:id="@+id/check_in_onboarding_body5"
@@ -228,8 +229,8 @@
                     android:layout_marginStart="15dp"
                     android:layout_marginTop="16dp"
                     android:focusable="true"
-                    android:textStyle="bold"
                     android:text="@string/trace_location_onboarding_body_consent5"
+                    android:textStyle="bold"
                     app:layout_constraintEnd_toEndOf="parent"
                     app:layout_constraintStart_toEndOf="@id/check_in_onboarding_bulletpoint3"
                     app:layout_constraintTop_toBottomOf="@id/check_in_onboarding_body4" />
@@ -255,8 +256,8 @@
                 android:layout_marginHorizontal="24dp"
                 android:layout_marginTop="30dp"
                 android:focusable="true"
-                app:titleText="@string/contact_diary_onboarding_legal_information"
-                app:layout_constraintTop_toBottomOf="@+id/check_in_onboarding_card_container"/>
+                app:layout_constraintTop_toBottomOf="@+id/check_in_onboarding_card_container"
+                app:titleText="@string/contact_diary_onboarding_legal_information" />
         </androidx.constraintlayout.widget.ConstraintLayout>
     </androidx.core.widget.NestedScrollView>
 
diff --git a/Corona-Warn-App/src/main/res/layout/include_contact_form.xml b/Corona-Warn-App/src/main/res/layout/include_contact_form.xml
index 0f3654c19de12d7e5f914941da5ed8361c447bc5..0af8211cc6d358a0b26c03d88cbfbc6cf44749e9 100644
--- a/Corona-Warn-App/src/main/res/layout/include_contact_form.xml
+++ b/Corona-Warn-App/src/main/res/layout/include_contact_form.xml
@@ -28,7 +28,7 @@
                 android:linksClickable="true"
                 android:text="@string/information_legal_subtitle_contact_label"
                 android:textColorLink="@color/colorTextTint"
-                android:visibility="@{FormatterInformationLegalHelper.formatVisibilityLanguageBased(context, true)}"
+                android:visibility="@{FormatterInformationLegalHelper.formatVisibilityLanguageBased(true)}"
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintTop_toTopOf="parent" />
 
@@ -42,7 +42,7 @@
                 android:linksClickable="true"
                 android:text="@string/information_legal_subtitle_contact_form_non_en_de"
                 android:textColorLink="@color/colorTextTint"
-                android:visibility="@{FormatterInformationLegalHelper.formatVisibilityLanguageBased(context, false)}"
+                android:visibility="@{FormatterInformationLegalHelper.formatVisibilityLanguageBased(false)}"
                 app:layout_constraintBottom_toBottomOf="parent"
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintTop_toBottomOf="@+id/information_legal_contact_form" />
diff --git a/Corona-Warn-App/src/main/res/layout/trace_location_attendee_checkins_fragment.xml b/Corona-Warn-App/src/main/res/layout/trace_location_attendee_checkins_fragment.xml
index 0d86c8e3555782de8c1716a1d36f5ea1d37e271a..1e665b70bab77733c13522cf12757475f33c3306 100644
--- a/Corona-Warn-App/src/main/res/layout/trace_location_attendee_checkins_fragment.xml
+++ b/Corona-Warn-App/src/main/res/layout/trace_location_attendee_checkins_fragment.xml
@@ -4,7 +4,8 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/content_container"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:background="@color/colorBackground">
 
     <com.google.android.material.appbar.MaterialToolbar
         android:id="@+id/toolbar"
@@ -58,6 +59,7 @@
             android:layout_marginTop="36dp"
             android:text="@string/trace_location_checkins_empty_label"
             android:textStyle="bold" />
+
         <TextView
             style="@style/body2Medium"
             android:layout_width="wrap_content"
diff --git a/Corona-Warn-App/src/main/res/layout/trace_location_attendee_checkins_item_active.xml b/Corona-Warn-App/src/main/res/layout/trace_location_attendee_checkins_item_active.xml
index b7d630bc5d2fbd3dc967a92b8ef92b176fb8220b..af99c65414025eef1cc19e0c7a24f7952a6df4ce 100644
--- a/Corona-Warn-App/src/main/res/layout/trace_location_attendee_checkins_item_active.xml
+++ b/Corona-Warn-App/src/main/res/layout/trace_location_attendee_checkins_item_active.xml
@@ -5,8 +5,8 @@
     style="@style/contactDiaryCardRipple"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:layout_marginVertical="8dp"
     android:layout_marginHorizontal="16dp"
+    android:layout_marginVertical="8dp"
     android:focusable="true">
 
     <de.rki.coronawarnapp.ui.eventregistration.common.TraceLocationCardHighlightView
@@ -17,10 +17,8 @@
         android:layout_marginTop="16dp"
         android:layout_marginBottom="8dp"
         android:orientation="vertical"
-        app:layout_constraintBottom_toTopOf="@+id/checkout_action"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        tools:text="21.01.2021">
+        app:layout_constraintTop_toTopOf="parent">
 
         <TextView
             android:id="@+id/highlight_duration_label"
@@ -38,6 +36,7 @@
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toTopOf="parent"
             app:layout_constraintVertical_chainStyle="packed" />
+
         <TextView
             android:id="@+id/highlight_duration"
             style="@style/headline5Bold"
@@ -91,8 +90,7 @@
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toEndOf="@id/traceLocationCardHighlightView"
         app:layout_constraintTop_toBottomOf="@id/address"
-        app:layout_constraintVertical_bias="0.0"
-        tools:text="18:00 - Automatisch auschecken nach 3 Std." />
+        tools:text="21.01.2021 18:00 - Automatisch auschecken nach 3 Std." />
 
     <ImageButton
         android:id="@+id/menu_action"
diff --git a/Corona-Warn-App/src/main/res/layout/trace_location_attendee_checkins_item_camera.xml b/Corona-Warn-App/src/main/res/layout/trace_location_attendee_checkins_item_camera.xml
index 35b62a8bd4b8fcdc11117edfdb277bb9800574b5..955e46ce2a15b69e5df49207f30728cde5a1e351 100644
--- a/Corona-Warn-App/src/main/res/layout/trace_location_attendee_checkins_item_camera.xml
+++ b/Corona-Warn-App/src/main/res/layout/trace_location_attendee_checkins_item_camera.xml
@@ -8,10 +8,7 @@
     android:layout_marginHorizontal="16dp"
     android:layout_marginVertical="8dp"
     android:focusable="true"
-    android:paddingStart="24dp"
-    android:paddingTop="32dp"
-    android:paddingEnd="24dp"
-    android:paddingBottom="24dp">
+    android:padding="16dp">
 
     <TextView
         android:id="@+id/title"
@@ -33,7 +30,7 @@
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@id/title" />
-    
+
     <Button
         android:id="@+id/open_settings"
         style="@style/buttonPrimary"
diff --git a/Corona-Warn-App/src/main/res/layout/trace_location_organizer_qr_code_detail_fragment.xml b/Corona-Warn-App/src/main/res/layout/trace_location_organizer_qr_code_detail_fragment.xml
index 58782363908fa6bf30e610630d4ad2c63b2b6fcc..9396dc1576dfc32de53f628d19d795c828a87d19 100644
--- a/Corona-Warn-App/src/main/res/layout/trace_location_organizer_qr_code_detail_fragment.xml
+++ b/Corona-Warn-App/src/main/res/layout/trace_location_organizer_qr_code_detail_fragment.xml
@@ -6,8 +6,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@drawable/trace_location_gradient_background"
-    android:contentDescription="@string/trace_location_event_detail_title_accessibility"
-    android:transitionName="trace_location_container_transition">
+    android:contentDescription="@string/trace_location_event_detail_title_accessibility">
 
     <androidx.coordinatorlayout.widget.CoordinatorLayout
         android:id="@+id/coordinator_layout"
@@ -61,9 +60,10 @@
 
                     <TextView
                         android:id="@+id/subtitle"
-                        android:layout_width="wrap_content"
+                        android:layout_width="match_parent"
                         android:layout_height="wrap_content"
                         android:layout_gravity="center"
+                        android:layout_marginHorizontal="24dp"
                         android:layout_marginBottom="8dp"
                         android:gravity="center"
                         android:textColor="@android:color/white"
diff --git a/Corona-Warn-App/src/main/res/layout/trace_location_organizer_qr_code_info_fragment.xml b/Corona-Warn-App/src/main/res/layout/trace_location_organizer_qr_code_info_fragment.xml
index 8cafcb270f82400a7b370d53a0977e87eefefa7c..594d4846fbd20bf048ddf06d8c1f6a14c415bad9 100644
--- a/Corona-Warn-App/src/main/res/layout/trace_location_organizer_qr_code_info_fragment.xml
+++ b/Corona-Warn-App/src/main/res/layout/trace_location_organizer_qr_code_info_fragment.xml
@@ -5,6 +5,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:contentDescription="@string/tracelocation_organizer_category_title"
+    android:background="@color/colorBackground"
     tools:context=".ui.eventregistration.organizer.qrinfo.TraceLocationQRInfoFragment">
 
     <com.google.android.material.appbar.MaterialToolbar
@@ -133,7 +134,7 @@
                 android:text="@string/trace_location_qr_info_time_text"
                 app:layout_constraintTop_toTopOf="@id/trace_location_qr_time_sheet_icon"
                 app:layout_constraintStart_toEndOf="@id/trace_location_qr_time_sheet_icon"
-                app:layout_constraintEnd_toEndOf="parent"/>
+                app:layout_constraintEnd_toEndOf="parent" />
 
             <include
                 android:id="@+id/privacy_card"
@@ -160,7 +161,7 @@
                 app:layout_constraintTop_toBottomOf="@id/privacy_card"
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintBottom_toBottomOf="parent"/>
+                app:layout_constraintBottom_toBottomOf="parent" />
 
         </androidx.constraintlayout.widget.ConstraintLayout>
     </ScrollView>
diff --git a/Corona-Warn-App/src/main/res/layout/trace_location_organizer_trace_locations_item.xml b/Corona-Warn-App/src/main/res/layout/trace_location_organizer_trace_locations_item.xml
index 8434f98f0f523dbcd52056d8547b74c966ebb31b..41503487bbafe2aa59352e6ad1e2056e3615f754 100644
--- a/Corona-Warn-App/src/main/res/layout/trace_location_organizer_trace_locations_item.xml
+++ b/Corona-Warn-App/src/main/res/layout/trace_location_organizer_trace_locations_item.xml
@@ -17,8 +17,7 @@
         android:layout_marginTop="16dp"
         android:layout_marginBottom="8dp"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        tools:text="21.01.2021">
+        app:layout_constraintTop_toTopOf="parent">
 
         <ImageView
             android:layout_width="42dp"
@@ -85,6 +84,11 @@
         app:barrierDirection="bottom"
         app:constraint_referenced_ids="address,duration,icon" />
 
+    <Space
+        android:layout_width="match_parent"
+        android:layout_height="16dp"
+        app:layout_constraintTop_toBottomOf="@id/button_barrier" />
+
     <com.google.android.material.button.MaterialButton
         android:id="@+id/checkin_action"
         style="@style/Widget.MaterialComponents.Button.OutlinedButton"
diff --git a/Corona-Warn-App/src/main/res/layout/trace_location_organizer_trace_locations_list_fragment.xml b/Corona-Warn-App/src/main/res/layout/trace_location_organizer_trace_locations_list_fragment.xml
index 2c3516cab07bf0aa2e3e00d29b07c8fdc6ab8556..7cc778f51698899505c2beef24786640fd99ec0a 100644
--- a/Corona-Warn-App/src/main/res/layout/trace_location_organizer_trace_locations_list_fragment.xml
+++ b/Corona-Warn-App/src/main/res/layout/trace_location_organizer_trace_locations_list_fragment.xml
@@ -5,6 +5,7 @@
     android:id="@+id/content_container"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:background="@color/colorBackground"
     android:focusable="true">
 
     <com.google.android.material.appbar.MaterialToolbar
diff --git a/Corona-Warn-App/src/main/res/layout/tracing_details_item_riskdetails_low_view.xml b/Corona-Warn-App/src/main/res/layout/tracing_details_item_riskdetails_low_view.xml
index c18fabd786e88c731fbc6114c590a0884e54e11a..47d969b248ad4f16080a27e47cba8e25ecc04fb5 100644
--- a/Corona-Warn-App/src/main/res/layout/tracing_details_item_riskdetails_low_view.xml
+++ b/Corona-Warn-App/src/main/res/layout/tracing_details_item_riskdetails_low_view.xml
@@ -60,6 +60,7 @@
             android:clickable="true"
             android:focusable="true"
             android:linksClickable="true"
+            tools:visibility="visible"
             android:visibility="gone"
             android:text="@string/risk_details_explanation_dialog_faq_body"
             app:layout_constraintEnd_toEndOf="parent"
diff --git a/Corona-Warn-App/src/main/res/navigation/trace_location_attendee_nav_graph.xml b/Corona-Warn-App/src/main/res/navigation/trace_location_attendee_nav_graph.xml
index cb34d67595e1f9efb9d3d33b0cce121e8e26c77b..bbf7abe775c1afe85f8994a4eba64e519d054a59 100644
--- a/Corona-Warn-App/src/main/res/navigation/trace_location_attendee_nav_graph.xml
+++ b/Corona-Warn-App/src/main/res/navigation/trace_location_attendee_nav_graph.xml
@@ -9,6 +9,7 @@
         android:name="de.rki.coronawarnapp.ui.eventregistration.attendee.onboarding.CheckInOnboardingFragment"
         android:label="CheckInOnboardingFragment"
         tools:layout="@layout/fragment_trace_location_onboarding">
+        <deepLink app:uri="coronawarnapp://check-ins/{uri}" />
         <action
             android:id="@+id/action_checkInOnboardingFragment_to_checkInsFragment"
             app:destination="@id/checkInsFragment"
@@ -21,6 +22,11 @@
             android:name="showBottomNav"
             android:defaultValue="true"
             app:argType="boolean" />
+        <argument
+            android:name="uri"
+            android:defaultValue="@null"
+            app:argType="string"
+            app:nullable="true" />
     </fragment>
     <fragment
         android:id="@+id/checkInPrivacyFragment"
@@ -56,7 +62,6 @@
         android:name="de.rki.coronawarnapp.ui.eventregistration.attendee.checkins.CheckInsFragment"
         android:label="CheckInsFragment"
         tools:layout="@layout/trace_location_attendee_checkins_fragment">
-        <deepLink app:uri="coronawarnapp://check-ins/{uri}" />
         <action
             android:id="@+id/action_checkInsFragment_to_scanCheckInQrCodeFragment"
             app:destination="@id/scanCheckInQrCodeFragment" />
diff --git a/Corona-Warn-App/src/main/res/navigation/trace_location_organizer_nav_graph.xml b/Corona-Warn-App/src/main/res/navigation/trace_location_organizer_nav_graph.xml
index aa52e6cb304971cded06b59023927f8fe76811eb..ae96af2c68e982128fd1f41093a65f7e5f34bbfa 100644
--- a/Corona-Warn-App/src/main/res/navigation/trace_location_organizer_nav_graph.xml
+++ b/Corona-Warn-App/src/main/res/navigation/trace_location_organizer_nav_graph.xml
@@ -82,6 +82,9 @@
         <action
             android:id="@+id/action_qrCodeDetailFragment_to_qrCodePosterFragment"
             app:destination="@id/qrCodePosterFragment" />
+        <action
+            android:id="@+id/action_qrCodeDetailFragment_to_traceLocationCreateFragment"
+            app:destination="@id/traceLocationCreateFragment" />
     </fragment>
 
     <fragment
diff --git a/Corona-Warn-App/src/main/res/values-bg/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values-bg/contact_diary_strings.xml
index 24439e7a46fc462d778b60cb7ade0e48eb4cda1b..b3079ef9d7a5dff1c548e034dc68d049a34d8522 100644
--- a/Corona-Warn-App/src/main/res/values-bg/contact_diary_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-bg/contact_diary_strings.xml
@@ -76,6 +76,13 @@
     <string name="contact_diary_risk_body_high_risk_due_to_low_risk_encounters">"въз основа на повече от едно излагане на нисък риск."</string>
     <!-- XTXT: Extended Body for contact diary overview screen risk information -->
     <string name="contact_diary_risk_body_extended">"Не е задължително те да са свързани с отбелязаните от Вас хора и места."</string>
+    <!-- XTXT: Body for contact diary overview screen trace location risk information prelude -->
+    <string name="contact_diary_trace_location_risk_body">"въз основа на присъствието им в:"</string>
+    <!-- XTXT: Indicates this trace location caused a high risk  -->
+    <string name="contact_diary_trace_location_risk_high">"повишен риск"</string>
+    <!-- XTXT: Indicates this trace location caused a lows risk -->
+    <string name="contact_diary_trace_location_risk_low">"нисък риск"</string>
+
 
 
     <!-- XTXT: content description of contact journal image on home screen -->
diff --git a/Corona-Warn-App/src/main/res/values-bg/event_registration_strings.xml b/Corona-Warn-App/src/main/res/values-bg/event_registration_strings.xml
index 1193e91a4727e0d30c9a030d836b20eb6a029097..8ca317a1a4d95c44a95798c7a7ebb8572d2cb6aa 100644
--- a/Corona-Warn-App/src/main/res/values-bg/event_registration_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-bg/event_registration_strings.xml
@@ -135,6 +135,33 @@
     <string name="create_trace_location_card_subtitle">"Планирате събитие или ръководите бизнес? Създайте QR код, за да могат посетителите да се регистрират, когато пристигнат."</string>
     <!-- XTXT: Text for trace location creation card -->
     <string name="create_trace_location_card_button">"Създаване на QR код"</string>
+    <!-- XTXT: Text for content description of tile image -->
+    <string name="create_trace_location_card_content_description">"Eдин човек сочи към флипчарт."</string>
+
+    <!--    Trace Location QR Code Info Screen-->
+    <!-- XTXT: Text for content description of info screen image -->
+    <string name="trace_location_qr_info_content_description">"Eдин човек посочва флипчарт, а други двама седят в близост един до друг и гледат към него."</string>
+    <!-- XHED: Headline for trace location creation card -->
+    <string name="trace_location_qr_info_headline_text">"Повече безопасност за Вас и Вашите посетители"</string>
+    <!-- XTXT: Text for subtitle of qr info screen -->
+    <string name="trace_location_qr_info_subtitle_text">"Създайте QR код, който посетителите Ви могат да сканират при пристигането си. Това ще им позволи при необходимост.да предупредят останалите посетители или да бъдат предупредени от тях."</string>
+    <!-- XTXT: Text for tracing icon of qr info screen -->
+    <string name="trace_location_qr_info_tracing_text">"Всяка регистрация се взема предвид също и при изчисляване на нивото на риска. При поставяне на диагноза коронавирус на лице, което се е регистрирало от дадено място или събитие, ще бъдат уведомени всички останали посетители, които по същото време или в рамките на 30 минути след това са се намирали в едно и също помещение с него."</string>
+    <!-- XTXT: Text for qr icon of qr info screen -->
+    <string name="trace_location_qr_info_qr_code_text">"Можете да предоставите QR кода на посетителите си от смартфон или отпечатан на хартия."</string>
+    <!-- XTXT: Text for time sheet icon of qr info screen -->
+    <string name="trace_location_qr_info_time_text">"Ако желаете да използвате QR код дългосрочно, трябва да генерирате такъв ежедневно извън работно време."</string>
+    <!-- XTXT: Text for I understand button -->
+    <string name="acknowledge_button">"Напред"</string>
+
+    <!-- XHED: Title of the notification channel for event registration related notifications. -->
+    <string name="tracelocation_notification_channel_title">"Регистрации"</string>
+    <!-- XTXT: Description of the notification channel for event registration related notifications. -->
+    <string name="tracelocation_notification_channel_description">"Известия за регистрациите Ви, като автоматично прекратяване на регистрацията."</string>
+    <!-- XHED: Title of the automatic check-out notification. -->
+    <string name="tracelocation_notification_autocheckout_title">"Регистрацията Ви беше прекратена автоматично."</string>
+    <!-- XTXT: Description of the automatic check-out notification. -->
+    <string name="tracelocation_notification_autocheckout_description">"Моля, коригирайте продължителността на престоя си, ако е необходимо."</string>
 
     <!-- ####################################
        Event Organiser Trace Locations List
@@ -173,6 +200,11 @@
     <!-- XBUT: Event organiser list item: checkin button -->
     <string name="trace_location_organizer_list_item_action_checkin">"Регистрация"</string>
 
+    <!-- XTXT: Event organizer detail qr-code: duration with date -->
+    <string name="trace_location_organizer_detail_item_duration">"%1$s, %2$s - %3$s"</string>
+    <!-- XTXT: Event organizer detail qr-code: duration with multiple date -->
+    <string name="trace_location_organizer_detail_item_duration_multiple_days">"%1$s, %2$s - %3$s, %4$s"</string>
+
     <!-- XBUT: Event organiser list item: menu: information button  -->
     <string name="trace_location_organizer_list_item_menu_duplicate_btn">"Дублиране"</string>
     <!-- XBUT: Event organiser list item: menu: show print button  -->
@@ -180,12 +212,42 @@
     <!-- XBUT: Event organiser list item: menu: clear button  -->
     <string name="trace_location_organizer_list_item_menu_clear_btn">"Изтриване"</string>
 
+    <!-- Trace Location Checkin Confirmation -->
+    <!-- XHED: Checkin Confirm: title for screen -->
+    <string name="confirm_checkin_title_text">"Регистрация за:"</string>
+    <!-- XTXT: Checkin Confirm: text for event is in future info card -->
+    <string name="confirm_checkin_event_in_future_card_text">"Това събитие започва в %2$s на %1$s. Желаете ли да се регистрирате още сега?"</string>
+    <!-- XTXT: Checkin Confirm: text for event is in past info card -->
+    <string name="confirm_checkin_event_in_past_card_text">"Това събитие вече е отминало. Желаете ли да се регистрирате със задна дата?"</string>
+    <!-- XTXT: Checkin Confirm: label for save to contact diary toggle -->
+    <string name="confirm_checkin_settings_card_checkout_toggle_label">"Да се създаде ли запис в дневника на контактите след прекратяване на регистрацията?"</string>
+    <!-- XTXT: Checkin Confirm: label for checkout delay selection -->
+    <string name="confirm_checkin_settings_card_checkout_time_label">"Автоматично прекратяване на регистрацията след"</string>
+    <!-- XTXT: Checkin Confirm: time length label for checkout delay selection -->
+    <string name="confirm_checkin_settings_card_checkout_time_tag">"ч"</string>
+    <!-- XBUT: Checkin Confirm: Checkin Button -->
+    <string name="confirm_checkin_confirm_button_text">"Регистрация"</string>
+
+    <!-- Trace Location Checkin Editing -->
+    <!-- XHED: Checkin Edit: title for screen -->
+    <string name="edit_checkin_title_text">"Промяна на продължителността на престой за:"</string>
+    <!-- XTXT: Checkin Edit: label for checkout time -->
+    <string name="edit_checkin_edit_card_checkout_time_label">"Регистрирано напускане"</string>
+    <!-- XTXT: Checkin Edit: label for checkin time -->
+    <string name="edit_checkin_edit_card_checkin_time_label">"Регистрирано пристигане"</string>
+    <!-- XTXT: Checkin Edit: hint for unchanged contact diary checkin duration -->
+    <string name="edit_checkin_duration_edit_hint_card_text">"Продължителността на престоя няма да бъде коригирана автоматично във вашия дневник на контактите."</string>
+    <!-- XTXT: Checkin Edit: warning if user input is incorrect -->
+    <string name="edit_checkin_wrong_input_warning_text">"Може да останете регистрирани в рамките на 24 часа. Часът на прекратяване на регистрирането трябва да е по-късен от този на регистрирането."</string>
+    <!-- XBUT: Checkin Edit: Save Button -->
+    <string name="edit_checkin_confirm_button_text">"Запазване"</string>
+
     <!--  Organizer Flow: Event Detail Screen-->
     <!-- XTXT: Organizer Flow : Accessibility description for qr-code illustration -->
     <string name="trace_location_event_detail_qr_code_accessibility">"QR код"</string>
     <!-- XHED: Organizer Flow : Accessibility title for event-overview -->
     <string name="trace_location_event_detail_title_accessibility">"Преглед на събитие"</string>
-    !-- XBUT: Organizer Flow : Title for show print version button --&gt;
+    <!-- XBUT: Organizer Flow : Title for show print version button -->
     <string name="trace_location_event_detail_show_print_qr_code_button">"Показване на версия за печат"</string>
     <!-- XBUT: Organizer Flow : Title for save as template button -->
     <string name="trace_location_event_detail_save_as_template_button">"Използване като шаблон"</string>
diff --git a/Corona-Warn-App/src/main/res/values-bg/release_info_strings.xml b/Corona-Warn-App/src/main/res/values-bg/release_info_strings.xml
index 8d48b68c7db7a875f359bf2c7fcba5f59c9bccbd..a1cbf8e4d5a5715198514f33ef5bb6d4876aecbf 100644
--- a/Corona-Warn-App/src/main/res/values-bg/release_info_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-bg/release_info_strings.xml
@@ -21,7 +21,7 @@
 
     <!-- XTXT: Text bodies for the release info screen bullet points -->
     <string-array name="new_release_body">
-        <item>"CWA Ви позволява да се регистрирате, когато пристигате на определени места и събития. Организаторите на събития и собствениците на магазини могат да използват приложението за създаване на QR код, който посетителите да сканират, когато пристигат, за да регистрират присъствието си. При поискване приложението може също да създава запис в дневника. Ако на някой от посетителите на съответното място или събитие бъде поставена диагноза коронавирус, всички лица, които са се регистрирали на същото място по същото време, ще бъдат уведомени."</item>
+        <item>"CWA Ви позволява да се регистрирате, когато пристигате на определени места и събития. Организаторите на събития и собствениците на магазини могат да използват приложението за създаване на QR код, който посетителите да сканират, когато пристигат, за да регистрират присъствието си. При поискване приложението може също да създава запис в дневника. Ако на някой от посетителите на съответното място или събитие бъде поставена диагноза коронавирус, други лица, които са се регистрирали на същото място по същото време, може да бъдат предупредени автоматично."</item>
     </string-array>
 
     <!-- XTXT: Text labels that will be converted to Links -->
diff --git a/Corona-Warn-App/src/main/res/values-bg/strings.xml b/Corona-Warn-App/src/main/res/values-bg/strings.xml
index 59084387a6fcf9573020c7feca7c97253c26b34d..646797d6076689e0bb7ec0078da5c49ab7d18f6e 100644
--- a/Corona-Warn-App/src/main/res/values-bg/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-bg/strings.xml
@@ -30,6 +30,10 @@
     <!-- ####################################
                Notification
     ###################################### -->
+    <!-- XHED: Title of the notification channel for general CWA notifications (e.g. risk change) -->
+    <string name="general_notification_channel_title">"Общи"</string>
+    <!-- XTXT: Description of the notification channel for general CWA notifications (e.g. risk change) -->
+    <string name="general_notification_channel_description">"Напомняния, бележки и общи известия - относно статуса Ви на риск, например."</string>
     <!-- XHED: Notification title -->
     <string name="notification_headline">"Corona-Warn-App"</string>
     <!-- XTXT: Notification body -->
@@ -1793,13 +1797,13 @@
     <string name="statistics_reproduction_title">"В момента"</string>
     <!-- XTXT: Caption for statistics reproduction card -->
     <string name="statistics_reproduction_average">"среден брой заразени от всяко заразено лице"</string>
-
     <!-- XTXT: Statistics trend increasing (Accessibilty) -->
     <string name="statistics_trend_increasing">"Тенденция: Нагоре"</string>
     <!-- XTXT: Statistics trend decreasing (Accessibilty) -->
     <string name="statistics_trend_decreasing">"Тенденция: Надолу"</string>
     <!-- XTXT: Statistics trend stable (Accessibilty) -->
     <string name="statistics_trend_stable">"Тенденция: Стабилизиране"</string>
+
     <!-- XHED: Title for BottomNav main screen title -->
     <string name="bottom_nav_home_title">"Начален екран"</string>
     <!-- XHED: Title for BottomNav diary screen title -->
@@ -1955,4 +1959,18 @@
     <string name="trace_location_onboarding_body_stay">"Моля, отбележете продължителността на престоя си възможно най-точно, за да може да получите адекватни предупреждения."</string>
     <!-- XACT: Button/Dialog label to consent-->
     <string name="trace_location_onboarding_body_confirm">"Приемам"</string>
+    <!--  XHED: Trace location check-ins camera permission card title-->
+    <string name="trace_location_attendee_camera_card_title">"Разрешаване на достъп до камерата"</string>
+    <!--  XTXT: Trace location check-ins camera permission card susbtitle-->
+    <string name="trace_location_attendee_camera_card_subtitle">"За да използвате камерата на телефона си за сканиране на QR кодове, трябва да разрешите на приложението да получи достъп до нея от настройките на устройството си."</string>
+    <!--  XBUT: Trace location check-ins camera permission card button-->
+    <string name="trace_location_attendee_camera_card_button">"Отворете менюто за настройки"</string>
+    <!--  YMSG: Trace location onboarding image description-->
+    <string name="trace_location_onboarding_content_description">"Трима души стоят до висока маса и двама от тях гледат телефоните си."</string>
+    <!-- XMIT: Trace location poster print -->
+    <string name="trace_location_organiser_poster_print">"Печат"</string>
+    <!-- XMIT: Trace location poster share -->
+    <string name="trace_location_organiser_poster_share">"Споделяне"</string>
+    <!-- XHED: Trace location poster title -->
+    <string name="trace_location_organiser_poster_title">"Версия за печат"</string>
 </resources>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/values-de/event_registration_strings.xml b/Corona-Warn-App/src/main/res/values-de/event_registration_strings.xml
index 2c21432140c2dd68198ee608f07da3079797bd9e..732c3f2c57841116a81ebae569f4bdc3f7defcef 100644
--- a/Corona-Warn-App/src/main/res/values-de/event_registration_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-de/event_registration_strings.xml
@@ -43,6 +43,8 @@
     <string name="trace_location_checkins_card_highlight_duration_label">Dauer</string>
     <!-- XTXT: My check-ins card: Active event, checkin information, automatic checkout info -->
     <string name="trace_location_checkins_card_automatic_checkout_info">"%1$s - Automatisch auschecken nach %2$s."</string>
+    <!-- XTXT: My check-ins card: Active event, checkin information, automatic checkout info -->
+    <string name="trace_location_checkins_card_automatic_checkout_info_format">"%1$s %2$s - Automatisch auschecken nach %3$s."</string>
 
     <!-- XHED: Title of the category list screen of the event creation  -->
     <string name="tracelocation_organizer_category_title">QR-Code erstellen</string>
@@ -185,7 +187,7 @@
     <!-- XHED:  Event organiser qr codes list: delete single popup title -->
     <string name="trace_location_organiser_list_delete_single_popup_title">"Wollen Sie den QR-Code wirklich entfernen?"</string>
     <!-- XTXT:  Event organiser qr codes list: delete single popup message -->
-    <string name="trace_location_organiser_list_delete_single_popup_message">"Bitte denken Sie daran, dass der QR-Code “Jahrestreffen der deutschen SAP Anwendergruppe” danach nicht mehr zum Einchecken verwendet werden kann."</string>
+    <string name="trace_location_organiser_list_delete_single_popup_message">"Bitte denken Sie daran, dass der QR-Code danach nicht mehr zum Einchecken verwendet werden kann."</string>
 
     <!-- XHED:  Event organiser qr codes list: delete all popup title -->
     <string name="trace_location_organiser_list_delete_all_popup_title">"Wollen Sie wirklich alle QR-Codes entfernen?"</string>
@@ -198,6 +200,10 @@
 
     <!-- XTXT: Event organiser list item: duration-->
     <string name="trace_location_organizer_list_item_duration">"%1$s - %2$s Uhr"</string>
+
+    <!-- XTXT: Event organiser list item: duration same day-->
+    <string name="trace_location_organizer_list_item_duration_same_day">"%1$s %2$s - %3$s Uhr"</string>
+
     <!-- XBUT: Event organiser list item: checkin button -->
     <string name="trace_location_organizer_list_item_action_checkin">Selbst einchecken</string>
 
@@ -238,6 +244,8 @@
     <string name="edit_checkin_edit_card_checkin_time_label">"Eingecheckt"</string>
     <!-- XTXT: Checkin Edit: hint for unchanged contact diary checkin duration -->
     <string name="edit_checkin_duration_edit_hint_card_text">"Die Aufenthaltsdauer wird nicht automatisch in Ihrem Kontakt-Tagebuch angepasst."</string>
+    <!-- XTXT: Checkin Edit: warning if user input is incorrect -->
+    <string name="edit_checkin_wrong_input_warning_text">"Sie können für maximal 24 Stunden eingecheckt sein und die Auscheck-Zeit muss nach der Eincheck-Zeit liegen."</string>
     <!-- XBUT: Checkin Edit: Save Button -->
     <string name="edit_checkin_confirm_button_text">"Speichern"</string>
 
diff --git a/Corona-Warn-App/src/main/res/values-de/strings.xml b/Corona-Warn-App/src/main/res/values-de/strings.xml
index 1c44b7cb590f80e1f6ec25b83366bbf828c6e603..74344fff12023323d98b03dfa9982c49bac570a5 100644
--- a/Corona-Warn-App/src/main/res/values-de/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-de/strings.xml
@@ -1974,7 +1974,7 @@
     <!-- YMSG: Onboarding trace location warning -->
     <string name="trace_location_onboarding_body_warning">Jeder Check-in wird bei der Ermittlung des Risikostatus zusätzlich berücksichtigt. Wird eine eingecheckte Person später positiv getestet, können Sie gewarnt werden, wenn Sie sich zur gleichen Zeit oder bis zu 30 Minuten nach der positiv getesteten Person im gleichen Raum aufgehalten haben.</string>
     <!-- YMSG: Onboarding trace location warning -->
-    <string name="trace_location_onboarding_body_stay">Bitte geben Sie Ihre Check-in- und Check-out-Zeit so genau wie möglich an, damit gezielt gewarnt werden kann.</string>
+    <string name="trace_location_onboarding_body_stay">Bitte geben Sie Ihre Aufenthaltszeit so genau wie möglich an, damit gezielt gewarnt werden kann.</string>
     <!-- XACT: Button/Dialog label to consent-->
     <string name="trace_location_onboarding_body_confirm">Einverstanden</string>
     <!--  XHED: Trace location check-ins camera permission card title-->
diff --git a/Corona-Warn-App/src/main/res/values-en/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values-en/contact_diary_strings.xml
index 44bcb0bcc8a0945703e533219caa962beefce532..97bab3bbeda1f7ab22d67db2b520de5abd020266 100644
--- a/Corona-Warn-App/src/main/res/values-en/contact_diary_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-en/contact_diary_strings.xml
@@ -76,6 +76,13 @@
     <string name="contact_diary_risk_body_high_risk_due_to_low_risk_encounters">"based on multiple exposures with low risk."</string>
     <!-- XTXT: Extended Body for contact diary overview screen risk information -->
     <string name="contact_diary_risk_body_extended">"They are not necessarily related to the people and places you have recorded."</string>
+    <!-- XTXT: Body for contact diary overview screen trace location risk information prelude -->
+    <string name="contact_diary_trace_location_risk_body">"based on their presence at:"</string>
+    <!-- XTXT: Indicates this trace location caused a high risk  -->
+    <string name="contact_diary_trace_location_risk_high">"increased risk"</string>
+    <!-- XTXT: Indicates this trace location caused a lows risk -->
+    <string name="contact_diary_trace_location_risk_low">"low risk"</string>
+
 
 
     <!-- XTXT: content description of contact journal image on home screen -->
diff --git a/Corona-Warn-App/src/main/res/values-en/event_registration_strings.xml b/Corona-Warn-App/src/main/res/values-en/event_registration_strings.xml
index ecc733f2aed79d13c087be1f0096e7c8a8ca1753..56f2df42950a06ceec76d37f81b3c7309d73c445 100644
--- a/Corona-Warn-App/src/main/res/values-en/event_registration_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-en/event_registration_strings.xml
@@ -135,6 +135,33 @@
     <string name="create_trace_location_card_subtitle">"Are you planning an event or do you run a business? Create a QR code so your guests can check in when they arrive."</string>
     <!-- XTXT: Text for trace location creation card -->
     <string name="create_trace_location_card_button">"Create QR Code"</string>
+    <!-- XTXT: Text for content description of tile image -->
+    <string name="create_trace_location_card_content_description">"A person points to a flip chart."</string>
+
+    <!--    Trace Location QR Code Info Screen-->
+    <!-- XTXT: Text for content description of info screen image -->
+    <string name="trace_location_qr_info_content_description">"One person points to a flip chart, while two people are sitting adjacent and looking at the flip chart."</string>
+    <!-- XHED: Headline for trace location creation card -->
+    <string name="trace_location_qr_info_headline_text">"Increased Safety for You and Your Guests"</string>
+    <!-- XTXT: Text for subtitle of qr info screen -->
+    <string name="trace_location_qr_info_subtitle_text">"Create a QR code that your guests can scan when they arrive. This will enable them to warn other guests or be warned by them if necessary."</string>
+    <!-- XTXT: Text for tracing icon of qr info screen -->
+    <string name="trace_location_qr_info_tracing_text">"Every check-in is also taken into account when calculating the risk status. If someone who checked in to this event or place is diagnosed with coronavirus later, the guests can be notified if they were in the same room at the same time or up to 30 minutes after the diagnosed person."</string>
+    <!-- XTXT: Text for qr icon of qr info screen -->
+    <string name="trace_location_qr_info_qr_code_text">"You can provide the QR code to your guests on your smartphone or as a printed form."</string>
+    <!-- XTXT: Text for time sheet icon of qr info screen -->
+    <string name="trace_location_qr_info_time_text">"If you want to use a QR code for the long term, you should generate it again each day, outside of your operating hours."</string>
+    <!-- XTXT: Text for I understand button -->
+    <string name="acknowledge_button">"Next"</string>
+
+    <!-- XHED: Title of the notification channel for event registration related notifications. -->
+    <string name="tracelocation_notification_channel_title">"Check-Ins"</string>
+    <!-- XTXT: Description of the notification channel for event registration related notifications. -->
+    <string name="tracelocation_notification_channel_description">"Notifications about your check-ins, such as automatic check-out."</string>
+    <!-- XHED: Title of the automatic check-out notification. -->
+    <string name="tracelocation_notification_autocheckout_title">"You were checked out automatically."</string>
+    <!-- XTXT: Description of the automatic check-out notification. -->
+    <string name="tracelocation_notification_autocheckout_description">"Please adjust the length of your stay if needed."</string>
 
     <!-- ####################################
        Event Organiser Trace Locations List
@@ -173,6 +200,11 @@
     <!-- XBUT: Event organiser list item: checkin button -->
     <string name="trace_location_organizer_list_item_action_checkin">"Check In"</string>
 
+    <!-- XTXT: Event organizer detail qr-code: duration with date -->
+    <string name="trace_location_organizer_detail_item_duration">"%1$s, %2$s - %3$s"</string>
+    <!-- XTXT: Event organizer detail qr-code: duration with multiple date -->
+    <string name="trace_location_organizer_detail_item_duration_multiple_days">"%1$s, %2$s - %3$s, %4$s"</string>
+
     <!-- XBUT: Event organiser list item: menu: information button  -->
     <string name="trace_location_organizer_list_item_menu_duplicate_btn">"Duplicate"</string>
     <!-- XBUT: Event organiser list item: menu: show print button  -->
@@ -180,6 +212,36 @@
     <!-- XBUT: Event organiser list item: menu: clear button  -->
     <string name="trace_location_organizer_list_item_menu_clear_btn">"Delete"</string>
 
+    <!-- Trace Location Checkin Confirmation -->
+    <!-- XHED: Checkin Confirm: title for screen -->
+    <string name="confirm_checkin_title_text">"Check in for:"</string>
+    <!-- XTXT: Checkin Confirm: text for event is in future info card -->
+    <string name="confirm_checkin_event_in_future_card_text">"This event doesn’t start until %2$s on %1$s. Do you want to check in already?"</string>
+    <!-- XTXT: Checkin Confirm: text for event is in past info card -->
+    <string name="confirm_checkin_event_in_past_card_text">"This event is already over. Do you want to check in retroactively?"</string>
+    <!-- XTXT: Checkin Confirm: label for save to contact diary toggle -->
+    <string name="confirm_checkin_settings_card_checkout_toggle_label">"Record in my contact journal after check-out?"</string>
+    <!-- XTXT: Checkin Confirm: label for checkout delay selection -->
+    <string name="confirm_checkin_settings_card_checkout_time_label">"Check out automatically after"</string>
+    <!-- XTXT: Checkin Confirm: time length label for checkout delay selection -->
+    <string name="confirm_checkin_settings_card_checkout_time_tag">"hrs"</string>
+    <!-- XBUT: Checkin Confirm: Checkin Button -->
+    <string name="confirm_checkin_confirm_button_text">"Check In"</string>
+
+    <!-- Trace Location Checkin Editing -->
+    <!-- XHED: Checkin Edit: title for screen -->
+    <string name="edit_checkin_title_text">"Change length of stay for:"</string>
+    <!-- XTXT: Checkin Edit: label for checkout time -->
+    <string name="edit_checkin_edit_card_checkout_time_label">"Checked Out"</string>
+    <!-- XTXT: Checkin Edit: label for checkin time -->
+    <string name="edit_checkin_edit_card_checkin_time_label">"Checked In"</string>
+    <!-- XTXT: Checkin Edit: hint for unchanged contact diary checkin duration -->
+    <string name="edit_checkin_duration_edit_hint_card_text">"The length of stay will not be adjusted automatically in your contact journal."</string>
+    <!-- XTXT: Checkin Edit: warning if user input is incorrect -->
+    <string name="edit_checkin_wrong_input_warning_text">"You can remain checked in for up to 24 hours. The check-out time must be later than the check-in time."</string>
+    <!-- XBUT: Checkin Edit: Save Button -->
+    <string name="edit_checkin_confirm_button_text">"Save"</string>
+
     <!--  Organizer Flow: Event Detail Screen-->
     <!-- XTXT: Organizer Flow : Accessibility description for qr-code illustration -->
     <string name="trace_location_event_detail_qr_code_accessibility">"QR Code"</string>
diff --git a/Corona-Warn-App/src/main/res/values-en/release_info_strings.xml b/Corona-Warn-App/src/main/res/values-en/release_info_strings.xml
index 6ad6582b2b85950b84f3b80eeee64dbcafcb1c1e..1fccdbaa35212bf36afc13952d4bb11e59e7dc6f 100644
--- a/Corona-Warn-App/src/main/res/values-en/release_info_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-en/release_info_strings.xml
@@ -21,7 +21,7 @@
 
     <!-- XTXT: Text bodies for the release info screen bullet points -->
     <string-array name="new_release_body">
-        <item>"The CWA now enables you to check in to events and places. Event organizers and store owners can use the app to create a QR code. Guests can then scan this QR code when they arrive to register their presence. The app can also create a journal entry upon request. If someone who checked in to this event or place is diagnosed with coronavirus later, everyone who was checked in at the same time is notified automatically."</item>
+        <item>"The CWA now enables you to check in to events and places. Event organizers and store owners can use the app to create a QR code. Guests can then scan this QR code when they arrive to register their presence. The app can also create a journal entry upon request. If someone who checked in to this event or place is diagnosed with coronavirus later, other people who were checked in at the same time can be warned automatically."</item>
     </string-array>
 
     <!-- XTXT: Text labels that will be converted to Links -->
diff --git a/Corona-Warn-App/src/main/res/values-en/strings.xml b/Corona-Warn-App/src/main/res/values-en/strings.xml
index db8c8318742a4bde8a5bfaf3249e296224e83bd0..15aa30d87239bd87eb73419ef462a17123181184 100644
--- a/Corona-Warn-App/src/main/res/values-en/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-en/strings.xml
@@ -30,6 +30,10 @@
     <!-- ####################################
                Notification
     ###################################### -->
+    <!-- XHED: Title of the notification channel for general CWA notifications (e.g. risk change) -->
+    <string name="general_notification_channel_title">"General"</string>
+    <!-- XTXT: Description of the notification channel for general CWA notifications (e.g. risk change) -->
+    <string name="general_notification_channel_description">"Reminders, notes, and general notifications – about your risk status, for example."</string>
     <!-- XHED: Notification title -->
     <string name="notification_headline">"Corona-Warn-App"</string>
     <!-- XTXT: Notification body -->
@@ -301,9 +305,9 @@
 <!--    Dialog part 1-->
     <string name="risk_details_information_body_period_logged">"Your risk of infection can be calculated only for periods during which exposure logging was active. The logging feature should therefore remain active permanently. Exposure logging covers the last 14 days."</string>
     <!-- XTXT: risk details - infection period logged information body, under 14 days -->
-    <string name="risk_details_information_body_period_logged_assessment_under_14_days">"The Corona-Warn-App was installed %s ago. Your risk of infection is calculated for the periods during which exposure logging was active. If you have encountered other people and exposure logging was active, your risk of infection is calculated."</string>
+    <string name="risk_details_information_body_period_logged_assessment_under_14_days">"The Corona-Warn-App was installed %s days ago. Your risk of infection is calculated for the periods during which exposure logging was active. If you have encountered other people and exposure logging was active, your risk of infection is calculated."</string>
     <!-- XTXT: risk details - infection period logged information body, over 14 days -->
-    <string name="risk_details_information_body_period_logged_assessment_over_14_days">"If exposure logging was active in times during which you encountered other people, your risk of infection can be calculated for this period."</string>
+    <string name="risk_details_information_body_period_logged_assessment_over_14_days">"If exposure logging was active at times during which you encountered other people, your risk of infection can be calculated for this period."</string>
     <!-- XHED: risk details - infection period logged information body, below behaviors -->	    <!-- XTXT: risk details - infection period logged information body, under 14 days -->
     <string name="risk_details_information_body_period_logged_assessment">"The app automatically deletes older logs, as these are no longer relevant for infection prevention."</string>
     <!-- XTXT: risk details - infection period days logged/14 -->
@@ -1793,13 +1797,13 @@
     <string name="statistics_reproduction_title">"Currently"</string>
     <!-- XTXT: Caption for statistics reproduction card -->
     <string name="statistics_reproduction_average">"average infections by each infected person"</string>
-
     <!-- XTXT: Statistics trend increasing (Accessibilty) -->
     <string name="statistics_trend_increasing">"Trend: Upwards"</string>
     <!-- XTXT: Statistics trend decreasing (Accessibilty) -->
     <string name="statistics_trend_decreasing">"Trend: Downwards"</string>
     <!-- XTXT: Statistics trend stable (Accessibilty) -->
     <string name="statistics_trend_stable">"Trend: Steady"</string>
+
     <!-- XHED: Title for BottomNav main screen title -->
     <string name="bottom_nav_home_title">"Start Screen"</string>
     <!-- XHED: Title for BottomNav diary screen title -->
@@ -1955,4 +1959,18 @@
     <string name="trace_location_onboarding_body_stay">"Please specify your length of stay as precisely as possible to enable targeted warnings."</string>
     <!-- XACT: Button/Dialog label to consent-->
     <string name="trace_location_onboarding_body_confirm">"Accept"</string>
+    <!--  XHED: Trace location check-ins camera permission card title-->
+    <string name="trace_location_attendee_camera_card_title">"Allow Access to Camera"</string>
+    <!--  XTXT: Trace location check-ins camera permission card susbtitle-->
+    <string name="trace_location_attendee_camera_card_subtitle">"To use your smartphone camera to scan QR codes, you have to allow access to the camera in the device settings for the app."</string>
+    <!--  XBUT: Trace location check-ins camera permission card button-->
+    <string name="trace_location_attendee_camera_card_button">"Open Settings"</string>
+    <!--  YMSG: Trace location onboarding image description-->
+    <string name="trace_location_onboarding_content_description">"Three persons are standing at a high table, two of them are looking at their smartphones."</string>
+    <!-- XMIT: Trace location poster print -->
+    <string name="trace_location_organiser_poster_print">"Print"</string>
+    <!-- XMIT: Trace location poster share -->
+    <string name="trace_location_organiser_poster_share">"Share"</string>
+    <!-- XHED: Trace location poster title -->
+    <string name="trace_location_organiser_poster_title">"Print Version"</string>
 </resources>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/values-pl/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values-pl/contact_diary_strings.xml
index d692b474a74c82904f040eca98cc3835f57e8abb..dcec3c8b4cf4e134170a6e6d278facaee44e05dd 100644
--- a/Corona-Warn-App/src/main/res/values-pl/contact_diary_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-pl/contact_diary_strings.xml
@@ -76,6 +76,13 @@
     <string name="contact_diary_risk_body_high_risk_due_to_low_risk_encounters">"na podstawie wielu narażeń o niskim ryzyku."</string>
     <!-- XTXT: Extended Body for contact diary overview screen risk information -->
     <string name="contact_diary_risk_body_extended">"Niekoniecznie sÄ… one zwiÄ…zane z zarejestrowanymi przez Ciebie osobami i miejscami."</string>
+    <!-- XTXT: Body for contact diary overview screen trace location risk information prelude -->
+    <string name="contact_diary_trace_location_risk_body">"na podstawie ich obecności w:"</string>
+    <!-- XTXT: Indicates this trace location caused a high risk  -->
+    <string name="contact_diary_trace_location_risk_high">"podwyższone ryzyko"</string>
+    <!-- XTXT: Indicates this trace location caused a lows risk -->
+    <string name="contact_diary_trace_location_risk_low">"niskie ryzyko"</string>
+
 
 
     <!-- XTXT: content description of contact journal image on home screen -->
diff --git a/Corona-Warn-App/src/main/res/values-pl/event_registration_strings.xml b/Corona-Warn-App/src/main/res/values-pl/event_registration_strings.xml
index 8fff5ab6706aeb3a6a149f614f93f1b803a61ced..4e9ce1076fc61d75dba61ac001080394a2cb94ab 100644
--- a/Corona-Warn-App/src/main/res/values-pl/event_registration_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-pl/event_registration_strings.xml
@@ -135,6 +135,33 @@
     <string name="create_trace_location_card_subtitle">"Planujesz wydarzenie lub prowadzisz firmę? Utwórz kod QR, aby Twoi goście mogli zameldować się po przybyciu na miejsce."</string>
     <!-- XTXT: Text for trace location creation card -->
     <string name="create_trace_location_card_button">"Utwórz kod QR"</string>
+    <!-- XTXT: Text for content description of tile image -->
+    <string name="create_trace_location_card_content_description">"Osoba wskazuje na tablicÄ™ flipchart."</string>
+
+    <!--    Trace Location QR Code Info Screen-->
+    <!-- XTXT: Text for content description of info screen image -->
+    <string name="trace_location_qr_info_content_description">"Jedna osoba wskazuje na tablicÄ™ flipchart, a dwie inne osoby siedzÄ… obok i patrzÄ… na flipchart."</string>
+    <!-- XHED: Headline for trace location creation card -->
+    <string name="trace_location_qr_info_headline_text">"Większe bezpieczeństwo dla Ciebie i Twoich gości"</string>
+    <!-- XTXT: Text for subtitle of qr info screen -->
+    <string name="trace_location_qr_info_subtitle_text">"Utwórz kod QR, który Twoi goście będą mogli zeskanować po przybyciu. Dzięki temu będą mogli ostrzegać innych gości lub otrzymywać od nich ostrzeżenia, jeśli zajdzie taka potrzeba."</string>
+    <!-- XTXT: Text for tracing icon of qr info screen -->
+    <string name="trace_location_qr_info_tracing_text">"Każde zameldowanie jest również brane pod uwagę przy obliczaniu statusu ryzyka. Jeśli u osoby, która zameldowała swoją obecność w danym wydarzeniu lub miejscu, zostanie później zdiagnozowany koronawirus, goście zostaną powiadomieni, jeśli przebywali w tym samym pomieszczeniu w tym samym czasie lub do 30 minut po opuszczeniu pomieszczenia przez zdiagnozowaną osobę."</string>
+    <!-- XTXT: Text for qr icon of qr info screen -->
+    <string name="trace_location_qr_info_qr_code_text">"Kod QR możesz przekazać gościom za pomocą smartfona lub w formie drukowanej."</string>
+    <!-- XTXT: Text for time sheet icon of qr info screen -->
+    <string name="trace_location_qr_info_time_text">"Używając kodu QR przez dłuższy czas, musisz generować go ponownie każdego dnia poza godzinami pracy."</string>
+    <!-- XTXT: Text for I understand button -->
+    <string name="acknowledge_button">"Dalej"</string>
+
+    <!-- XHED: Title of the notification channel for event registration related notifications. -->
+    <string name="tracelocation_notification_channel_title">"Zameldowania"</string>
+    <!-- XTXT: Description of the notification channel for event registration related notifications. -->
+    <string name="tracelocation_notification_channel_description">"Powiadomienia o zameldowaniach i wymeldowaniach, np. o automatycznym wymeldowaniu."</string>
+    <!-- XHED: Title of the automatic check-out notification. -->
+    <string name="tracelocation_notification_autocheckout_title">"Nastąpiło automatyczne wymeldowanie."</string>
+    <!-- XTXT: Description of the automatic check-out notification. -->
+    <string name="tracelocation_notification_autocheckout_description">"W razie potrzeby dostosuj długość pobytu."</string>
 
     <!-- ####################################
        Event Organiser Trace Locations List
@@ -173,6 +200,11 @@
     <!-- XBUT: Event organiser list item: checkin button -->
     <string name="trace_location_organizer_list_item_action_checkin">"Zamelduj siÄ™"</string>
 
+    <!-- XTXT: Event organizer detail qr-code: duration with date -->
+    <string name="trace_location_organizer_detail_item_duration">"%1$s, %2$s - %3$s"</string>
+    <!-- XTXT: Event organizer detail qr-code: duration with multiple date -->
+    <string name="trace_location_organizer_detail_item_duration_multiple_days">"%1$s, %2$s - %3$s, %4$s"</string>
+
     <!-- XBUT: Event organiser list item: menu: information button  -->
     <string name="trace_location_organizer_list_item_menu_duplicate_btn">"Duplikuj"</string>
     <!-- XBUT: Event organiser list item: menu: show print button  -->
@@ -180,12 +212,42 @@
     <!-- XBUT: Event organiser list item: menu: clear button  -->
     <string name="trace_location_organizer_list_item_menu_clear_btn">"Usuń"</string>
 
+    <!-- Trace Location Checkin Confirmation -->
+    <!-- XHED: Checkin Confirm: title for screen -->
+    <string name="confirm_checkin_title_text">"Zamelduj siÄ™ na:"</string>
+    <!-- XTXT: Checkin Confirm: text for event is in future info card -->
+    <string name="confirm_checkin_event_in_future_card_text">"To wydarzenie zaczyna się dopiero %2$s w dniu %1$s. Czy chcesz się zameldować już teraz?"</string>
+    <!-- XTXT: Checkin Confirm: text for event is in past info card -->
+    <string name="confirm_checkin_event_in_past_card_text">"To wydarzenie już się skończyło. Czy chcesz się zameldować z datą wsteczną?"</string>
+    <!-- XTXT: Checkin Confirm: label for save to contact diary toggle -->
+    <string name="confirm_checkin_settings_card_checkout_toggle_label">"Zapisać w dzienniku kontaktów po wymeldowaniu?"</string>
+    <!-- XTXT: Checkin Confirm: label for checkout delay selection -->
+    <string name="confirm_checkin_settings_card_checkout_time_label">"Wymelduj automatycznie po"</string>
+    <!-- XTXT: Checkin Confirm: time length label for checkout delay selection -->
+    <string name="confirm_checkin_settings_card_checkout_time_tag">"godz."</string>
+    <!-- XBUT: Checkin Confirm: Checkin Button -->
+    <string name="confirm_checkin_confirm_button_text">"Zamelduj siÄ™"</string>
+
+    <!-- Trace Location Checkin Editing -->
+    <!-- XHED: Checkin Edit: title for screen -->
+    <string name="edit_checkin_title_text">"Zmień długość pobytu dla:"</string>
+    <!-- XTXT: Checkin Edit: label for checkout time -->
+    <string name="edit_checkin_edit_card_checkout_time_label">"Wymeldowano"</string>
+    <!-- XTXT: Checkin Edit: label for checkin time -->
+    <string name="edit_checkin_edit_card_checkin_time_label">"Zameldowano"</string>
+    <!-- XTXT: Checkin Edit: hint for unchanged contact diary checkin duration -->
+    <string name="edit_checkin_duration_edit_hint_card_text">"Długość pobytu nie zostanie automatycznie skorygowana w Twoim dzienniku kontaktów."</string>
+    <!-- XTXT: Checkin Edit: warning if user input is incorrect -->
+    <string name="edit_checkin_wrong_input_warning_text">"Maksymalny czas trwania zameldowania wynosi 24 godziny. Godzina wymeldowania musi być późniejsza niż godzina zameldowania."</string>
+    <!-- XBUT: Checkin Edit: Save Button -->
+    <string name="edit_checkin_confirm_button_text">"Zapisz"</string>
+
     <!--  Organizer Flow: Event Detail Screen-->
     <!-- XTXT: Organizer Flow : Accessibility description for qr-code illustration -->
     <string name="trace_location_event_detail_qr_code_accessibility">"Kod QR"</string>
     <!-- XHED: Organizer Flow : Accessibility title for event-overview -->
     <string name="trace_location_event_detail_title_accessibility">"Widok wydarzenia"</string>
-    !-- XBUT: Organizer Flow : Title for show print version button --&gt;
+    <!-- XBUT: Organizer Flow : Title for show print version button -->
     <string name="trace_location_event_detail_show_print_qr_code_button">"Wyświetl wersję do druku"</string>
     <!-- XBUT: Organizer Flow : Title for save as template button -->
     <string name="trace_location_event_detail_save_as_template_button">"Użyj jako szablonu"</string>
diff --git a/Corona-Warn-App/src/main/res/values-pl/release_info_strings.xml b/Corona-Warn-App/src/main/res/values-pl/release_info_strings.xml
index 1ebf43917e62a93e1abafb0300b731da43b92fe9..0363f66e3a4d211dd76f266b8dd1bde827db5ea6 100644
--- a/Corona-Warn-App/src/main/res/values-pl/release_info_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-pl/release_info_strings.xml
@@ -21,7 +21,7 @@
 
     <!-- XTXT: Text bodies for the release info screen bullet points -->
     <string-array name="new_release_body">
-        <item>"CWA umożliwia teraz meldowanie obecności w wydarzeniach i miejscach. Organizatorzy wydarzeń i właściciele sklepów mogą wykorzystać tę aplikację do utworzenia kodu QR. Goście mogą zeskanować ten kod QR po przybyciu na miejsce, aby zarejestrować swoją obecność. Na życzenie aplikacja może również utworzyć wpis w dzienniku. Jeśli u osoby, która zameldowała swoją obecność w danym wydarzeniu lub miejscu, zostanie później zdiagnozowany koronawirus, wszystkie  osoby, które zameldowały się w tym samym czasie, zostaną o tym automatycznie powiadomione."</item>
+        <item>"CWA umożliwia teraz meldowanie obecności w wydarzeniach i miejscach. Organizatorzy wydarzeń i właściciele sklepów mogą wykorzystać tę aplikację do utworzenia kodu QR. Goście mogą zeskanować ten kod QR po przybyciu na miejsce, aby zarejestrować swoją obecność. Na życzenie aplikacja może również utworzyć wpis w dzienniku. Jeśli u osoby, która zameldowała swoją obecność w danym wydarzeniu lub miejscu, zostanie później zdiagnozowany koronawirus, inne osoby, które zameldowały się w tym samym czasie, otrzymają automatyczne ostrzeżenie."</item>
     </string-array>
 
     <!-- XTXT: Text labels that will be converted to Links -->
diff --git a/Corona-Warn-App/src/main/res/values-pl/strings.xml b/Corona-Warn-App/src/main/res/values-pl/strings.xml
index 2b395e1915458f83f0ca29f89863697a767f377b..c0c4d62a5e992784ad81c673262b3cad75116089 100644
--- a/Corona-Warn-App/src/main/res/values-pl/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-pl/strings.xml
@@ -30,6 +30,10 @@
     <!-- ####################################
                Notification
     ###################################### -->
+    <!-- XHED: Title of the notification channel for general CWA notifications (e.g. risk change) -->
+    <string name="general_notification_channel_title">"Ogólne"</string>
+    <!-- XTXT: Description of the notification channel for general CWA notifications (e.g. risk change) -->
+    <string name="general_notification_channel_description">"Przypomnienia, notatki i ogólne powiadomienia – na przykład o statusie ryzyka."</string>
     <!-- XHED: Notification title -->
     <string name="notification_headline">"Corona-Warn-App"</string>
     <!-- XTXT: Notification body -->
@@ -301,7 +305,7 @@
 <!--    Dialog part 1-->
     <string name="risk_details_information_body_period_logged">"Ryzyko zakażenia można obliczyć tylko dla okresów, w których rejestrowanie narażenia było aktywne. Dlatego też funkcja rejestrowania powinna być stale aktywna. Rejestrowanie narażenia obejmuje 14 ostatnich dni."</string>
     <!-- XTXT: risk details - infection period logged information body, under 14 days -->
-    <string name="risk_details_information_body_period_logged_assessment_under_14_days">"Aplikacja Corona-Warn-App została zainstalowana %s temu. Ryzyko zakażenia jest obliczane dla okresów, w których aktywne było rejestrowanie narażenia. Oblicza się je w przypadku kontaktowania się z innymi ludźmi przy aktywnej funkcji rejestrowania narażenia."</string>
+    <string name="risk_details_information_body_period_logged_assessment_under_14_days">"Aplikacja Corona-Warn-App została zainstalowana %s dni temu. Ryzyko zakażenia jest obliczane dla okresów, w których aktywne było rejestrowanie narażenia. Oblicza się je w przypadku kontaktowania się z innymi ludźmi przy aktywnej funkcji rejestrowania narażenia."</string>
     <!-- XTXT: risk details - infection period logged information body, over 14 days -->
     <string name="risk_details_information_body_period_logged_assessment_over_14_days">"Jeśli rejestrowanie narażenia było aktywne podczas kontaktowania się z innymi ludźmi, można obliczyć ryzyko zakażenia dla tego okresu."</string>
     <!-- XHED: risk details - infection period logged information body, below behaviors -->	    <!-- XTXT: risk details - infection period logged information body, under 14 days -->
@@ -1793,13 +1797,13 @@
     <string name="statistics_reproduction_title">"Aktualnie"</string>
     <!-- XTXT: Caption for statistics reproduction card -->
     <string name="statistics_reproduction_average">"średnia liczba zakażeń przez zakażoną osobę"</string>
-
     <!-- XTXT: Statistics trend increasing (Accessibilty) -->
     <string name="statistics_trend_increasing">"Trend: RosnÄ…cy"</string>
     <!-- XTXT: Statistics trend decreasing (Accessibilty) -->
     <string name="statistics_trend_decreasing">"Trend: MalejÄ…cy"</string>
     <!-- XTXT: Statistics trend stable (Accessibilty) -->
     <string name="statistics_trend_stable">"Trend: Stabilny"</string>
+
     <!-- XHED: Title for BottomNav main screen title -->
     <string name="bottom_nav_home_title">"Ekran poczÄ…tkowy"</string>
     <!-- XHED: Title for BottomNav diary screen title -->
@@ -1955,4 +1959,18 @@
     <string name="trace_location_onboarding_body_stay">"Określ długość pobytu jak najdokładniej, aby ostrzeżenia mogły zostać odpowiednio dopasowane."</string>
     <!-- XACT: Button/Dialog label to consent-->
     <string name="trace_location_onboarding_body_confirm">"Akceptuj"</string>
+    <!--  XHED: Trace location check-ins camera permission card title-->
+    <string name="trace_location_attendee_camera_card_title">"Zezwól na dostęp do aparatu"</string>
+    <!--  XTXT: Trace location check-ins camera permission card susbtitle-->
+    <string name="trace_location_attendee_camera_card_subtitle">"Aby używać aparatu w smartfonie do skanowania kodów QR, musisz zezwolić na dostęp do aparatu w ustawieniach urządzenia dla aplikacji."</string>
+    <!--  XBUT: Trace location check-ins camera permission card button-->
+    <string name="trace_location_attendee_camera_card_button">"Otwórz opcję Ustawienia"</string>
+    <!--  YMSG: Trace location onboarding image description-->
+    <string name="trace_location_onboarding_content_description">"Trzy osoby stojÄ… przy wysokim stole, dwie z nich patrzÄ… na swoje smartfony."</string>
+    <!-- XMIT: Trace location poster print -->
+    <string name="trace_location_organiser_poster_print">"Drukuj"</string>
+    <!-- XMIT: Trace location poster share -->
+    <string name="trace_location_organiser_poster_share">"Udostępnij"</string>
+    <!-- XHED: Trace location poster title -->
+    <string name="trace_location_organiser_poster_title">"Wersja do druku"</string>
 </resources>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/values-ro/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values-ro/contact_diary_strings.xml
index c7f0d2b21c4b6fe785418c674c31ed2adba0d33c..3811f313e6f41eb4828478d4690cedf83dd0bde4 100644
--- a/Corona-Warn-App/src/main/res/values-ro/contact_diary_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-ro/contact_diary_strings.xml
@@ -76,6 +76,13 @@
     <string name="contact_diary_risk_body_high_risk_due_to_low_risk_encounters">"pe baza mai multor expuneri cu risc redus."</string>
     <!-- XTXT: Extended Body for contact diary overview screen risk information -->
     <string name="contact_diary_risk_body_extended">"Acestea nu sunt legate neapărat de persoanele și locurile pe care le-ați înregistrat."</string>
+    <!-- XTXT: Body for contact diary overview screen trace location risk information prelude -->
+    <string name="contact_diary_trace_location_risk_body">"pe baza prezenței la:"</string>
+    <!-- XTXT: Indicates this trace location caused a high risk  -->
+    <string name="contact_diary_trace_location_risk_high">"risc crescut"</string>
+    <!-- XTXT: Indicates this trace location caused a lows risk -->
+    <string name="contact_diary_trace_location_risk_low">"risc redus"</string>
+
 
 
     <!-- XTXT: content description of contact journal image on home screen -->
diff --git a/Corona-Warn-App/src/main/res/values-ro/event_registration_strings.xml b/Corona-Warn-App/src/main/res/values-ro/event_registration_strings.xml
index f65ea84b0e901665098615bf983b2cad4b00db27..d3211806019b512d0c83c7f53041c81edb686e03 100644
--- a/Corona-Warn-App/src/main/res/values-ro/event_registration_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-ro/event_registration_strings.xml
@@ -135,6 +135,33 @@
     <string name="create_trace_location_card_subtitle">"Planificați un eveniment sau aveți o afacere? Creați un cod QR pentru ca invitații dvs. să poată face check-in când sosesc."</string>
     <!-- XTXT: Text for trace location creation card -->
     <string name="create_trace_location_card_button">"Creare cod QR"</string>
+    <!-- XTXT: Text for content description of tile image -->
+    <string name="create_trace_location_card_content_description">"O persoană arată către un flipchart."</string>
+
+    <!--    Trace Location QR Code Info Screen-->
+    <!-- XTXT: Text for content description of info screen image -->
+    <string name="trace_location_qr_info_content_description">"O persoană arată către un flipchart, în timp ce două persoane stau în apropiere și privesc flipchartul."</string>
+    <!-- XHED: Headline for trace location creation card -->
+    <string name="trace_location_qr_info_headline_text">"Siguranță crescută pentru dvs. și invitații dvs."</string>
+    <!-- XTXT: Text for subtitle of qr info screen -->
+    <string name="trace_location_qr_info_subtitle_text">"Creați un cod QR pe care îl pot scana invitații dvs. atunci când sosesc. Acesta îi va ajuta să îi avertizeze pe ceilalți invitați sau să fie avertizați de ei, dacă este necesar."</string>
+    <!-- XTXT: Text for tracing icon of qr info screen -->
+    <string name="trace_location_qr_info_tracing_text">"La calcularea stării riscului este luat în calcul și fiecare check-in. Dacă o persoană care a făcut check-in la acest eveniment sau în acest loc este diagnosticată ulterior cu coronavirus, invitații pot fi notificați dacă au fost în aceeași cameră în același timp sau în decurs de 30 de minute după persoana diagnosticată."</string>
+    <!-- XTXT: Text for qr icon of qr info screen -->
+    <string name="trace_location_qr_info_qr_code_text">"Puteți furniza codul QR invitaților dvs. de pe smartphone-ul dvs. sau în formă tipărită."</string>
+    <!-- XTXT: Text for time sheet icon of qr info screen -->
+    <string name="trace_location_qr_info_time_text">"Dacă doriți să utilizați un cod QR pe termen lung, generați-l din nou în fiecare zi, în afara programului dvs. de lucru."</string>
+    <!-- XTXT: Text for I understand button -->
+    <string name="acknowledge_button">"ÃŽnainte"</string>
+
+    <!-- XHED: Title of the notification channel for event registration related notifications. -->
+    <string name="tracelocation_notification_channel_title">"Check-inuri"</string>
+    <!-- XTXT: Description of the notification channel for event registration related notifications. -->
+    <string name="tracelocation_notification_channel_description">"Notificări despre check-inurile dvs., precum check-outul automat."</string>
+    <!-- XHED: Title of the automatic check-out notification. -->
+    <string name="tracelocation_notification_autocheckout_title">"Ați făcut check-out automat."</string>
+    <!-- XTXT: Description of the automatic check-out notification. -->
+    <string name="tracelocation_notification_autocheckout_description">"Ajustați durata șederii dvs. dacă este necesar."</string>
 
     <!-- ####################################
        Event Organiser Trace Locations List
@@ -173,6 +200,11 @@
     <!-- XBUT: Event organiser list item: checkin button -->
     <string name="trace_location_organizer_list_item_action_checkin">"Check-in"</string>
 
+    <!-- XTXT: Event organizer detail qr-code: duration with date -->
+    <string name="trace_location_organizer_detail_item_duration">"%1$s, %2$s - %3$s"</string>
+    <!-- XTXT: Event organizer detail qr-code: duration with multiple date -->
+    <string name="trace_location_organizer_detail_item_duration_multiple_days">"%1$s, %2$s - %3$s, %4$s"</string>
+
     <!-- XBUT: Event organiser list item: menu: information button  -->
     <string name="trace_location_organizer_list_item_menu_duplicate_btn">"Duplicare"</string>
     <!-- XBUT: Event organiser list item: menu: show print button  -->
@@ -180,12 +212,42 @@
     <!-- XBUT: Event organiser list item: menu: clear button  -->
     <string name="trace_location_organizer_list_item_menu_clear_btn">"Ștergere"</string>
 
+    <!-- Trace Location Checkin Confirmation -->
+    <!-- XHED: Checkin Confirm: title for screen -->
+    <string name="confirm_checkin_title_text">"Check-in pentru:"</string>
+    <!-- XTXT: Checkin Confirm: text for event is in future info card -->
+    <string name="confirm_checkin_event_in_future_card_text">"Acest eveniment nu începe până la %2$s pe %1$s. Doriți să faceți deja check-inul?"</string>
+    <!-- XTXT: Checkin Confirm: text for event is in past info card -->
+    <string name="confirm_checkin_event_in_past_card_text">"Aceste eveniment s-a încheiat deja. Doriți să faceți check-in retroactiv?"</string>
+    <!-- XTXT: Checkin Confirm: label for save to contact diary toggle -->
+    <string name="confirm_checkin_settings_card_checkout_toggle_label">"Înregistrați în jurnalul meu de contacte după check-out?"</string>
+    <!-- XTXT: Checkin Confirm: label for checkout delay selection -->
+    <string name="confirm_checkin_settings_card_checkout_time_label">"Check-out automat după"</string>
+    <!-- XTXT: Checkin Confirm: time length label for checkout delay selection -->
+    <string name="confirm_checkin_settings_card_checkout_time_tag">"ore"</string>
+    <!-- XBUT: Checkin Confirm: Checkin Button -->
+    <string name="confirm_checkin_confirm_button_text">"Check-in"</string>
+
+    <!-- Trace Location Checkin Editing -->
+    <!-- XHED: Checkin Edit: title for screen -->
+    <string name="edit_checkin_title_text">"Modificare lungime ședere pentru:"</string>
+    <!-- XTXT: Checkin Edit: label for checkout time -->
+    <string name="edit_checkin_edit_card_checkout_time_label">"Check-out făcut"</string>
+    <!-- XTXT: Checkin Edit: label for checkin time -->
+    <string name="edit_checkin_edit_card_checkin_time_label">"Check-in făcut"</string>
+    <!-- XTXT: Checkin Edit: hint for unchanged contact diary checkin duration -->
+    <string name="edit_checkin_duration_edit_hint_card_text">"Lungimea șederii nu va fi ajustată automat în jurnalul dvs. de contacte."</string>
+    <!-- XTXT: Checkin Edit: warning if user input is incorrect -->
+    <string name="edit_checkin_wrong_input_warning_text">"Puteți rămâne cu check-inul făcut maximum 24 de ore. Ora de check-out trebuie să fie după ora de check-in."</string>
+    <!-- XBUT: Checkin Edit: Save Button -->
+    <string name="edit_checkin_confirm_button_text">"Salvare"</string>
+
     <!--  Organizer Flow: Event Detail Screen-->
     <!-- XTXT: Organizer Flow : Accessibility description for qr-code illustration -->
     <string name="trace_location_event_detail_qr_code_accessibility">"Cod QR"</string>
     <!-- XHED: Organizer Flow : Accessibility title for event-overview -->
     <string name="trace_location_event_detail_title_accessibility">"Vizualizare eveniment"</string>
-    !-- XBUT: Organizer Flow : Title for show print version button --&gt;
+    <!-- XBUT: Organizer Flow : Title for show print version button -->
     <string name="trace_location_event_detail_show_print_qr_code_button">"Afișare versiune de tipărire"</string>
     <!-- XBUT: Organizer Flow : Title for save as template button -->
     <string name="trace_location_event_detail_save_as_template_button">"Utilizare ca șablon"</string>
diff --git a/Corona-Warn-App/src/main/res/values-ro/release_info_strings.xml b/Corona-Warn-App/src/main/res/values-ro/release_info_strings.xml
index dd71c100b52d851f2dfb7f1915b246faadc7ef94..ca0f51243fa69b448026fb667961916e8e1a2df4 100644
--- a/Corona-Warn-App/src/main/res/values-ro/release_info_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-ro/release_info_strings.xml
@@ -21,7 +21,7 @@
 
     <!-- XTXT: Text bodies for the release info screen bullet points -->
     <string-array name="new_release_body">
-        <item>"Acum, aplicația Corona-Warn vă permite să faceți check-in la evenimente și în locuri. Organizatorii de evenimente și proprietarii de magazine pot utiliza aplicația pentru a crea un cod QR. Apoi, invitații pot scana acest cod QR atunci când sosesc, pentru a-și înregistra prezența. De asemenea, aplicația poate crea la cerere o intrare în jurnal. Dacă o persoană care a făcut check-in la acest eveniment sau în acest loc este diagnosticată ulterior cu coronavirus, toate persoanele care au făcut check-in în același timp sunt notificate automat."</item>
+        <item>"Acum, aplicația Corona-Warn vă permite să faceți check-in la evenimente și în locuri. Organizatorii de evenimente și proprietarii de magazine pot utiliza aplicația pentru a crea un cod QR. Apoi, invitații pot scana acest cod QR atunci când sosesc, pentru a-și înregistra prezența. De asemenea, aplicația poate crea la cerere o intrare în jurnal. Dacă o persoană care a făcut check-in la acest eveniment sau în acest loc este diagnosticată ulterior cu coronavirus, alte persoane care au făcut check-in în același timp pot fi avertizate automat."</item>
     </string-array>
 
     <!-- XTXT: Text labels that will be converted to Links -->
diff --git a/Corona-Warn-App/src/main/res/values-ro/strings.xml b/Corona-Warn-App/src/main/res/values-ro/strings.xml
index 42f54f41a08888f4e4bde2234ae3e0747b7b3710..50d09ff8ae9d5fb6ce85e1264004498cf2e98d83 100644
--- a/Corona-Warn-App/src/main/res/values-ro/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-ro/strings.xml
@@ -30,6 +30,10 @@
     <!-- ####################################
                Notification
     ###################################### -->
+    <!-- XHED: Title of the notification channel for general CWA notifications (e.g. risk change) -->
+    <string name="general_notification_channel_title">"Generale"</string>
+    <!-- XTXT: Description of the notification channel for general CWA notifications (e.g. risk change) -->
+    <string name="general_notification_channel_description">"Mementouri, note și notificări generale – de exemplu, despre starea riscului dvs."</string>
     <!-- XHED: Notification title -->
     <string name="notification_headline">"Corona-Warn-App"</string>
     <!-- XTXT: Notification body -->
@@ -301,7 +305,7 @@
 <!--    Dialog part 1-->
     <string name="risk_details_information_body_period_logged">"Riscul dvs. de infectare poate fi calculat doar pentru perioadele în care a fost activă înregistrarea în jurnal a expunerilor. Prin urmare, caracteristica de înregistrare în jurnal trebuie să rămână permanent activă. Înregistrarea în jurnal a expunerilor acoperă ultimele 14 zile."</string>
     <!-- XTXT: risk details - infection period logged information body, under 14 days -->
-    <string name="risk_details_information_body_period_logged_assessment_under_14_days">"Aplicația Corona-Warn a fost instalată acum %s. Riscul dvs. de infectare este calculat pentru perioadele în care înregistrarea în jurnal a expunerilor a fost activă. Dacă v-ați întâlnit cu alte persoane și înregistrarea în jurnal a expunerilor a fost activă, este calculat riscul dvs. de infectare."</string>
+    <string name="risk_details_information_body_period_logged_assessment_under_14_days">"Aplicația Corona-Warn a fost instalată acum %s zi(le). Riscul dvs. de infectare este calculat pentru perioadele în care înregistrarea în jurnal a expunerilor a fost activă. Dacă v-ați întâlnit cu alte persoane și înregistrarea în jurnal a expunerilor a fost activă, este calculat riscul dvs. de infectare."</string>
     <!-- XTXT: risk details - infection period logged information body, over 14 days -->
     <string name="risk_details_information_body_period_logged_assessment_over_14_days">"Dacă înregistrarea în jurnal a expunerilor a fost activă pe durata în care v-ați întâlnit cu alte persoane, riscul dvs. de infectare poate fi calculat pentru această perioadă."</string>
     <!-- XHED: risk details - infection period logged information body, below behaviors -->	    <!-- XTXT: risk details - infection period logged information body, under 14 days -->
@@ -1793,13 +1797,13 @@
     <string name="statistics_reproduction_title">"Curentă"</string>
     <!-- XTXT: Caption for statistics reproduction card -->
     <string name="statistics_reproduction_average">"infecții medii de la fiecare persoană infectată"</string>
-
     <!-- XTXT: Statistics trend increasing (Accessibilty) -->
     <string name="statistics_trend_increasing">"Tendință: ascendentă"</string>
     <!-- XTXT: Statistics trend decreasing (Accessibilty) -->
     <string name="statistics_trend_decreasing">"Tendință: descendentă"</string>
     <!-- XTXT: Statistics trend stable (Accessibilty) -->
     <string name="statistics_trend_stable">"Tendință: constantă"</string>
+
     <!-- XHED: Title for BottomNav main screen title -->
     <string name="bottom_nav_home_title">"Ecran inițial"</string>
     <!-- XHED: Title for BottomNav diary screen title -->
@@ -1955,4 +1959,18 @@
     <string name="trace_location_onboarding_body_stay">"Specificați durata șederii cât mai precis posibil pentru a permite avertizările exacte."</string>
     <!-- XACT: Button/Dialog label to consent-->
     <string name="trace_location_onboarding_body_confirm">"Accept"</string>
+    <!--  XHED: Trace location check-ins camera permission card title-->
+    <string name="trace_location_attendee_camera_card_title">"Permite accesul la cameră"</string>
+    <!--  XTXT: Trace location check-ins camera permission card susbtitle-->
+    <string name="trace_location_attendee_camera_card_subtitle">"Pentru a utiliza camera smartphone-ului să scanați codurile QR, trebuie să permiteți accesul la cameră în setările dispozitivului pentru aplicație."</string>
+    <!--  XBUT: Trace location check-ins camera permission card button-->
+    <string name="trace_location_attendee_camera_card_button">"Deschideți Configurări"</string>
+    <!--  YMSG: Trace location onboarding image description-->
+    <string name="trace_location_onboarding_content_description">"Trei persoane stau în picioare la o masă înaltă, iar două dintre ele se uită pe smartphone."</string>
+    <!-- XMIT: Trace location poster print -->
+    <string name="trace_location_organiser_poster_print">"Tipărire"</string>
+    <!-- XMIT: Trace location poster share -->
+    <string name="trace_location_organiser_poster_share">"Partajare"</string>
+    <!-- XHED: Trace location poster title -->
+    <string name="trace_location_organiser_poster_title">"Versiune de tipărire"</string>
 </resources>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/values-tr/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values-tr/contact_diary_strings.xml
index dd2de4ef2aa4a159bb9dc50ce58385acfb2facba..ba14375c44e5d0603fb96eed435c86613589e86c 100644
--- a/Corona-Warn-App/src/main/res/values-tr/contact_diary_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-tr/contact_diary_strings.xml
@@ -76,6 +76,13 @@
     <string name="contact_diary_risk_body_high_risk_due_to_low_risk_encounters">"(düşük riskli birden fazla maruz kalmaya göre)."</string>
     <!-- XTXT: Extended Body for contact diary overview screen risk information -->
     <string name="contact_diary_risk_body_extended">"Kaydettiğiniz kişilerle ve yerlerle ilgili olmaları şart değildir."</string>
+    <!-- XTXT: Body for contact diary overview screen trace location risk information prelude -->
+    <string name="contact_diary_trace_location_risk_body">"temel alınan katılım:"</string>
+    <!-- XTXT: Indicates this trace location caused a high risk  -->
+    <string name="contact_diary_trace_location_risk_high">"daha yüksek risk"</string>
+    <!-- XTXT: Indicates this trace location caused a lows risk -->
+    <string name="contact_diary_trace_location_risk_low">"düşük risk"</string>
+
 
 
     <!-- XTXT: content description of contact journal image on home screen -->
diff --git a/Corona-Warn-App/src/main/res/values-tr/event_registration_strings.xml b/Corona-Warn-App/src/main/res/values-tr/event_registration_strings.xml
index a021d8daa3264b99c1afb31431d4ab95715d2ca8..4e87da23cd26e40c79ca1eb46498f39ebf8cac32 100644
--- a/Corona-Warn-App/src/main/res/values-tr/event_registration_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-tr/event_registration_strings.xml
@@ -135,6 +135,33 @@
     <string name="create_trace_location_card_subtitle">"Bir etkinlik planlıyor ya da işletme mi çalıştırıyorsunuz? Konuklarınızın geldiklerinde check in yapabilmeleri için bir QR kod oluşturun."</string>
     <!-- XTXT: Text for trace location creation card -->
     <string name="create_trace_location_card_button">"QR Kod OluÅŸtur"</string>
+    <!-- XTXT: Text for content description of tile image -->
+    <string name="create_trace_location_card_content_description">"Bir kişi bir kağıt tahtayı işaret ediyor."</string>
+
+    <!--    Trace Location QR Code Info Screen-->
+    <!-- XTXT: Text for content description of info screen image -->
+    <string name="trace_location_qr_info_content_description">"Bir kişi bir kağıt tahtayı işaret ederken iki kişi yanında oturuyor ve tahtaya bakıyor."</string>
+    <!-- XHED: Headline for trace location creation card -->
+    <string name="trace_location_qr_info_headline_text">"Siz ve Konuklarınız için Daha Yüksek Düzeyde Güvenlik"</string>
+    <!-- XTXT: Text for subtitle of qr info screen -->
+    <string name="trace_location_qr_info_subtitle_text">"Geldiklerinde konuklarınızın tarayabilmeleri için bir QR kod oluşturun. Bu sayede gerekirse diğer konukları uyarabilir ya da diğer konuklardan uyarı alabileceklerdir."</string>
+    <!-- XTXT: Text for tracing icon of qr info screen -->
+    <string name="trace_location_qr_info_tracing_text">"Risk durumu hesaplanırken her bir check-in de dikkate alınır. Bu etkinliğe veya yere check in yapan biri daha sonra koronavirüs tanısı alırsa tanı alan kişi ile aynı anda ya da bu kişi odadan çıktıktan sonra en fazla 30 dakika içinde aynı odada bulunmuşlarsa konuklara uyarı gönderilebilir."</string>
+    <!-- XTXT: Text for qr icon of qr info screen -->
+    <string name="trace_location_qr_info_qr_code_text">"QR kodu konuklarınıza akıllı telefonunuzda ya da yazılı bir form halinde sunabilirsiniz."</string>
+    <!-- XTXT: Text for time sheet icon of qr info screen -->
+    <string name="trace_location_qr_info_time_text">"QR kodu uzun süreli olarak kullanmak istiyorsanız mesai saatlerinizin dışında her gün yeniden QR kod oluşturmanız gerekir."</string>
+    <!-- XTXT: Text for I understand button -->
+    <string name="acknowledge_button">"Sonraki"</string>
+
+    <!-- XHED: Title of the notification channel for event registration related notifications. -->
+    <string name="tracelocation_notification_channel_title">"Check-In’ler"</string>
+    <!-- XTXT: Description of the notification channel for event registration related notifications. -->
+    <string name="tracelocation_notification_channel_description">"Check-in’lerinizle ilgili bildirimler; örneğin, otomatik check-out."</string>
+    <!-- XHED: Title of the automatic check-out notification. -->
+    <string name="tracelocation_notification_autocheckout_title">"Otomatik olarak check out yaptınız."</string>
+    <!-- XTXT: Description of the automatic check-out notification. -->
+    <string name="tracelocation_notification_autocheckout_description">"Gerekiyorsa lütfen kalış sürenizi düzenleyin."</string>
 
     <!-- ####################################
        Event Organiser Trace Locations List
@@ -173,6 +200,11 @@
     <!-- XBUT: Event organiser list item: checkin button -->
     <string name="trace_location_organizer_list_item_action_checkin">"Check In"</string>
 
+    <!-- XTXT: Event organizer detail qr-code: duration with date -->
+    <string name="trace_location_organizer_detail_item_duration">"%1$s, %2$s - %3$s"</string>
+    <!-- XTXT: Event organizer detail qr-code: duration with multiple date -->
+    <string name="trace_location_organizer_detail_item_duration_multiple_days">"%1$s, %2$s - %3$s, %4$s"</string>
+
     <!-- XBUT: Event organiser list item: menu: information button  -->
     <string name="trace_location_organizer_list_item_menu_duplicate_btn">"Çoğalt"</string>
     <!-- XBUT: Event organiser list item: menu: show print button  -->
@@ -180,12 +212,42 @@
     <!-- XBUT: Event organiser list item: menu: clear button  -->
     <string name="trace_location_organizer_list_item_menu_clear_btn">"Sil"</string>
 
+    <!-- Trace Location Checkin Confirmation -->
+    <!-- XHED: Checkin Confirm: title for screen -->
+    <string name="confirm_checkin_title_text">"Check in niteliÄŸi:"</string>
+    <!-- XTXT: Checkin Confirm: text for event is in future info card -->
+    <string name="confirm_checkin_event_in_future_card_text">"Bu etkinliğin başlangıç saati, %1$s %2$s olarak belirlenmiştir. Şimdiden check in yapmak istiyor musunuz?"</string>
+    <!-- XTXT: Checkin Confirm: text for event is in past info card -->
+    <string name="confirm_checkin_event_in_past_card_text">"Bu etkinlik zaten bitmiş. Geriye dönük olarak check in yapmak istiyor musunuz?"</string>
+    <!-- XTXT: Checkin Confirm: label for save to contact diary toggle -->
+    <string name="confirm_checkin_settings_card_checkout_toggle_label">"Check-out yapıldıktan sonra temas günceme kaydedilsin mi?"</string>
+    <!-- XTXT: Checkin Confirm: label for checkout delay selection -->
+    <string name="confirm_checkin_settings_card_checkout_time_label">"Daha sonra otomatik olarak check out yap"</string>
+    <!-- XTXT: Checkin Confirm: time length label for checkout delay selection -->
+    <string name="confirm_checkin_settings_card_checkout_time_tag">"sa"</string>
+    <!-- XBUT: Checkin Confirm: Checkin Button -->
+    <string name="confirm_checkin_confirm_button_text">"Check In"</string>
+
+    <!-- Trace Location Checkin Editing -->
+    <!-- XHED: Checkin Edit: title for screen -->
+    <string name="edit_checkin_title_text">"Kalış süresini değiştir:"</string>
+    <!-- XTXT: Checkin Edit: label for checkout time -->
+    <string name="edit_checkin_edit_card_checkout_time_label">"Check Out yapıldı"</string>
+    <!-- XTXT: Checkin Edit: label for checkin time -->
+    <string name="edit_checkin_edit_card_checkin_time_label">"Check In yapıldı"</string>
+    <!-- XTXT: Checkin Edit: hint for unchanged contact diary checkin duration -->
+    <string name="edit_checkin_duration_edit_hint_card_text">"Kalış süresi temas güncenizde otomatik olarak ayarlanmayacak."</string>
+    <!-- XTXT: Checkin Edit: warning if user input is incorrect -->
+    <string name="edit_checkin_wrong_input_warning_text">"Check in’inizi 24 saate kadar sürdürebilirsiniz. Check-out zamanı check-in zamanından sonra olmalıdır."</string>
+    <!-- XBUT: Checkin Edit: Save Button -->
+    <string name="edit_checkin_confirm_button_text">"Kaydet"</string>
+
     <!--  Organizer Flow: Event Detail Screen-->
     <!-- XTXT: Organizer Flow : Accessibility description for qr-code illustration -->
     <string name="trace_location_event_detail_qr_code_accessibility">"QR kod"</string>
     <!-- XHED: Organizer Flow : Accessibility title for event-overview -->
     <string name="trace_location_event_detail_title_accessibility">"Etkinlik Görünümü"</string>
-    !-- XBUT: Organizer Flow : Title for show print version button --&gt;
+    <!-- XBUT: Organizer Flow : Title for show print version button -->
     <string name="trace_location_event_detail_show_print_qr_code_button">"Basılı Versiyonu Görüntüle"</string>
     <!-- XBUT: Organizer Flow : Title for save as template button -->
     <string name="trace_location_event_detail_save_as_template_button">"Åžablon olarak kullan"</string>
diff --git a/Corona-Warn-App/src/main/res/values-tr/release_info_strings.xml b/Corona-Warn-App/src/main/res/values-tr/release_info_strings.xml
index 4306536cd319d23a33380117c5505acc33bcb338..647de500bcd9025e787228efd55ee1c74563e106 100644
--- a/Corona-Warn-App/src/main/res/values-tr/release_info_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-tr/release_info_strings.xml
@@ -21,7 +21,7 @@
 
     <!-- XTXT: Text bodies for the release info screen bullet points -->
     <string-array name="new_release_body">
-        <item>"CWA artık etkinliklere ve yerlere check in yapabilmenizi sağlar. Etkinlik organizatörleri ve mağaza sahipleri uygulamayı kullanarak bir QR kod oluşturabilir. Ardından konuklar geldiklerinde bu QR kodu tarayarak katılımlarını kayıt altına alabilir. Uygulama, talep üzerine günce girişi oluşturma seçeneği de sunmaktadır. Bu etkinliğe ya da yere check in yapan bir kişi daha sonra koronavirüs tanısı alırsa aynı anda check in yapmış herkese otomatik olarak uyarı gönderilir."</item>
+        <item>"CWA artık etkinliklere ve yerlere check in yapabilmenizi sağlar. Etkinlik organizatörleri ve mağaza sahipleri uygulamayı kullanarak bir QR kod oluşturabilir. Ardından konuklar geldiklerinde bu QR kodu tarayarak katılımlarını kayıt altına alabilir. Uygulama, talep üzerine günce girişi oluşturma seçeneği de sunmaktadır. Bu etkinliğe ya da yere check in yapan bir kişi daha sonra koronavirüs tanısı alırsa aynı anda check in yapmış diğer kişilere otomatik olarak uyarı gönderilebilir."</item>
     </string-array>
 
     <!-- XTXT: Text labels that will be converted to Links -->
diff --git a/Corona-Warn-App/src/main/res/values-tr/strings.xml b/Corona-Warn-App/src/main/res/values-tr/strings.xml
index 899b582582ec3dbb5dbaaf1baab5099ccd680900..d080eb6d94cba83a4cab05fbffa1ce71adb7ee8b 100644
--- a/Corona-Warn-App/src/main/res/values-tr/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-tr/strings.xml
@@ -30,6 +30,10 @@
     <!-- ####################################
                Notification
     ###################################### -->
+    <!-- XHED: Title of the notification channel for general CWA notifications (e.g. risk change) -->
+    <string name="general_notification_channel_title">"Genel"</string>
+    <!-- XTXT: Description of the notification channel for general CWA notifications (e.g. risk change) -->
+    <string name="general_notification_channel_description">"Hatırlatmalar, notlar ve genel bildirimler (örneğin, risk durumunuz hakkında)."</string>
     <!-- XHED: Notification title -->
     <string name="notification_headline">"Corona-Warn-App"</string>
     <!-- XTXT: Notification body -->
@@ -303,7 +307,7 @@
     <!-- XTXT: risk details - infection period logged information body, under 14 days -->
     <string name="risk_details_information_body_period_logged_assessment_under_14_days">"Corona-Warn-App %s gün önce yüklendi. Enfeksiyon riskiniz, maruz kalma günlüğünün etkin olduğu dönemler için hesaplanır. Başka insanlarla karşılaşmışsanız ve bu sırada maruz kalma günlüğü etkindiyse enfeksiyon riskiniz hesaplanır."</string>
     <!-- XTXT: risk details - infection period logged information body, over 14 days -->
-    <string name="risk_details_information_body_period_logged_assessment_over_14_days">"Maruz kalma günlüğü başka insanlarla karşılaştığınız sırada etkindiyse bu dönem için enfeksiyon riskiniz hesaplanabilir."</string>
+    <string name="risk_details_information_body_period_logged_assessment_over_14_days">"Maruz kalma günlüğü başka insanlarla karşılaştığınız anlarda etkindiyse bu dönem için enfeksiyon riskiniz hesaplanabilir."</string>
     <!-- XHED: risk details - infection period logged information body, below behaviors -->	    <!-- XTXT: risk details - infection period logged information body, under 14 days -->
     <string name="risk_details_information_body_period_logged_assessment">"Uygulama, enfeksiyondan korunma için artık ilgili olmadığından daha eski kayıtları otomatik olarak siler."</string>
     <!-- XTXT: risk details - infection period days logged/14 -->
@@ -1793,13 +1797,13 @@
     <string name="statistics_reproduction_title">"Åžu Anda"</string>
     <!-- XTXT: Caption for statistics reproduction card -->
     <string name="statistics_reproduction_average">"enfekte olan kişi başına ortalama enfeksiyon sayısı"</string>
-
     <!-- XTXT: Statistics trend increasing (Accessibilty) -->
     <string name="statistics_trend_increasing">"Trend: Yukarı"</string>
     <!-- XTXT: Statistics trend decreasing (Accessibilty) -->
     <string name="statistics_trend_decreasing">"Trend: Aşağı"</string>
     <!-- XTXT: Statistics trend stable (Accessibilty) -->
     <string name="statistics_trend_stable">"Trend: Sabit"</string>
+
     <!-- XHED: Title for BottomNav main screen title -->
     <string name="bottom_nav_home_title">"Başlangıç Ekranı"</string>
     <!-- XHED: Title for BottomNav diary screen title -->
@@ -1955,4 +1959,18 @@
     <string name="trace_location_onboarding_body_stay">"Hedeflenen uyarıları etkinleştirmek için lütfen kalış sürenizi mümkün olduğunca net bir biçimde belirtin."</string>
     <!-- XACT: Button/Dialog label to consent-->
     <string name="trace_location_onboarding_body_confirm">"Kabul Et"</string>
+    <!--  XHED: Trace location check-ins camera permission card title-->
+    <string name="trace_location_attendee_camera_card_title">"Kamera EriÅŸimine Ä°zin Ver"</string>
+    <!--  XTXT: Trace location check-ins camera permission card susbtitle-->
+    <string name="trace_location_attendee_camera_card_subtitle">"Akıllı telefonunuzun kamerasını kullanarak QR kodları taramak için uygulamanın cihaz ayarlarında kamera erişimine izin vermeniz gerekir."</string>
+    <!--  XBUT: Trace location check-ins camera permission card button-->
+    <string name="trace_location_attendee_camera_card_button">"Ayarları Aç"</string>
+    <!--  YMSG: Trace location onboarding image description-->
+    <string name="trace_location_onboarding_content_description">"Üç kişi yüksek bir masanın etrafında ayakta duruyor, ikisi akıllı telefonuna bakıyor."</string>
+    <!-- XMIT: Trace location poster print -->
+    <string name="trace_location_organiser_poster_print">"Yazdır"</string>
+    <!-- XMIT: Trace location poster share -->
+    <string name="trace_location_organiser_poster_share">"PaylaÅŸ"</string>
+    <!-- XHED: Trace location poster title -->
+    <string name="trace_location_organiser_poster_title">"Yazdırma Sürümü"</string>
 </resources>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml
index 80718cbbbd309538f704035c4d9548a2174a934a..2a15f03cf339fb1410ad35260a076f9885391d1b 100644
--- a/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml
+++ b/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" tools:ignore="MissingTranslation">
     <!-- ####################################
-                 Contact Diary
-     ###################################### -->
+                Contact Diary
+    ###################################### -->
     <string name="contact_diary_day_person_tab_title">"People"</string>
     <string name="contact_diary_day_person_fab_title">"Person"</string>
     <string name="contact_diary_day_location_tab_title">"Places"</string>
@@ -64,7 +64,7 @@
     <!-- XTXT: Subtitle for contact diary overview screen -->
     <string name="contact_diary_overview_subtitle">"Write down the people you have met and places you have visited. If a risk is displayed for a day, you can warn people you have been with on that day if they do not use the Corona-Warn-App themselves."</string>
     <!-- XTXT: Header for contact diary overview screen -->
-    <string name="contact_diary_overview_header">Start Page</string>
+    <string name="contact_diary_overview_header">"Start Page"</string>
 
 
     <!-- XTXT: Title for contact diary overview screen high risk information -->
@@ -78,11 +78,12 @@
     <!-- XTXT: Extended Body for contact diary overview screen risk information -->
     <string name="contact_diary_risk_body_extended">"They are not necessarily related to the people and places you have recorded."</string>
     <!-- XTXT: Body for contact diary overview screen trace location risk information prelude -->
-    <string name="contact_diary_trace_location_risk_body">""</string>
+    <string name="contact_diary_trace_location_risk_body">"based on their presence at:"</string>
     <!-- XTXT: Indicates this trace location caused a high risk  -->
-    <string name="contact_diary_trace_location_risk_high">""</string>
+    <string name="contact_diary_trace_location_risk_high">"increased risk"</string>
     <!-- XTXT: Indicates this trace location caused a lows risk -->
-    <string name="contact_diary_trace_location_risk_low">""</string>
+    <string name="contact_diary_trace_location_risk_low">"low risk"</string>
+
 
     <!-- XTXT: content description of contact journal image on home screen -->
     <string name="contact_diary_homescreen_card_image_content_description">"A closed book with a bookmark"</string>
@@ -125,6 +126,7 @@
     <!-- XTXT: Message for the contact diary dialog to delete a single person -->
     <string name="contact_diary_delete_person_message">"If you remove a person, all the entries for that person will be removed from your journal."</string>
 
+    <!-- EXPORT -->
     <!-- XHED: Title for the contact journal export email subject -->
     <string name="contact_diary_export_subject" translatable="false">"Mein Kontakt-Tagebuch"</string>
     <!-- XTXT: Intro text for the contact journal email export part one-->
@@ -208,4 +210,4 @@
     <string name="contact_diary_location_visit_duration_hour">"hrs"</string>
     <!-- XTXT: Option - person encounter - circumstances hint-->
     <string name="contact_diary_location_visit_circumstances_hint">"Note (e.g. very full)"</string>
-</resources>
+</resources>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/values/event_registration_strings.xml b/Corona-Warn-App/src/main/res/values/event_registration_strings.xml
index b748e76ead86b6fc283427c1629e237575db530e..a326943cfb63867f792db7ac14a3789e7bac4326 100644
--- a/Corona-Warn-App/src/main/res/values/event_registration_strings.xml
+++ b/Corona-Warn-App/src/main/res/values/event_registration_strings.xml
@@ -42,7 +42,8 @@
     <string name="trace_location_checkins_card_highlight_duration_label">"Duration"</string>
     <!-- XTXT: My check-ins card: Active event, checkin information, automatic checkout info -->
     <string name="trace_location_checkins_card_automatic_checkout_info">"%1$s - check out automatically after %2$s."</string>
-
+    <!-- XTXT: My check-ins card: Active event, checkin information, automatic checkout info -->
+    <string name="trace_location_checkins_card_automatic_checkout_info_format">"%1$s 2$s - check out automatically after %3$s."</string>
     <!-- XHED: Title of the category list screen of the event creation  -->
     <string name="tracelocation_organizer_category_title">"Create QR Code"</string>
 
@@ -136,33 +137,32 @@
     <!-- XTXT: Text for trace location creation card -->
     <string name="create_trace_location_card_button">"Create QR Code"</string>
     <!-- XTXT: Text for content description of tile image -->
-    <string name="create_trace_location_card_content_description">"Eine Person zeigt auf ein Flipchart."</string>
+    <string name="create_trace_location_card_content_description">"A person points to a flip chart."</string>
 
     <!--    Trace Location QR Code Info Screen-->
     <!-- XTXT: Text for content description of info screen image -->
-    <string name="trace_location_qr_info_content_description">"Eine Person zeigt auf ein Flipchart, zwei Personen sitzen daneben und schauen auf das Flipchart."</string>
+    <string name="trace_location_qr_info_content_description">"One person points to a flip chart, while two people are sitting adjacent and looking at the flip chart."</string>
     <!-- XHED: Headline for trace location creation card -->
-    <string name="trace_location_qr_info_headline_text">"Mehr Sicherheit für Sie und Ihre Gäste"</string>
+    <string name="trace_location_qr_info_headline_text">"Increased Safety for You and Your Guests"</string>
     <!-- XTXT: Text for subtitle of qr info screen -->
-    <string name="trace_location_qr_info_subtitle_text">"Erstellen Sie einen QR-Code, den Ihre Gäste bei ihrer Ankunft scannen können. So können sie bei Bedarf andere Gäste warnen oder von ihnen gewarnt werden."</string>
+    <string name="trace_location_qr_info_subtitle_text">"Create a QR code that your guests can scan when they arrive. This will enable them to warn other guests or be warned by them if necessary."</string>
     <!-- XTXT: Text for tracing icon of qr info screen -->
-    <string name="trace_location_qr_info_tracing_text">"Jeder Check-in wird bei der Ermittlung des Risikostatus zusätzlich berücksichtigt. Wird eine eingecheckte Person später positiv getestet, können die Gäste gewarnt werden, wenn sie sich zur gleichen Zeit oder bis zu 30 Minuten nach der positiv getesteten Person im gleichen Raum aufgehalten haben."</string>
+    <string name="trace_location_qr_info_tracing_text">"Every check-in is also taken into account when calculating the risk status. If someone who checked in to this event or place is diagnosed with coronavirus later, the guests can be notified if they were in the same room at the same time or up to 30 minutes after the diagnosed person."</string>
     <!-- XTXT: Text for qr icon of qr info screen -->
-    <string name="trace_location_qr_info_qr_code_text">"Stellen Sie den QR-Code Ihren Gästen entweder über Ihr Smartphone oder in ausgedruckter Form zur Verfügung."</string>
+    <string name="trace_location_qr_info_qr_code_text">"You can provide the QR code to your guests on your smartphone or as a printed form."</string>
     <!-- XTXT: Text for time sheet icon of qr info screen -->
-    <string name="trace_location_qr_info_time_text">"Wenn Sie dauerhaft einen QR-Code verwenden, sollten Sie diesen einmal täglich neu erstellen außerhalb der Öffnungszeiten."</string>
+    <string name="trace_location_qr_info_time_text">"If you want to use a QR code for the long term, you should generate it again each day, outside of your operating hours."</string>
     <!-- XTXT: Text for I understand button -->
-    <string name="acknowledge_button">"Enverstanden"</string>
-
+    <string name="acknowledge_button">"Next"</string>
 
     <!-- XHED: Title of the notification channel for event registration related notifications. -->
-    <string name="tracelocation_notification_channel_title">"Check-ins"</string>
+    <string name="tracelocation_notification_channel_title">"Check-Ins"</string>
     <!-- XTXT: Description of the notification channel for event registration related notifications. -->
-    <string name="tracelocation_notification_channel_description">"Benachrichtungen zu Ihren Check-ins, z.B. automatischer Check-out."</string>
+    <string name="tracelocation_notification_channel_description">"Notifications about your check-ins, such as automatic check-out."</string>
     <!-- XHED: Title of the automatic check-out notification. -->
-    <string name="tracelocation_notification_autocheckout_title">"Sie wurden automatisch ausgecheckt."</string>
+    <string name="tracelocation_notification_autocheckout_title">"You were checked out automatically."</string>
     <!-- XTXT: Description of the automatic check-out notification. -->
-    <string name="tracelocation_notification_autocheckout_description">"Bitte passen Sie Ihre Aufenthaltsdauer gegebenenfalls an."</string>
+    <string name="tracelocation_notification_autocheckout_description">"Please adjust the length of your stay if needed."</string>
 
     <!-- ####################################
        Event Organiser Trace Locations List
@@ -198,13 +198,17 @@
 
     <!-- XTXT: Event organiser list item: duration-->
     <string name="trace_location_organizer_list_item_duration">"%1$s - %2$s"</string>
+
+    <!-- XTXT: Event organiser list item: duration same day-->
+    <string name="trace_location_organizer_list_item_duration_same_day">"%1$s 2$s - %3$s"</string>
+
     <!-- XBUT: Event organiser list item: checkin button -->
     <string name="trace_location_organizer_list_item_action_checkin">"Check In"</string>
 
     <!-- XTXT: Event organizer detail qr-code: duration with date -->
-    <string name="trace_location_organizer_detail_item_duration">"%1$s, %2$s - %3$s Uhr"</string>
+    <string name="trace_location_organizer_detail_item_duration">"%1$s, %2$s - %3$s"</string>
     <!-- XTXT: Event organizer detail qr-code: duration with multiple date -->
-    <string name="trace_location_organizer_detail_item_duration_multiple_days">"%1$s, %2$s - %3$s, %4$s Uhr"</string>
+    <string name="trace_location_organizer_detail_item_duration_multiple_days">"%1$s, %2$s - %3$s, %4$s"</string>
 
     <!-- XBUT: Event organiser list item: menu: information button  -->
     <string name="trace_location_organizer_list_item_menu_duplicate_btn">"Duplicate"</string>
@@ -213,34 +217,35 @@
     <!-- XBUT: Event organiser list item: menu: clear button  -->
     <string name="trace_location_organizer_list_item_menu_clear_btn">"Delete"</string>
 
-
     <!-- Trace Location Checkin Confirmation -->
     <!-- XHED: Checkin Confirm: title for screen -->
-    <string name="confirm_checkin_title_text">"Einchecken für:"</string>
+    <string name="confirm_checkin_title_text">"Check in for:"</string>
     <!-- XTXT: Checkin Confirm: text for event is in future info card -->
-    <string name="confirm_checkin_event_in_future_card_text">"Das Event beginnt erst am %1$s um %2$s Uhr. Wollen Sie jetzt bereits einchecken?"</string>
+    <string name="confirm_checkin_event_in_future_card_text">"This event doesn’t start until %2$s on %1$s. Do you want to check in already?"</string>
     <!-- XTXT: Checkin Confirm: text for event is in past info card -->
-    <string name="confirm_checkin_event_in_past_card_text">"Das Event ist beendet. Wollen Sie nachträglich einchecken?"</string>
+    <string name="confirm_checkin_event_in_past_card_text">"This event is already over. Do you want to check in retroactively?"</string>
     <!-- XTXT: Checkin Confirm: label for save to contact diary toggle -->
-    <string name="confirm_checkin_settings_card_checkout_toggle_label">"Nach dem Auschecken in mein Kontakt-Tagebuch eintragen?"</string>
+    <string name="confirm_checkin_settings_card_checkout_toggle_label">"Record in my contact journal after check-out?"</string>
     <!-- XTXT: Checkin Confirm: label for checkout delay selection -->
-    <string name="confirm_checkin_settings_card_checkout_time_label">"Automatisch auschecken nach"</string>
+    <string name="confirm_checkin_settings_card_checkout_time_label">"Check out automatically after"</string>
     <!-- XTXT: Checkin Confirm: time length label for checkout delay selection -->
-    <string name="confirm_checkin_settings_card_checkout_time_tag">"Std"</string>
+    <string name="confirm_checkin_settings_card_checkout_time_tag">"hrs"</string>
     <!-- XBUT: Checkin Confirm: Checkin Button -->
-    <string name="confirm_checkin_confirm_button_text">"Einchecken"</string>
+    <string name="confirm_checkin_confirm_button_text">"Check In"</string>
 
     <!-- Trace Location Checkin Editing -->
     <!-- XHED: Checkin Edit: title for screen -->
-    <string name="edit_checkin_title_text">"Aufenthaltsdauer anpassen für:"</string>
+    <string name="edit_checkin_title_text">"Change length of stay for:"</string>
     <!-- XTXT: Checkin Edit: label for checkout time -->
-    <string name="edit_checkin_edit_card_checkout_time_label">"Ausgecheckt"</string>
+    <string name="edit_checkin_edit_card_checkout_time_label">"Checked Out"</string>
     <!-- XTXT: Checkin Edit: label for checkin time -->
-    <string name="edit_checkin_edit_card_checkin_time_label">"Eingecheckt"</string>
+    <string name="edit_checkin_edit_card_checkin_time_label">"Checked In"</string>
     <!-- XTXT: Checkin Edit: hint for unchanged contact diary checkin duration -->
-    <string name="edit_checkin_duration_edit_hint_card_text">"Die Aufenthaltsdauer wird nicht automatisch in Ihrem Kontakt-Tagebuch angepasst."</string>
+    <string name="edit_checkin_duration_edit_hint_card_text">"The length of stay will not be adjusted automatically in your contact journal."</string>
+    <!-- XTXT: Checkin Edit: warning if user input is incorrect -->
+    <string name="edit_checkin_wrong_input_warning_text">"You can remain checked in for up to 24 hours. The check-out time must be later than the check-in time."</string>
     <!-- XBUT: Checkin Edit: Save Button -->
-    <string name="edit_checkin_confirm_button_text">"Speichern"</string>
+    <string name="edit_checkin_confirm_button_text">"Save"</string>
 
     <!--  Organizer Flow: Event Detail Screen-->
     <!-- XTXT: Organizer Flow : Accessibility description for qr-code illustration -->
diff --git a/Corona-Warn-App/src/main/res/values/release_info_strings.xml b/Corona-Warn-App/src/main/res/values/release_info_strings.xml
index d0c5629983daf84179471605bf87da8c83298fa5..f480f402b927499db999d597b89dd70293fdc893 100644
--- a/Corona-Warn-App/src/main/res/values/release_info_strings.xml
+++ b/Corona-Warn-App/src/main/res/values/release_info_strings.xml
@@ -7,7 +7,7 @@
     <!-- XHED: Title for the release info screen -->
     <string name="release_info_header">"New Features"</string>
     <!-- XHED: Version title for the release info screen -->
-    <string name="release_info_version_title">Release %1$s</string>
+    <string name="release_info_version_title">"Release %1$s"</string>
     <!-- XTXT: Description for the release info screen -->
     <string name="release_info_version_body">"Along with bug fixes, this update also includes new and enhanced features."</string>
     <!-- XBUT: Continue button for the release info screen -->
@@ -22,7 +22,7 @@
 
     <!-- XTXT: Text bodies for the release info screen bullet points -->
     <string-array name="new_release_body">
-        <item>"The CWA now enables you to check in to events and places. Event organizers and store owners can use the app to create a QR code. Guests can then scan this QR code when they arrive to register their presence. The app can also create a journal entry upon request. If someone who checked in to this event or place is diagnosed with coronavirus later, everyone who was checked in at the same time is notified automatically."</item>
+        <item>"The CWA now enables you to check in to events and places. Event organizers and store owners can use the app to create a QR code. Guests can then scan this QR code when they arrive to register their presence. The app can also create a journal entry upon request. If someone who checked in to this event or place is diagnosed with coronavirus later, other people who were checked in at the same time can be warned automatically."</item>
     </string-array>
 
     <!-- XTXT: Text labels that will be converted to Links -->
@@ -35,4 +35,4 @@
         <item/>
     </string-array>
 
-</resources>
+</resources>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml
index 0d6a785821099345fbd57d5192707d9d26b2a4f6..530da0471d5301ce113b1209ffc9c87584c6f478 100644
--- a/Corona-Warn-App/src/main/res/values/strings.xml
+++ b/Corona-Warn-App/src/main/res/values/strings.xml
@@ -1,5 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" tools:ignore="MissingTranslation">
+
+    <!-- ####################################
+                     Non translatable
+    ###################################### -->
+
+    <!-- XTXT: Path to the full blown legal html, currently not translated -->
+    <string name="information_technical_html_path" translatable="false">"technical.html"</string>
+
     <!-- ####################################
                      Generics
     ###################################### -->
@@ -31,14 +39,10 @@
     <!-- ####################################
                Notification
     ###################################### -->
-    <!-- NOTR -->
-    <string name="notification_channel_id"><xliff:g id="notification_channel_id">"de.rki.coronawarnapp.notification.exposureNotificationChannelId"</xliff:g></string>
-    <!-- NOTR -->
-    <string name="notification_id"><xliff:g id="notification_id">"1"</xliff:g></string>
     <!-- XHED: Title of the notification channel for general CWA notifications (e.g. risk change) -->
-    <string name="general_notification_channel_title">"Allgemein"</string>
+    <string name="general_notification_channel_title">"General"</string>
     <!-- XTXT: Description of the notification channel for general CWA notifications (e.g. risk change) -->
-    <string name="general_notification_channel_description">"Erinnerungen, Hinweise und allgemeine Benachrichtigungen, z.B. zu Ihrem Risikostatus."</string>
+    <string name="general_notification_channel_description">"Reminders, notes, and general notifications – about your risk status, for example."</string>
     <!-- XHED: Notification title -->
     <string name="notification_headline">"Corona-Warn-App"</string>
     <!-- XTXT: Notification body -->
@@ -307,12 +311,12 @@
     <!-- XHED: risk details - infection period logged headling, below behaviors -->
     <string name="risk_details_subtitle_period_logged">"This period is included in the calculation."</string>
     <!-- XHED: risk details - infection period logged information body, below behaviors -->
-<!--    Dialog part 1-->
+    <!--    Dialog part 1-->
     <string name="risk_details_information_body_period_logged">"Your risk of infection can be calculated only for periods during which exposure logging was active. The logging feature should therefore remain active permanently. Exposure logging covers the last 14 days."</string>
     <!-- XTXT: risk details - infection period logged information body, under 14 days -->
-    <string name="risk_details_information_body_period_logged_assessment_under_14_days">"The Corona-Warn-App was installed %s ago. Your risk of infection is calculated for the periods during which exposure logging was active. If you have encountered other people and exposure logging was active, your risk of infection is calculated."</string>
+    <string name="risk_details_information_body_period_logged_assessment_under_14_days">"The Corona-Warn-App was installed %s days ago. Your risk of infection is calculated for the periods during which exposure logging was active. If you have encountered other people and exposure logging was active, your risk of infection is calculated."</string>
     <!-- XTXT: risk details - infection period logged information body, over 14 days -->
-    <string name="risk_details_information_body_period_logged_assessment_over_14_days">"If exposure logging was active in times during which you encountered other people, your risk of infection can be calculated for this period."</string>
+    <string name="risk_details_information_body_period_logged_assessment_over_14_days">"If exposure logging was active at times during which you encountered other people, your risk of infection can be calculated for this period."</string>
     <!-- XHED: risk details - infection period logged information body, below behaviors -->        <!-- XTXT: risk details - infection period logged information body, under 14 days -->
     <string name="risk_details_information_body_period_logged_assessment">"The app automatically deletes older logs, as these are no longer relevant for infection prevention."</string>
     <!-- XTXT: risk details - infection period days logged/14 -->
@@ -327,6 +331,8 @@
     <string name="risk_details_information_body_low_risk">"You have a low risk of infection because no exposure to people later diagnosed with coronavirus was logged, or because your encounters were only for a short time and at a greater distance."</string>
     <!-- YTXT: risk details - low risk explanation text with encounter with low risk -->
     <string name="risk_details_information_body_low_risk_with_encounter">"The risk of infection is calculated locally on your smartphone, using exposure logging data. The calculation also takes into account distance and duration of any exposure to persons diagnosed with coronavirus, as well as their potential infectiousness. Your risk of infection cannot be seen by or passed on to anyone else."</string>
+    <!-- XLNK: FAQ URL pointing to the faq page in german. Need to use the URL for english for all other languages-->
+    <string name="risk_details_explanation_faq_link">"https://www.coronawarn.app/en/faq/#encounter_but_green"</string>
     <!-- YTXT: risk details - increased risk explanation text with variable date since last contact -->
     <string name="risk_details_information_body_increased_risk_date">"You have an increased risk of infection because you were exposed over a longer period of time and at close proximity to at least one person diagnosed with coronavirus."</string>
     <!-- YTXT: risk details - increased risk explanation text with variable for day(s) since last contact -->
@@ -353,7 +359,6 @@
     <string name="risk_details_explanation_dialog_title">"Information about exposure logging functionality"</string>
     <!-- YTXT: one time risk explanation dialog - pointing to the faq page for more information-->
     <string name="risk_details_explanation_dialog_faq_body">"For further information, please see our FAQ page."</string>
-
     <!-- XHED: risk details - deadman notification title -->
     <string name="risk_details_deadman_notification_title">"Your Risk Status"</string>
     <!-- YTXT: risk details - deadman notification text -->
@@ -582,8 +587,8 @@
 
 
     <!-- ####################################
-                 Onboarding sixteen include
-       ###################################### -->
+             Onboarding sixteen include
+   ###################################### -->
 
     <!-- XACT: onboarding(sixteen) title -->
     <string name="sixteen_title_text">"Age 16 Warning"</string>
@@ -644,8 +649,6 @@
     <string name="settings_tracing_status_connection_headline">"Open Internet connection"</string>
     <!-- XTXT: settings(tracing) - explains user what to do on card if connection is disabled -->
     <string name="settings_tracing_status_connection_body">"Exposure logging requires an Internet connection to calculate your risk of infection. Please turn on Wi-Fi or mobile data in your device settings."</string>
-    <!-- XLNK: FAQ URL pointing to the faq page in german. Need to use the URL for english for all other languages-->
-    <string name="risk_details_explanation_faq_link">"https://www.coronawarn.app/en/faq/#encounter_but_green"</string>
     <!-- XBUT: settings(tracing) - go to operating system settings button on card -->
     <string name="settings_tracing_status_connection_button">"Open Device Settings"</string>
     <!-- XTXT: settings(tracing) - explains the circle progress indicator to the right with the current value -->
@@ -807,8 +810,6 @@
     <string name="information_technical_title">"Legal Notices"</string>
     <!-- XACT: describes illustration -->
     <string name="information_technical_illustration_description">"A hand holds a smartphone displaying a large body of text on the screen. Next to the text is a balance scale that symbolizes legal notices."</string>
-    <!-- XTXT: Path to the full blown legal html, currently not translated -->
-    <string name="information_technical_html_path" translatable="false">"technical.html"</string>
     <!-- XHED: Page title for legal information page, also menu item / button text -->
     <string name="information_legal_title">"Imprint"</string>
     <!-- XHED: Headline for legal information page, publisher section -->
@@ -834,9 +835,8 @@
     <!-- XACT: describes illustration -->
     <string name="information_legal_illustration_description">"A hand holds a smartphone displaying a large body of text on the screen. Next to the text is a section symbol representing the imprint."</string>
 
-
     <!-- ####################################
-           App Information - Bug Reporting
+               App Information - Bug Reporting
     ###################################### -->
 
     <!-- XHED: Headline for debug log screen -->
@@ -1131,6 +1131,7 @@
     <!-- YTXT: Description for illustration in submission onboarding-->
     <string name="submission_intro_illustration_description">"An encrypted positive test diagnosis is transmitted to the system, which will now warn other users."</string>
 
+
     <!-- Dispatcher -->
     <!-- XHED: Page headline for dispatcher menu  -->
     <string name="submission_dispatcher_headline">"Retrieve Test Result"</string>
@@ -1149,7 +1150,6 @@
     <!-- YTXT: Body text for TAN code dispatcher option -->
     <string name="submission_dispatcher_tan_code_card_text">"Do you have a TAN? Tap here to enter your TAN so you can warn others. "</string>
     <!-- YTXT: Dispatcher text for TELE-TAN option -->
-    <!-- YTXT: Dispatcher text for TELE-TAN option -->
     <string name="submission_dispatcher_card_tan_tele">"No TAN yet?"</string>
     <!-- YTXT: Body text for TELE_TAN dispatcher option -->
     <string name="submission_dispatcher_tan_tele_card_text">"Call us and get a TAN."</string>
@@ -1352,12 +1352,12 @@
     <string name="submission_status_card_body_positive">"You have been diagnosed positive for SARS-CoV-2."</string>
     <!-- YTXT: Body text for submission status: negative -->
     <string name="submission_status_card_body_negative">"You have been diagnosed negative for SARS-CoV-2."</string>
+    <!-- YTXT: Body text for submission status fetch failed -->
+    <string name="submission_status_card_body_failed">"Your test is more than 21 days old and is therefore no longer relevant. Please delete the test. You can then add another."</string>
     <!-- YTXT: Body text for submission status fetch ready -->
     <string name="submission_status_card_body_ready">"If you have tested positive for coronavirus, you can warn others."</string>
     <!-- YTXT: Button text for submission status fetch ready -->
     <string name="submission_status_card_retrieve_test_result">"Retrieve Test Result"</string>
-    <!-- YTXT: Body text for submission status fetch failed -->
-    <string name="submission_status_card_body_failed">"Your test is more than 21 days old and is therefore no longer relevant. Please delete the test. You can then add another."</string>
     <!-- XBUT: submission status card unregistered button -->
     <string name="submission_status_card_button_unregistered">"Next Steps"</string>
     <!-- XBUT: submission status card show results button -->
@@ -1482,8 +1482,8 @@
     <string name="submission_your_consent_agreement_details">"Detailed Information on Data Processing and Your Consent"</string>
 
     <!-- ####################################
-        Statistics
-   ###################################### -->
+         Statistics
+    ###################################### -->
 
     <!-- Incidence statistics card -->
     <!-- XHED: Title for incident statistics card -->
@@ -1574,7 +1574,7 @@
     <string name="statistics_explanation_trend_stable_title">"Trend: Steady"</string>
     <!-- XHED: Explanation screen trend description -->
     <string name="statistics_explanation_trend_description">"The assessment of the trend for warnings by app users changes depending on current infection levels, which is why this trend is always displayed as neutral."</string>
-    <!-- XTXT: Explains user about statistics: URL, has to be "translated" into english (relevant for all languages except german)0 - https://www.coronawarn.app/en/faq/#further_details -->
+    <!-- XTXT: Explains user about statistics: URL, has to be "translated" into english (relevant for all languages except german) - https://www.coronawarn.app/en/faq/#further_details -->
     <string name="statistics_explanation_faq_url">"https://www.coronawarn.app/en/faq/#further_details"</string>
     <!-- XACT: Statistics explanation illustration description -->
     <string name="statistics_explanation_illustration_description">"Abstract picture of a smartphone with four placeholders for information"</string>
@@ -1584,7 +1584,6 @@
     <!-- XTXT: Statistics Card Navigation Announcement -->
     <string name="accessibility_statistics_card_navigation_information">"Swipe horizontally between the tiles to display more statistics"</string>
 
-
     <!-- ####################################
           Button Tooltips for Accessibility
     ###################################### -->
@@ -1824,13 +1823,13 @@
     <string name="statistics_reproduction_title">"Currently"</string>
     <!-- XTXT: Caption for statistics reproduction card -->
     <string name="statistics_reproduction_average">"average infections by each infected person"</string>
-
     <!-- XTXT: Statistics trend increasing (Accessibilty) -->
     <string name="statistics_trend_increasing">"Trend: Upwards"</string>
     <!-- XTXT: Statistics trend decreasing (Accessibilty) -->
     <string name="statistics_trend_decreasing">"Trend: Downwards"</string>
     <!-- XTXT: Statistics trend stable (Accessibilty) -->
     <string name="statistics_trend_stable">"Trend: Steady"</string>
+
     <!-- XHED: Title for BottomNav main screen title -->
     <string name="bottom_nav_home_title">"Start Screen"</string>
     <!-- XHED: Title for BottomNav diary screen title -->
@@ -1987,17 +1986,17 @@
     <!-- XACT: Button/Dialog label to consent-->
     <string name="trace_location_onboarding_body_confirm">"Accept"</string>
     <!--  XHED: Trace location check-ins camera permission card title-->
-    <string name="trace_location_attendee_camera_card_title">Zugriff auf Kamera erlauben</string>
+    <string name="trace_location_attendee_camera_card_title">"Allow Access to Camera"</string>
     <!--  XTXT: Trace location check-ins camera permission card susbtitle-->
-    <string name="trace_location_attendee_camera_card_subtitle">Um die Kamera für das Scannen des QR-Codes zu nutzen, müssen Sie die Verwendung der Kamera in den Geräte-Einstellungen zur App zulassen.</string>
+    <string name="trace_location_attendee_camera_card_subtitle">"To use your smartphone camera to scan QR codes, you have to allow access to the camera in the device settings for the app."</string>
     <!--  XBUT: Trace location check-ins camera permission card button-->
-    <string name="trace_location_attendee_camera_card_button">Einstellungen öffnen</string>
+    <string name="trace_location_attendee_camera_card_button">"Open Settings"</string>
     <!--  YMSG: Trace location onboarding image description-->
-    <string name="trace_location_onboarding_content_description">Drei Personen an einem Stehtisch, zwei von ihnen schauen auf ihr Smartphone.</string>
+    <string name="trace_location_onboarding_content_description">"Three persons are standing at a high table, two of them are looking at their smartphones."</string>
     <!-- XMIT: Trace location poster print -->
     <string name="trace_location_organiser_poster_print">"Print"</string>
     <!-- XMIT: Trace location poster share -->
     <string name="trace_location_organiser_poster_share">"Share"</string>
     <!-- XHED: Trace location poster title -->
-    <string name="trace_location_organiser_poster_title">"Print version"</string>
-</resources>
+    <string name="trace_location_organiser_poster_title">"Print Version"</string>
+</resources>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/edit/ContactDiaryEditLocationsViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/edit/ContactDiaryEditLocationsViewModelTest.kt
index e8ee5c3275b31cd946d5dfae4556b7d023127e3a..6706173c4975ad8508aa49a7fe7f77c3c0aadc6d 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/edit/ContactDiaryEditLocationsViewModelTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/edit/ContactDiaryEditLocationsViewModelTest.kt
@@ -3,6 +3,7 @@ package de.rki.coronawarnapp.contactdiary.ui.edit
 import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocation
 import de.rki.coronawarnapp.contactdiary.storage.entity.toContactDiaryLocationEntity
 import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
+import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocationId
 import io.kotest.matchers.shouldBe
 import io.mockk.MockKAnnotations
 import io.mockk.Runs
@@ -30,7 +31,7 @@ class ContactDiaryEditLocationsViewModelTest {
         override val phoneNumber: String? = null
         override val emailAddress: String? = null
         override val stableId = 1L
-        override val traceLocationID: String? = null
+        override val traceLocationID: TraceLocationId? = null
     }
     private val locationList = listOf(location)
 
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModelTest.kt
index 7c0754dd1a75fa657fe35e47ee9156b1cc95ef31..b50da8d26d837814fd363f8957e9e362ff9cb0e9 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModelTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModelTest.kt
@@ -35,6 +35,7 @@ import io.mockk.mockk
 import io.mockk.runs
 import io.mockk.verify
 import kotlinx.coroutines.flow.flowOf
+import okio.ByteString.Companion.decodeBase64
 import org.joda.time.DateTimeZone
 import org.joda.time.Instant
 import org.joda.time.LocalDate
@@ -69,7 +70,7 @@ open class ContactDiaryOverviewViewModelTest {
         every { contactDiaryRepository.personEncounters } returns flowOf(emptyList())
         every { riskLevelStorage.ewDayRiskStates } returns flowOf(emptyList())
         every { riskLevelStorage.traceLocationCheckInRiskStates } returns flowOf(emptyList())
-        every { checkInRepository.allCheckIns } returns flowOf(emptyList())
+        every { checkInRepository.checkInsWithinRetention } returns flowOf(emptyList())
 
         mockStringsForContactDiaryExporterTests(context)
         every { timeStamper.nowUTC } returns Instant.ofEpochMilli(dateMillis)
@@ -83,13 +84,13 @@ open class ContactDiaryOverviewViewModelTest {
     private val locationEventLowRisk = DefaultContactDiaryLocation(
         locationId = 456,
         locationName = "Jahrestreffen der deutschen SAP Anwendergruppe",
-        traceLocationID = "12ab-34cd-56ef-78gh-456"
+        traceLocationID = "12ab-34cd-56ef-78gh-456".decodeBase64()
     )
 
     private val locationEventHighRisk = DefaultContactDiaryLocation(
         locationId = 457,
         locationName = "Kiosk",
-        traceLocationID = "12ab-34cd-56ef-78gh-457"
+        traceLocationID = "12ab-34cd-56ef-78gh-457".decodeBase64()
     )
 
     private val locationEventLowRiskVisit = DefaultContactDiaryLocationVisit(
@@ -361,7 +362,7 @@ open class ContactDiaryOverviewViewModelTest {
         every { riskLevelStorage.ewDayRiskStates } returns flowOf(listOf(aggregatedRiskPerDateResultLowRisk))
         every { riskLevelStorage.traceLocationCheckInRiskStates } returns flowOf(listOf(traceLocationCheckInRiskHigh))
         every { contactDiaryRepository.locationVisits } returns flowOf(listOf(locationEventHighRiskVisit))
-        every { checkInRepository.allCheckIns } returns flowOf(listOf(checkInHigh))
+        every { checkInRepository.checkInsWithinRetention } returns flowOf(listOf(checkInHigh))
 
         var item = createInstance().listItems.getOrAwaitValue().first {
             it is DayOverviewItem && it.date == date
@@ -384,7 +385,7 @@ open class ContactDiaryOverviewViewModelTest {
         )
         every { riskLevelStorage.traceLocationCheckInRiskStates } returns flowOf(listOf(traceLocationCheckInRiskLow))
         every { contactDiaryRepository.locationVisits } returns flowOf(listOf(locationEventLowRiskVisit))
-        every { checkInRepository.allCheckIns } returns flowOf(listOf(checkInLow))
+        every { checkInRepository.checkInsWithinRetention } returns flowOf(listOf(checkInLow))
 
         item = createInstance().listItems.getOrAwaitValue().first {
             it is DayOverviewItem && it.date == date
@@ -414,7 +415,7 @@ open class ContactDiaryOverviewViewModelTest {
     fun `low risk event by attending event with low risk`() {
         every { contactDiaryRepository.locationVisits } returns flowOf(listOf(locationEventLowRiskVisit))
         every { riskLevelStorage.traceLocationCheckInRiskStates } returns flowOf(listOf(traceLocationCheckInRiskLow))
-        every { checkInRepository.allCheckIns } returns flowOf(listOf(checkInLow))
+        every { checkInRepository.checkInsWithinRetention } returns flowOf(listOf(checkInLow))
 
         val item = createInstance().listItems.getOrAwaitValue().first {
             it is DayOverviewItem && it.date == date
@@ -436,7 +437,7 @@ open class ContactDiaryOverviewViewModelTest {
     fun `high risk event by attending event with high risk`() {
         every { contactDiaryRepository.locationVisits } returns flowOf(listOf(locationEventHighRiskVisit))
         every { riskLevelStorage.traceLocationCheckInRiskStates } returns flowOf(listOf(traceLocationCheckInRiskHigh))
-        every { checkInRepository.allCheckIns } returns flowOf(listOf(checkInHigh))
+        every { checkInRepository.checkInsWithinRetention } returns flowOf(listOf(checkInHigh))
 
         val item = createInstance().listItems.getOrAwaitValue().first {
             it is DayOverviewItem && it.date == date
@@ -469,7 +470,7 @@ open class ContactDiaryOverviewViewModelTest {
             )
         )
 
-        every { checkInRepository.allCheckIns } returns flowOf(listOf(checkInHigh, checkInLow))
+        every { checkInRepository.checkInsWithinRetention } returns flowOf(listOf(checkInHigh, checkInLow))
 
         val item = createInstance().listItems.getOrAwaitValue().first {
             it is DayOverviewItem && it.date == date
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/attendee/confirm/ConfirmCheckInViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/attendee/confirm/ConfirmCheckInViewModelTest.kt
index aee24dd7643b2551114c25038649cc427269aad3..f5b58f654c33d15067a76e6d8740474edce34cd7 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/attendee/confirm/ConfirmCheckInViewModelTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/attendee/confirm/ConfirmCheckInViewModelTest.kt
@@ -14,6 +14,7 @@ import io.mockk.coEvery
 import io.mockk.every
 import io.mockk.impl.annotations.MockK
 import okio.ByteString.Companion.decodeBase64
+import org.joda.time.Duration
 import org.joda.time.Instant
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
@@ -29,8 +30,6 @@ class ConfirmCheckInViewModelTest : BaseTest() {
     @MockK lateinit var checkInRepository: CheckInRepository
     @MockK lateinit var timeStamper: TimeStamper
 
-    private lateinit var viewModel: ConfirmCheckInViewModel
-
     private val traceLocation = TraceLocation(
         id = 1,
         type = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_OTHER,
@@ -51,23 +50,35 @@ class ConfirmCheckInViewModelTest : BaseTest() {
         coEvery { checkInRepository.addCheckIn(any()) } returns 1L
         every { verifiedTraceLocation.traceLocation } returns traceLocation
         every { timeStamper.nowUTC } returns Instant.parse("2021-03-04T10:30:00Z")
+    }
+
+    private fun createInstance() = ConfirmCheckInViewModel(
+        verifiedTraceLocation = verifiedTraceLocation,
+        checkInRepository = checkInRepository,
+        timeStamper = timeStamper
+    )
 
-        viewModel = ConfirmCheckInViewModel(
-            verifiedTraceLocation = verifiedTraceLocation,
-            checkInRepository = checkInRepository,
-            timeStamper = timeStamper
-        )
+    @Test
+    fun onClose() = with(createInstance()) {
+        onClose()
+        events.getOrAwaitValue() shouldBe ConfirmCheckInNavigation.BackNavigation
+    }
+
+    @Test
+    fun onConfirmEvent() = with(createInstance()) {
+        onConfirmTraceLocation()
+        events.getOrAwaitValue() shouldBe ConfirmCheckInNavigation.ConfirmNavigation
     }
 
     @Test
-    fun onClose() {
-        viewModel.onClose()
-        viewModel.events.getOrAwaitValue() shouldBe ConfirmCheckInNavigation.BackNavigation
+    fun `confirm button should be disabled when autoCheckOutLength is 0`() = with(createInstance()) {
+        durationUpdated(Duration.standardMinutes(0))
+        uiState.getOrAwaitValue().confirmButtonEnabled shouldBe false
     }
 
     @Test
-    fun onConfirmEvent() {
-        viewModel.onConfirmTraceLocation()
-        viewModel.events.getOrAwaitValue() shouldBe ConfirmCheckInNavigation.ConfirmNavigation
+    fun `confirm button should be enabled when autoCheckOutLength is greater than 0`() = with(createInstance()) {
+        durationUpdated(Duration.standardMinutes(15))
+        uiState.getOrAwaitValue().confirmButtonEnabled shouldBe true
     }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepositoryTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepositoryTest.kt
index 0298f03aec66f49a628fb48937b3f1106e802387..23ea1802a9cfc3827af343301079606c0e160f46 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepositoryTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepositoryTest.kt
@@ -3,6 +3,7 @@ package de.rki.coronawarnapp.eventregistration.checkins
 import de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase
 import de.rki.coronawarnapp.eventregistration.storage.dao.CheckInDao
 import de.rki.coronawarnapp.eventregistration.storage.entity.TraceLocationCheckInEntity
+import de.rki.coronawarnapp.util.TimeStamper
 import io.kotest.assertions.throwables.shouldThrow
 import io.kotest.matchers.shouldBe
 import io.mockk.MockKAnnotations
@@ -10,11 +11,13 @@ import io.mockk.coEvery
 import io.mockk.coVerify
 import io.mockk.every
 import io.mockk.impl.annotations.MockK
+import io.mockk.impl.annotations.RelaxedMockK
 import io.mockk.mockk
 import io.mockk.slot
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runBlockingTest
 import okio.ByteString.Companion.encode
 import org.joda.time.Instant
@@ -27,6 +30,7 @@ class CheckInRepositoryTest : BaseTest() {
     @MockK lateinit var factory: TraceLocationDatabase.Factory
     @MockK lateinit var database: TraceLocationDatabase
     @MockK lateinit var checkInDao: CheckInDao
+    @RelaxedMockK lateinit var timeStamper: TimeStamper
     private val allEntriesFlow = MutableStateFlow(emptyList<TraceLocationCheckInEntity>())
 
     @BeforeEach
@@ -40,7 +44,7 @@ class CheckInRepositoryTest : BaseTest() {
         }
     }
 
-    private fun createInstance(scope: CoroutineScope) = CheckInRepository(factory)
+    private fun createInstance(scope: CoroutineScope) = CheckInRepository(factory, timeStamper)
 
     @Test
     fun `new entities should have ID 0`() = runBlockingTest {
@@ -88,7 +92,8 @@ class CheckInRepositoryTest : BaseTest() {
                     checkInStart = time,
                     checkInEnd = end,
                     completed = false,
-                    createJournalEntry = false
+                    createJournalEntry = false,
+                    isSubmitted = true
                 )
             )
             coVerify {
@@ -108,7 +113,8 @@ class CheckInRepositoryTest : BaseTest() {
                         checkInStart = time,
                         checkInEnd = end,
                         completed = false,
-                        createJournalEntry = false
+                        createJournalEntry = false,
+                        isSubmitted = true,
                     )
                 )
             }
@@ -152,7 +158,8 @@ class CheckInRepositoryTest : BaseTest() {
                 checkInStart = start,
                 checkInEnd = end,
                 completed = false,
-                createJournalEntry = false
+                createJournalEntry = false,
+                isSubmitted = true,
             )
         )
         runBlockingTest {
@@ -172,9 +179,51 @@ class CheckInRepositoryTest : BaseTest() {
                     checkInStart = start,
                     checkInEnd = end,
                     completed = false,
-                    createJournalEntry = false
+                    createJournalEntry = false,
+                    isSubmitted = true,
                 )
             )
         }
     }
+
+    @Test
+    fun `checkInsWithinRetention() should filter out stale check-ins`() = runBlockingTest {
+
+        // Now = Jan 16th 2020, 00:00
+        // CheckIns should be kept for 15 days, so every check-in with an end date before
+        // Jan 1st 2020, 00:00 should get deleted
+        every { timeStamper.nowUTC } returns Instant.parse("2020-01-16T00:00:00.000Z")
+
+        val checkInWithinRetention = createCheckIn(Instant.parse("2020-01-01T00:00:00.000Z"))
+
+        // should be filtered out
+        val staleCheckIn = createCheckIn(Instant.parse("2019-12-31T23:59:59.000Z"))
+
+        every { checkInDao.allEntries() } returns flowOf(
+            listOf(
+                staleCheckIn.toEntity(),
+                checkInWithinRetention.toEntity()
+            )
+        )
+
+        createInstance(scope = this).checkInsWithinRetention.first() shouldBe
+            listOf(checkInWithinRetention)
+    }
+
+    private fun createCheckIn(checkOutDate: Instant) = CheckIn(
+        traceLocationId = "traceLocationId1".encode(),
+        version = 1,
+        type = 1,
+        description = "",
+        address = "",
+        traceLocationStart = null,
+        traceLocationEnd = null,
+        defaultCheckInLengthInMinutes = 30,
+        cryptographicSeed = "cryptographicSeed".encode(),
+        cnPublicKey = "cnPublicKey",
+        checkInStart = Instant.parse("1970-01-01T00:00:00.000Z"),
+        checkInEnd = checkOutDate,
+        completed = true,
+        createJournalEntry = true
+    )
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRetentionTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRetentionTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c95a3d181f9774bf3f772bd239d6122dce82635b
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRetentionTest.kt
@@ -0,0 +1,44 @@
+package de.rki.coronawarnapp.eventregistration.checkins
+
+import io.kotest.matchers.shouldBe
+import okio.ByteString.Companion.encode
+import org.joda.time.Instant
+import org.junit.jupiter.api.Test
+
+internal class CheckInRetentionTest {
+
+    @Test
+    fun `isWithinRetention() and isOutOfRetention() should return correct result`() {
+
+        // Now = Jan 16th 2020, 00:00
+        // CheckIns should be kept for 15 days, so every check-in with an end date before
+        // Jan 1st 2020 is out of retention
+        val now = Instant.parse("2020-01-16T00:00:00.000Z")
+
+        val checkInWithinRetention = createCheckIn(Instant.parse("2020-01-01T00:00:00.000Z"))
+        val checkInOutOfRetention = createCheckIn(Instant.parse("2019-12-31T23:59:59.000Z"))
+
+        checkInWithinRetention.isWithinRetention(now) shouldBe true
+        checkInWithinRetention.isOutOfRetention(now) shouldBe false
+
+        checkInOutOfRetention.isWithinRetention(now) shouldBe false
+        checkInOutOfRetention.isOutOfRetention(now) shouldBe true
+    }
+
+    private fun createCheckIn(checkOutDate: Instant) = CheckIn(
+        traceLocationId = "traceLocationId1".encode(),
+        version = 1,
+        type = 1,
+        description = "",
+        address = "",
+        traceLocationStart = null,
+        traceLocationEnd = null,
+        defaultCheckInLengthInMinutes = 30,
+        cryptographicSeed = "cryptographicSeed".encode(),
+        cnPublicKey = "cnPublicKey",
+        checkInStart = Instant.parse("1970-01-01T00:00:00.000Z"),
+        checkInEnd = checkOutDate,
+        completed = true,
+        createJournalEntry = true
+    )
+}
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/AutoCheckoutHelperTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/AutoCheckoutHelperTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c0690025cf2d7d8acc53403175cfef1b61f830c3
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/AutoCheckoutHelperTest.kt
@@ -0,0 +1,46 @@
+package de.rki.coronawarnapp.eventregistration.checkins.qrcode
+
+import io.kotest.matchers.shouldBe
+import org.junit.jupiter.params.ParameterizedTest
+import org.junit.jupiter.params.provider.MethodSource
+
+internal class AutoCheckoutHelperTest {
+
+    @ParameterizedTest
+    @MethodSource("provideArguments")
+    fun `roundToNearest15Minutes() should round correctly`(testCase: TestCase) = with(testCase) {
+        roundToNearest15Minutes(minutesToRound) shouldBe expectedRoundingResult
+    }
+
+    companion object {
+        @Suppress("unused")
+        @JvmStatic
+        fun provideArguments() = listOf(
+            TestCase(
+                minutesToRound = 0,
+                expectedRoundingResult = 0
+            ),
+            TestCase(
+                minutesToRound = 7,
+                expectedRoundingResult = 0
+            ),
+            TestCase(
+                minutesToRound = 8,
+                expectedRoundingResult = 15
+            ),
+            TestCase(
+                minutesToRound = 22,
+                expectedRoundingResult = 15
+            ),
+            TestCase(
+                minutesToRound = 23,
+                expectedRoundingResult = 30
+            )
+        )
+    }
+
+    data class TestCase(
+        val minutesToRound: Int,
+        val expectedRoundingResult: Int
+    )
+}
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/events/DefaultAutoCheckoutLengthTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/events/DefaultAutoCheckoutLengthTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f5d72d1ae03d53902b8a71df0964a07857b97aae
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/events/DefaultAutoCheckoutLengthTest.kt
@@ -0,0 +1,188 @@
+package de.rki.coronawarnapp.eventregistration.events
+
+import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocation
+import de.rki.coronawarnapp.eventregistration.checkins.qrcode.getDefaultAutoCheckoutLengthInMinutes
+import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass
+import io.kotest.matchers.shouldBe
+import okio.ByteString.Companion.encode
+import org.joda.time.Instant
+import org.junit.jupiter.params.ParameterizedTest
+import org.junit.jupiter.params.provider.MethodSource
+import testhelpers.BaseTest
+import java.util.concurrent.TimeUnit
+
+class DefaultAutoCheckoutLengthTest : BaseTest() {
+
+    @ParameterizedTest
+    @MethodSource("provideArguments")
+    fun `getDefaultAuthCheckoutLengthInMinutes(now) should return correct value`(
+        testCase: DefaultAutoCheckoutLengthTestCase
+    ) = with(testCase) {
+
+        createTraceLocation(this)
+            .getDefaultAutoCheckoutLengthInMinutes(now) shouldBe expectedDefaultAutoCheckoutLength
+    }
+
+    private fun createTraceLocation(testCase: DefaultAutoCheckoutLengthTestCase) = TraceLocation(
+        id = 1,
+        type = TraceLocationOuterClass.TraceLocationType.UNRECOGNIZED,
+        description = "",
+        address = "",
+        startDate = testCase.startDate,
+        endDate = testCase.endDate,
+        defaultCheckInLengthInMinutes = testCase.defaultCheckInLengthInMinutes,
+        cryptographicSeed = "seed byte array".encode(),
+        cnPublicKey = "cnPublicKey"
+    )
+
+    companion object {
+
+        // min valid length = 00:15h
+        private const val MIN_VALID_LENGTH = 15
+
+        // max valid length = 23:45h
+        private val MAX_VALID_LENGTH = (TimeUnit.HOURS.toMinutes(23) + 45).toInt()
+
+        @Suppress("unused")
+        @JvmStatic
+        fun provideArguments() = listOf(
+            DefaultAutoCheckoutLengthTestCase(
+                // now doesn't matter, as defaultCheckInLengthInMinutes is not null
+                now = Instant.parse("1970-01-01T00:00:00.000Z"),
+                defaultCheckInLengthInMinutes = 30,
+                startDate = null,
+                endDate = null,
+                expectedDefaultAutoCheckoutLength = 30,
+            ),
+            DefaultAutoCheckoutLengthTestCase(
+                // now doesn't matter here, as defaultCheckInLengthInMinutes is not null
+                now = Instant.parse("1970-01-01T00:00:00.000Z"),
+                // min valid length = 00:15h
+                defaultCheckInLengthInMinutes = 0,
+                startDate = null,
+                endDate = null,
+                expectedDefaultAutoCheckoutLength = MIN_VALID_LENGTH
+            ),
+            DefaultAutoCheckoutLengthTestCase(
+                // now doesn't matter here, as defaultCheckInLengthInMinutes is not null
+                now = Instant.parse("1970-01-01T00:00:00.000Z"),
+                // TraceLocations with CWA can actually only have 15 minute interval lengths. However, a trace location
+                // created by a third party could create arbitrary lengths.
+                // 22 min should be rounded to 15
+                defaultCheckInLengthInMinutes = 22,
+                startDate = null,
+                endDate = null,
+                expectedDefaultAutoCheckoutLength = 15
+            ),
+            DefaultAutoCheckoutLengthTestCase(
+                // now doesn't matter here, as defaultCheckInLengthInMinutes is not null
+                now = Instant.parse("1970-01-01T00:00:00.000Z"),
+                // TraceLocations with CWA can actually only have 15 minute interval lengths. However, a trace location
+                // created by a third party could create arbitrary lengths.
+                // 23 min should be rounded to 30
+                defaultCheckInLengthInMinutes = 23,
+                startDate = null,
+                endDate = null,
+                expectedDefaultAutoCheckoutLength = 30
+            ),
+            DefaultAutoCheckoutLengthTestCase(
+                // now doesn't matter here, as defaultCheckInLengthInMinutes is not null
+                now = Instant.parse("1970-01-01T00:00:00.000Z"),
+                // max valid length = 23:45h
+                defaultCheckInLengthInMinutes = MAX_VALID_LENGTH,
+                startDate = null,
+                endDate = null,
+                expectedDefaultAutoCheckoutLength = MAX_VALID_LENGTH
+            ),
+            DefaultAutoCheckoutLengthTestCase(
+                // now doesn't matter here, as defaultCheckInLengthInMinutes is not null
+                now = Instant.parse("1970-01-01T00:00:00.000Z"),
+                // max valid length = 23:45h
+                // TraceLocations with CWA can actually only have a max length of 23:45h. However, a trace location
+                // created by a third party could have a bigger length.
+                defaultCheckInLengthInMinutes = MAX_VALID_LENGTH + 1,
+                startDate = null,
+                endDate = null,
+                expectedDefaultAutoCheckoutLength = MAX_VALID_LENGTH
+            ),
+            DefaultAutoCheckoutLengthTestCase(
+                now = Instant.parse("2021-12-23T17:00:00.000Z"),
+                defaultCheckInLengthInMinutes = null,
+                startDate = Instant.parse("2021-12-24T15:00:00.000Z"),
+                endDate = Instant.parse("2021-12-24T17:00:00.000Z"),
+                // use 23:45h if user checks in earlier than 23:45 before the event ends
+                expectedDefaultAutoCheckoutLength = MAX_VALID_LENGTH
+            ),
+            DefaultAutoCheckoutLengthTestCase(
+                now = Instant.parse("2021-12-23T17:30:00.000Z"),
+                defaultCheckInLengthInMinutes = null,
+                startDate = Instant.parse("2021-12-24T15:00:00.000Z"),
+                endDate = Instant.parse("2021-12-24T17:00:00.000Z"),
+                // 23:30h in minutes
+                expectedDefaultAutoCheckoutLength = (TimeUnit.HOURS.toMinutes(23) + 30).toInt()
+            ),
+            DefaultAutoCheckoutLengthTestCase(
+                now = Instant.parse("2021-12-24T16:00:00.000Z"),
+                defaultCheckInLengthInMinutes = null,
+                startDate = Instant.parse("2021-12-24T15:00:00.000Z"),
+                endDate = Instant.parse("2021-12-24T17:00:00.000Z"),
+                expectedDefaultAutoCheckoutLength = 60
+            ),
+            DefaultAutoCheckoutLengthTestCase(
+                now = Instant.parse("2021-12-24T17:01:00.000Z"),
+                defaultCheckInLengthInMinutes = null,
+                startDate = Instant.parse("2021-12-24T15:00:00.000Z"),
+                endDate = Instant.parse("2021-12-24T17:00:00.000Z"),
+                expectedDefaultAutoCheckoutLength = 15
+            ),
+            DefaultAutoCheckoutLengthTestCase(
+                now = Instant.parse("2021-12-24T17:30:00.000Z"),
+                defaultCheckInLengthInMinutes = null,
+                startDate = Instant.parse("2021-12-24T15:00:00.000Z"),
+                endDate = Instant.parse("2021-12-24T17:00:00.000Z"),
+                // We take the min value when the user checks in after the event has already ended
+                expectedDefaultAutoCheckoutLength = 15
+            ),
+            DefaultAutoCheckoutLengthTestCase(
+                now = Instant.parse("2021-12-24T16:31:00.000Z"),
+                defaultCheckInLengthInMinutes = null,
+                startDate = Instant.parse("2021-12-24T15:00:00.000Z"),
+                endDate = Instant.parse("2021-12-24T17:00:00.000Z"),
+                // Event ends in 29min ->  we round to the nearest 15 minutes
+                expectedDefaultAutoCheckoutLength = 30
+            ),
+            DefaultAutoCheckoutLengthTestCase(
+                now = Instant.parse("2021-12-24T16:38:00.000Z"),
+                defaultCheckInLengthInMinutes = null,
+                startDate = Instant.parse("2021-12-24T15:00:00.000Z"),
+                endDate = Instant.parse("2021-12-24T17:00:00.000Z"),
+                // Event ends in 22min ->  we round to the nearest 15 minutes
+                expectedDefaultAutoCheckoutLength = 15
+            ),
+            DefaultAutoCheckoutLengthTestCase(
+                now = Instant.parse("2021-12-24T16:59:00.000Z"),
+                defaultCheckInLengthInMinutes = null,
+                startDate = Instant.parse("2021-12-24T15:00:00.000Z"),
+                endDate = Instant.parse("2021-12-24T17:00:00.000Z"),
+                // Event ends in 1min ->  we are not rounding to 0 but to the min value (15min)
+                expectedDefaultAutoCheckoutLength = 15
+            ),
+            DefaultAutoCheckoutLengthTestCase(
+                now = Instant.parse("2021-12-24T17:00:00.000Z"),
+                defaultCheckInLengthInMinutes = null,
+                startDate = Instant.parse("2021-12-24T15:00:00.000Z"),
+                endDate = Instant.parse("2021-12-24T17:00:00.000Z"),
+                // We check in at event end, return min value (15min)
+                expectedDefaultAutoCheckoutLength = 15
+            )
+        )
+    }
+}
+
+data class DefaultAutoCheckoutLengthTestCase(
+    val now: Instant,
+    val defaultCheckInLengthInMinutes: Int?,
+    val startDate: Instant?,
+    val endDate: Instant?,
+    val expectedDefaultAutoCheckoutLength: Int,
+)
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/events/server/qrcodepostertemplate/QrCodePosterTemplateApiV1Test.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/events/server/qrcodepostertemplate/QrCodePosterTemplateApiV1Test.kt
index fe715bcdc2a27941e2f4c7206a274a39039a0637..0aea9cdf1e398308995bde72f087fa3b094386ba 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/events/server/qrcodepostertemplate/QrCodePosterTemplateApiV1Test.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/events/server/qrcodepostertemplate/QrCodePosterTemplateApiV1Test.kt
@@ -114,4 +114,49 @@ class QrCodePosterTemplateApiV1Test : BaseIOTest() {
             headers["If-None-Match"] shouldBe "ETAG_OF_MOCKED_RESPONSE"
         }
     }
+
+    @Test
+    fun `should return cached response when backend returns unsuccessful response`() {
+
+        // Backend response contains Cache-Control header "public,max-age=300", therefore, okhttp should
+        // serve the cached response in case the backend returns an unsuccessful response for a subsequent request
+
+        webServer.enqueue(
+            MockResponse()
+                .setBody("Poster Template")
+                .setResponseCode(200)
+                .setHeader("ETag", "ETAG_OF_MOCKED_RESPONSE")
+                .setHeader("Cache-Control", "public,max-age=300")
+        )
+
+        runBlocking {
+            createAPI().getQrCodePosterTemplate().apply {
+                // we should receive the body and ETag
+                code() shouldBe 200
+                body()!!.string() shouldBe "Poster Template"
+                headers()["ETag"] shouldBe "ETAG_OF_MOCKED_RESPONSE"
+                headers()["Cache-Control"] shouldBe "public,max-age=300"
+            }
+        }
+
+        webServer.takeRequest(5, TimeUnit.SECONDS)
+
+        // Second response is unsuccessful ...
+        webServer.enqueue(
+            MockResponse()
+                .setResponseCode(500)
+        )
+
+        // ... and in this case, okhttp should serve the cached response
+        runBlocking {
+            createAPI().getQrCodePosterTemplate().apply {
+                code() shouldBe 200
+                raw().cacheResponse shouldNotBe null
+                // cached poster template should be returned
+                body()!!.string() shouldBe "Poster Template"
+                headers()["ETag"] shouldBe "ETAG_OF_MOCKED_RESPONSE"
+                headers()["Cache-Control"] shouldBe "public,max-age=300"
+            }
+        }
+    }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/events/server/qrcodepostertemplate/QrCodePosterTemplateServerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/events/server/qrcodepostertemplate/QrCodePosterTemplateServerTest.kt
index 15083e52e544f6bc9586f5963ca5f7ba1071eb78..68c3ee124e630adce7004a40f3f0454ce65a128d 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/events/server/qrcodepostertemplate/QrCodePosterTemplateServerTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/events/server/qrcodepostertemplate/QrCodePosterTemplateServerTest.kt
@@ -23,7 +23,7 @@ internal class QrCodePosterTemplateServerTest : BaseTest() {
     @MockK lateinit var defaultTemplateSource: DefaultQrCodePosterTemplateSource
 
     /**
-     * Info: [QrCodePosterTemplateApiV1Test] is testing if the ETag is set correctly
+     * Info: [QrCodePosterTemplateApiV1Test] is testing if okhttp caching is working correctly
      */
 
     @BeforeEach
@@ -31,7 +31,7 @@ internal class QrCodePosterTemplateServerTest : BaseTest() {
         MockKAnnotations.init(this)
 
         every { signatureValidation.hasValidSignature(any(), any()) } returns true
-        every { defaultTemplateSource.getDefaultQrCodePosterTemplate() } returns "CACHE".toByteArray()
+        every { defaultTemplateSource.getDefaultQrCodePosterTemplate() } returns "DEFAULT TEMPLATE".toByteArray()
     }
 
     private fun createInstance() = QrCodePosterTemplateServer(
@@ -47,13 +47,15 @@ internal class QrCodePosterTemplateServerTest : BaseTest() {
         } returns Response.success(POSTER_BUNDLE.toResponseBody())
 
         createInstance().downloadQrCodePosterTemplate().apply {
-            template.toStringUtf8().substring(0, 22) shouldBe "<vector xmlns:android="
-            offsetX shouldBe 10.0f
-            offsetY shouldBe 10.0f
-            qrCodeSideLength shouldBe 100
+
+            // check if template contains the pdf by checking the first characters
+            template.toStringUtf8().substring(0, 8) shouldBe "%PDF-1.1"
+            offsetX shouldBe 0.16f
+            offsetY shouldBe 0.095f
+            qrCodeSideLength shouldBe 1000
             with(descriptionTextBox) {
-                offsetX shouldBe 0.0f
-                offsetY shouldBe 0.0f
+                offsetX shouldBe 0.132f
+                offsetY shouldBe 0.61f
                 width shouldBe 100
                 height shouldBe 20
                 fontSize shouldBe 10
@@ -65,14 +67,14 @@ internal class QrCodePosterTemplateServerTest : BaseTest() {
     }
 
     @Test
-    fun `should fallback to cached or default template if signature is invalid`() = runBlockingTest {
+    fun `should fallback to default template if signature is invalid`() = runBlockingTest {
         every { signatureValidation.hasValidSignature(any(), any()) } returns false
 
         coEvery {
             api.getQrCodePosterTemplate()
         } returns Response.success(POSTER_BUNDLE.toResponseBody())
 
-        createInstance().getTemplateFromApiOrCache() shouldBe "CACHE".toByteArray()
+        createInstance().getTemplateFromApiOrCache() shouldBe "DEFAULT TEMPLATE".toByteArray()
     }
 
     @Test
@@ -87,12 +89,12 @@ internal class QrCodePosterTemplateServerTest : BaseTest() {
     }
 
     @Test
-    fun `should fallback to cached or default template when response is not successful`() = runBlockingTest {
+    fun `should fallback to default template when response is not successful`() = runBlockingTest {
         coEvery {
             api.getQrCodePosterTemplate()
         } returns Response.error(404, "ERROR".toResponseBody())
 
-        createInstance().getTemplateFromApiOrCache() shouldBe "CACHE".toByteArray()
+        createInstance().getTemplateFromApiOrCache() shouldBe "DEFAULT TEMPLATE".toByteArray()
     }
 
     companion object {
@@ -101,8 +103,8 @@ internal class QrCodePosterTemplateServerTest : BaseTest() {
 
         private val descriptionTextBox =
             QrCodePosterTemplate.QRCodePosterTemplateAndroid.QRCodeTextBoxAndroid.newBuilder()
-                .setOffsetX(10)
-                .setOffsetY(50)
+                .setOffsetX(0.132f)
+                .setOffsetY(0.61f)
                 .setWidth(100)
                 .setHeight(20)
                 .setFontSize(10)
@@ -110,38 +112,29 @@ internal class QrCodePosterTemplateServerTest : BaseTest() {
                 .build()
 
         private val qrCodePosterTemplate = QrCodePosterTemplate.QRCodePosterTemplateAndroid.newBuilder()
-            .setOffsetX(10.0f)
-            .setOffsetY(10.0f)
-            .setQrCodeSideLength(100)
+            .setOffsetX(0.16f)
+            .setOffsetY(0.095f)
+            .setQrCodeSideLength(1000)
             .setDescriptionTextBox(descriptionTextBox)
-            .setTemplate(
-                ByteString.copyFromUtf8("""<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
-                "    xmlns:aapt=\"http://schemas.android.com/aapt\"\n" +
-                "    android:width=\"595.3dp\"\n" +
-                "    android:height=\"841.9dp\"\n" +
-                "    android:viewportWidth=\"595.3\"\n" +
-                "    android:viewportHeight=\"841.9\">\n" +
-                "  <path\n" +
-                "      android:pathData=\"M78.1,665.6v-12.8h1.2l3.6,8.5v-8.5h1.5v12.8h-1.1l-3.7,-8.7v8.7H78.1z\"\n" +
-                "      android:fillColor=\"#404040\"/>\n" +
-                "</vector>\n"""))
+            .setTemplate(BINARY PDF)
             .build()*/
 
-        // TODO update this bundle to send PDF file not XML
         private val POSTER_BUNDLE = (
-            "504b03040a000000080014867d52008c85fefb000000ab0100000a0000006578706f72742e62" +
-                "696e7d90cf4bc33014c7071e949c0415bc0825bbc8685f9676edbad216440fbb78f61c9a6a8ae912da9089ff80ffb66957700e" +
-                "f185bcc3e7fbe3f0d0d7596eebcaa8cefb68e5aecfd88e77aae10516c6e88c90be1275cb7a983854aa254cbf93aeeec9c430f2" +
-                "dc4c71a6cdff59673804269aed1b6e4481e34d0c11d7bf3551376fc215a62b0a9b53d136f55eabcebc1c15fcedd81ed7e0d279" +
-                "72cd8c18bd3fee013d31c30afcbc4e81fa49124362031a422a28843282c44f21b6815b0ec47654020a540611ac7dc7d7d6fded" +
-                "90fec427edaf8d948f4aaaaec0f3d572789894282787eb97e86636f31eee86e5f1c5d505ba0c6fb9777d8fc2f3f9729c6f504b" +
-                "03040a000000080014867d528a1d0eac8f0000008a0000000a0000006578706f72742e736967018a0075ff0a87010a380a1864" +
-                "652e726b692e636f726f6e617761726e6170702d6465761a02763122033236322a13312e322e3834302e31303034352e342e33" +
-                "2e321001180122473045022100c251eb5e62282e5573fdb915edf61115d61d020354a510bed66b7b8ce482a38d02202a793775" +
-                "0958155c82a17acb6dd4b666afc1566285ef532e6e8c11e1d52e5a75504b01020a000a000000080014867d52008c85fefb0000" +
-                "00ab0100000a0000000000000000000000a401000000006578706f72742e62696e504b01020a000a000000080014867d528a1d" +
-                "0eac8f0000008a0000000a0000000000000000000000a401230100006578706f72742e736967504b0506000000000200020070" +
-                "000000da0100000000"
+            "504b03040a0000000800685588525c24ae70900100000e0300000a0000006578706f72742e62696e6d52cd4ac3401006410a0bde2c" +
+                "28280c9442556a9226db7aa8155a5b04154b1af0507bd89a6d8da45949b6507d099fc293275fa13e840fe0c527f0ec6e7e6ada" +
+                "744f33df7edf7c33b38bbe378bddf34e593bd65071fe36fff87c47480315d8f01101d4eba058cf4f149416e1c465638189a374" +
+                "c9980650113c53208d06a29e2d15a8b2461a9263e1a56307d0d7a57010432d36f5386871764d6d8734d90cfaaa20e9aa0a9a61" +
+                "0c964df4b449da25aa21639f8a9a497f2166d2804dfdfba493a8c10ef378922f302d8d246864b2ca8f8fd29b0e794890b48c5e" +
+                "329a24a0522d28ce840665934d88b74a1433aecd16915896c7c5680118d9dd1b4bbbbfa2de983f00c69212709f9289b8695a61" +
+                "2531246827608dc24c6edab2c3b074415d97c12df35dfb002c59ac6d4987b842e235f3e908a98091ba3850c558c7308205261c" +
+                "a21bef1fabd5329856cbf20c9ce2719f382ef593f7361913ff25fdb63de7858a5e201a95f83c6c0f57312a16db371d94475f85" +
+                "c6feddebfc147e7287bb5b1b47b946feb7b477b663c37609557285c8f50f504b03040a00000008006855885218d81ad88f0000" +
+                "008a0000000a0000006578706f72742e736967018a0075ff0a87010a380a1864652e726b692e636f726f6e617761726e617070" +
+                "2d6465761a02763122033236322a13312e322e3834302e31303034352e342e332e3210011801224730450220148d01176d9be9" +
+                "8fa78ca1b0cad0b8b12033f35a43cb7d10369536c233701fff022100ed7c748e7f8e82c6a98ead3a19f2041b1ec090268e3ae1" +
+                "5aa146bd0d567617c7504b01020a000a0000000800685588525c24ae70900100000e0300000a0000000000000000000000a401" +
+                "000000006578706f72742e62696e504b01020a000a00000008006855885218d81ad88f0000008a0000000a0000000000000000" +
+                "000000a401b80100006578706f72742e736967504b05060000000002000200700000006f0200000000"
             ).decodeHex()
     }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/storage/repo/DefaultTraceLocationRepositoryTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/storage/repo/DefaultTraceLocationRepositoryTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..89c9e4da754a01c06001e2e7e9fe2a4976054553
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/storage/repo/DefaultTraceLocationRepositoryTest.kt
@@ -0,0 +1,74 @@
+package de.rki.coronawarnapp.eventregistration.storage.repo
+
+import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocation
+import de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase
+import de.rki.coronawarnapp.eventregistration.storage.dao.TraceLocationDao
+import de.rki.coronawarnapp.eventregistration.storage.entity.toTraceLocationEntity
+import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass
+import de.rki.coronawarnapp.util.TimeStamper
+import io.kotest.matchers.shouldBe
+import io.mockk.MockKAnnotations
+import io.mockk.every
+import io.mockk.impl.annotations.MockK
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.runBlockingTest
+import okio.ByteString.Companion.encode
+import org.joda.time.Instant
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import testhelpers.BaseTest
+
+internal class DefaultTraceLocationRepositoryTest : BaseTest() {
+
+    @MockK lateinit var factory: TraceLocationDatabase.Factory
+    @MockK lateinit var database: TraceLocationDatabase
+    @MockK lateinit var appScope: CoroutineScope
+    @MockK lateinit var timeStamper: TimeStamper
+    @MockK lateinit var traceLocationDao: TraceLocationDao
+
+    @BeforeEach
+    fun setUp() {
+        MockKAnnotations.init(this)
+        every { factory.create() } returns database
+        every { database.traceLocationDao() } returns traceLocationDao
+    }
+
+    private fun createInstance() = DefaultTraceLocationRepository(factory, appScope, timeStamper)
+
+    @Test
+    fun `getTraceLocationsWithinRetention() should filter out stale trace locations`() = runBlockingTest {
+
+        // Now = Jan 16th 2020, 00:00
+        // TraceLocations should be kept for 15 days, so every TraceLocation with an end date before
+        // Jan 1st 2020, 00:00 should get deleted
+        every { timeStamper.nowUTC } returns Instant.parse("2020-01-16T00:00:00.000Z")
+
+        val traceLocationWithinRetention = createTraceLocationWithEndDate(Instant.parse("2020-01-01T00:00:00.000Z"))
+
+        // should be filtered out
+        val staleTraceLocation = createTraceLocationWithEndDate(Instant.parse("2019-12-31T23:59:59.000Z"))
+
+        every { traceLocationDao.allEntries() } returns flowOf(
+            listOf(
+                staleTraceLocation.toTraceLocationEntity(),
+                traceLocationWithinRetention.toTraceLocationEntity()
+            )
+        )
+
+        createInstance().traceLocationsWithinRetention.first() shouldBe listOf(traceLocationWithinRetention)
+    }
+
+    private fun createTraceLocationWithEndDate(endDate: Instant?) = TraceLocation(
+        id = 1,
+        type = TraceLocationOuterClass.TraceLocationType.UNRECOGNIZED,
+        description = "",
+        address = "",
+        startDate = null,
+        endDate = endDate,
+        defaultCheckInLengthInMinutes = 30,
+        cryptographicSeed = "seed byte array".encode(),
+        cnPublicKey = "cnPublicKey"
+    )
+}
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/storage/retention/TraceLocationRetentionTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/storage/retention/TraceLocationRetentionTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d0f58ebbc8de7827753a9d2f70cffd5423ec0b68
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/storage/retention/TraceLocationRetentionTest.kt
@@ -0,0 +1,46 @@
+package de.rki.coronawarnapp.eventregistration.storage.retention
+
+import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocation
+import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass
+import io.kotest.matchers.shouldBe
+import okio.ByteString.Companion.encode
+import org.joda.time.Instant
+import org.junit.jupiter.api.Test
+
+internal class TraceLocationRetentionTest {
+
+    @Test
+    fun `isWithinRetention() and isOutOfRetention() should return correct result`() {
+
+        // Now = Jan 16th 2020, 00:00
+        // TraceLocations should be kept for 15 days, so every trace location with and end date before
+        // Jan 1st 2020, 00:00 should be out of retention
+        val now = Instant.parse("2020-01-16T00:00:00.000Z")
+
+        val traceLocationWithinRetention = createTraceLocation(Instant.parse("2020-01-01T00:00:00.000Z"))
+        val traceLocationOutOfRetention = createTraceLocation(Instant.parse("2019-12-31T23:59:59.000Z"))
+        val traceLocationNoEndDate = createTraceLocation(null)
+
+        traceLocationWithinRetention.isWithinRetention(now) shouldBe true
+        traceLocationWithinRetention.isOutOfRetention(now) shouldBe false
+
+        traceLocationOutOfRetention.isWithinRetention(now) shouldBe false
+        traceLocationOutOfRetention.isOutOfRetention(now) shouldBe true
+
+        // trace locations without end date are never out of retention
+        traceLocationNoEndDate.isWithinRetention(now) shouldBe true
+        traceLocationNoEndDate.isOutOfRetention(now) shouldBe false
+    }
+
+    private fun createTraceLocation(endDate: Instant?) = TraceLocation(
+        id = 1,
+        type = TraceLocationOuterClass.TraceLocationType.UNRECOGNIZED,
+        description = "",
+        address = "",
+        startDate = null,
+        endDate = endDate,
+        defaultCheckInLengthInMinutes = 30,
+        cryptographicSeed = "seed byte array".encode(),
+        cnPublicKey = "cnPublicKey"
+    )
+}
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/main/MainActivityViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/main/MainActivityViewModelTest.kt
index 349174209a5e60b842f29743c31c5be66cbee914..e456fa43ae2757a5bfa043e2ff923cc1cbb8b57f 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/main/MainActivityViewModelTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/main/MainActivityViewModelTest.kt
@@ -44,7 +44,7 @@ class MainActivityViewModelTest : BaseTest() {
         every { environmentSetup.currentEnvironment } returns EnvironmentSetup.Type.WRU
         every { traceLocationSettings.onboardingStatus } returns TraceLocationSettings.OnboardingStatus.NOT_ONBOARDED
         every { onboardingSettings.isBackgroundCheckDone } returns true
-        every { checkInRepository.allCheckIns } returns MutableStateFlow(listOf())
+        every { checkInRepository.checkInsWithinRetention } returns MutableStateFlow(listOf())
     }
 
     private fun createInstance(): MainActivityViewModel = MainActivityViewModel(
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/CheckOutHandlerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/CheckOutHandlerTest.kt
index 04fbb3a38e611423435fd717cc6e31d76f76e096..07007ff99eeed66a36d4c651f91d3a51c8904be0 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/CheckOutHandlerTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/CheckOutHandlerTest.kt
@@ -1,14 +1,16 @@
 package de.rki.coronawarnapp.presencetracing.checkins.checkout
 
-import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
 import de.rki.coronawarnapp.eventregistration.checkins.CheckIn
 import de.rki.coronawarnapp.eventregistration.checkins.CheckInRepository
 import de.rki.coronawarnapp.util.TimeStamper
 import io.kotest.matchers.shouldBe
 import io.mockk.MockKAnnotations
 import io.mockk.coEvery
+import io.mockk.coVerify
 import io.mockk.every
 import io.mockk.impl.annotations.MockK
+import io.mockk.just
+import io.mockk.runs
 import kotlinx.coroutines.test.runBlockingTest
 import okio.ByteString.Companion.encode
 import org.joda.time.Instant
@@ -20,7 +22,7 @@ class CheckOutHandlerTest : BaseTest() {
 
     @MockK lateinit var repository: CheckInRepository
     @MockK lateinit var timeStamper: TimeStamper
-    @MockK lateinit var diaryRepository: ContactDiaryRepository
+    @MockK lateinit var contactJournalCheckInEntryCreator: ContactJournalCheckInEntryCreator
 
     private val testCheckIn = CheckIn(
         id = 42L,
@@ -39,6 +41,12 @@ class CheckOutHandlerTest : BaseTest() {
         completed = false,
         createJournalEntry = true
     )
+
+    private val testCheckInDontCreate = testCheckIn.copy(
+        id = 43L,
+        createJournalEntry = false
+    )
+
     private var updatedCheckIn: CheckIn? = null
     private val nowUTC = Instant.ofEpochMilli(50)
 
@@ -52,12 +60,19 @@ class CheckOutHandlerTest : BaseTest() {
             val callback: (CheckIn) -> CheckIn = arg(1)
             updatedCheckIn = callback(testCheckIn)
         }
+
+        coEvery { repository.updateCheckIn(43, any()) } coAnswers {
+            val callback: (CheckIn) -> CheckIn = arg(1)
+            updatedCheckIn = callback(testCheckInDontCreate)
+        }
+
+        coEvery { contactJournalCheckInEntryCreator.createEntry(any()) } just runs
     }
 
     private fun createInstance() = CheckOutHandler(
         repository = repository,
         timeStamper = timeStamper,
-        diaryRepository = diaryRepository,
+        contactJournalCheckInEntryCreator = contactJournalCheckInEntryCreator
     )
 
     @Test
@@ -68,7 +83,37 @@ class CheckOutHandlerTest : BaseTest() {
             checkInEnd = nowUTC,
             completed = true
         )
-        // TODO journal creation
+
+        coVerify(exactly = 1) {
+            contactJournalCheckInEntryCreator.createEntry(any())
+        }
+
         // TODO cancel auto checkouts
     }
+
+    @Test
+    fun `Creates entry if create journal entry is true`() = runBlockingTest {
+        createInstance().apply {
+            checkOut(42)
+        }
+
+        updatedCheckIn?.createJournalEntry shouldBe true
+
+        coVerify(exactly = 1) {
+            contactJournalCheckInEntryCreator.createEntry(any())
+        }
+    }
+
+    @Test
+    fun `Does not create entry if create journal entry is false`() = runBlockingTest {
+        createInstance().apply {
+            checkOut(43)
+        }
+
+        updatedCheckIn?.createJournalEntry shouldBe false
+
+        coVerify(exactly = 0) {
+            contactJournalCheckInEntryCreator.createEntry(any())
+        }
+    }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/ContactJournalCheckInEntryCreatorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/ContactJournalCheckInEntryCreatorTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..58834e6c7b70de6ac2f0e5a7452baabbd0c29e86
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/ContactJournalCheckInEntryCreatorTest.kt
@@ -0,0 +1,87 @@
+package de.rki.coronawarnapp.presencetracing.checkins.checkout
+
+import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryLocation
+import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
+import de.rki.coronawarnapp.eventregistration.checkins.CheckIn
+import io.mockk.MockKAnnotations
+import io.mockk.coEvery
+import io.mockk.coVerify
+import io.mockk.every
+import io.mockk.impl.annotations.MockK
+import io.mockk.just
+import io.mockk.runs
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.runBlockingTest
+import okio.ByteString.Companion.encode
+import org.joda.time.Instant
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import testhelpers.BaseTest
+
+class ContactJournalCheckInEntryCreatorTest : BaseTest() {
+
+    @MockK lateinit var contactDiaryRepo: ContactDiaryRepository
+
+    private val testCheckIn = CheckIn(
+        id = 42L,
+        traceLocationId = "traceLocationId1".encode(),
+        version = 1,
+        type = 1,
+        description = "Restaurant",
+        address = "Around the corner",
+        traceLocationStart = Instant.parse("2021-03-04T22:00+01:00"),
+        traceLocationEnd = Instant.parse("2021-03-04T23:00+01:00"),
+        defaultCheckInLengthInMinutes = null,
+        cryptographicSeed = "cryptographicSeed".encode(),
+        cnPublicKey = "cnPublicKey",
+        checkInStart = Instant.parse("2021-03-04T22:00+01:00"),
+        checkInEnd = Instant.parse("2021-03-04T23:00+01:00"),
+        completed = false,
+        createJournalEntry = true
+    )
+
+    private val testLocation = DefaultContactDiaryLocation(
+        locationId = 123L,
+        locationName = "${testCheckIn.description}, ${testCheckIn.address}, ${testCheckIn.traceLocationStart} - ${testCheckIn.traceLocationEnd}",
+        traceLocationID = testCheckIn.traceLocationId
+    )
+
+    @BeforeEach
+    fun setup() {
+        MockKAnnotations.init(this)
+
+        every { contactDiaryRepo.locations } returns flowOf(emptyList())
+
+        every { contactDiaryRepo.locationVisits } returns flowOf(emptyList())
+
+        coEvery { contactDiaryRepo.addLocationVisit(any()) } just runs
+
+        coEvery { contactDiaryRepo.addLocation(any()) } returns testLocation
+    }
+
+    private fun createInstance() = ContactJournalCheckInEntryCreator(
+        diaryRepository = contactDiaryRepo
+    )
+
+    @Test
+    fun `Creates location if missing`() = runBlockingTest {
+        every { contactDiaryRepo.locations } returns flowOf(emptyList()) andThen flowOf(listOf(testLocation))
+
+        // Repo returns an empty list for the first call, so location is missing and a new location should be created and added
+        val instance = createInstance()
+        instance.createEntry(testCheckIn)
+
+        coVerify(exactly = 1) {
+            contactDiaryRepo.addLocation(any())
+        }
+
+        // Location with trace location id already exists, so that location will be used
+        instance.createEntry(testCheckIn)
+        instance.createEntry(testCheckIn)
+        instance.createEntry(testCheckIn)
+
+        coVerify(exactly = 1) {
+            contactDiaryRepo.addLocation(any())
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/calculation/CheckInWarningMatcherTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/calculation/CheckInWarningMatcherTest.kt
index b8beb8b1106ba1b21dc47c0596ea523728adc571..52e215794f50a5b27cedbb9853e447bce06d214a 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/calculation/CheckInWarningMatcherTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/calculation/CheckInWarningMatcherTest.kt
@@ -252,4 +252,59 @@ class CheckInWarningMatcherTest : BaseTest() {
             }
         }
     }
+
+    @Test
+    fun `we do not match our own CheckIns`() {
+        val checkIn1 = createCheckIn(
+            id = 2L,
+            traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871",
+            startDateStr = "2021-03-04T10:15+01:00",
+            endDateStr = "2021-03-04T10:17+01:00"
+        )
+        val checkIn2 = createCheckIn(
+            id = 3L,
+            traceLocationId = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060",
+            startDateStr = "2021-03-04T09:15+01:00",
+            endDateStr = "2021-03-04T10:12+01:00",
+            isSubmitted = true
+        )
+
+        val warning1 = createWarning(
+            traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871",
+            startIntervalDateStr = "2021-03-04T10:00+01:00",
+            period = 6,
+            transmissionRiskLevel = 8
+        )
+
+        val warning2 = createWarning(
+            traceLocationId = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060",
+            startIntervalDateStr = "2021-03-04T10:00+01:00",
+            period = 6,
+            transmissionRiskLevel = 8
+        )
+
+        val warningPackage = object : TraceWarningPackage {
+            override suspend fun extractWarnings(): List<TraceWarning.TraceTimeIntervalWarning> {
+                return listOf(warning1, warning2)
+            }
+
+            override val packageId: WarningPackageId
+                get() = "id"
+        }
+
+        runBlockingTest {
+            val result = createInstance().process(
+                checkIns = listOf(checkIn1, checkIn2),
+                warningPackages = listOf(warningPackage)
+            )
+            result.apply {
+                successful shouldBe true
+                processedPackages.single().warningPackage shouldBe warningPackage
+                processedPackages.single().apply {
+                    overlaps.size shouldBe 1
+                    overlaps.any { it.checkInId == 2L } shouldBe true
+                }
+            }
+        }
+    }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/calculation/OverlapTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/calculation/OverlapTest.kt
index 67cdb5a057bde725542c8cd8712ade2d4aeb3ba0..bff78e2cc5b30c5fc13a732d15456d48d6f4f3f6 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/calculation/OverlapTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/calculation/OverlapTest.kt
@@ -262,13 +262,32 @@ class OverlapTest : BaseTest() {
             traceWarningPackageId = id
         )!!.roundedMinutes shouldBe 5
     }
+
+    @Test
+    fun `returns null if it matches our own ssubmitted CheckIn`() {
+        createCheckIn(
+            traceLocationId = locationId,
+            startDateStr = "2021-03-04T10:15+01:00",
+            endDateStr = "2021-03-04T10:17+01:00",
+            isSubmitted = true,
+        ).calculateOverlap(
+            createWarning(
+                traceLocationId = locationId,
+                startIntervalDateStr = "2021-03-04T10:00+01:00",
+                period = 6,
+                transmissionRiskLevel = 8
+            ),
+            traceWarningPackageId = id
+        ) shouldBe null
+    }
 }
 
 fun createCheckIn(
     id: Long = 1L,
     traceLocationId: String,
     startDateStr: String,
-    endDateStr: String
+    endDateStr: String,
+    isSubmitted: Boolean = false,
 ) = CheckIn(
     id = id,
     traceLocationId = traceLocationId.decodeHex(),
@@ -284,7 +303,8 @@ fun createCheckIn(
     checkInStart = Instant.parse(startDateStr),
     checkInEnd = Instant.parse(endDateStr),
     completed = false,
-    createJournalEntry = false
+    createJournalEntry = false,
+    isSubmitted = isSubmitted
 )
 
 fun createWarning(
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTaskTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTaskTest.kt
index e44656741f40654af7de030c9812598a591047f4..918257658101455d756ffaa64ddcf11ac0885cb4 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTaskTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/execution/PresenceTracingWarningTaskTest.kt
@@ -46,7 +46,7 @@ class PresenceTracingWarningTaskTest : BaseTest() {
         MockKAnnotations.init(this)
 
         every { timeStamper.nowUTC } returns Instant.ofEpochMilli(9000)
-        coEvery { syncTool.syncPackages() } returns mockk()
+        coEvery { syncTool.syncPackages() } returns TraceWarningPackageSyncTool.SyncResult(successful = true)
         coEvery { checkInWarningMatcher.process(any(), any()) } answers {
             CheckInWarningMatcher.Result(
                 successful = true,
@@ -64,7 +64,7 @@ class PresenceTracingWarningTaskTest : BaseTest() {
             coEvery { markPackagesProcessed(any()) } just Runs
         }
 
-        coEvery { checkInsRepository.allCheckIns } returns flowOf(listOf(CHECKIN_1, CHECKIN_2))
+        coEvery { checkInsRepository.checkInsWithinRetention } returns flowOf(listOf(CHECKIN_1, CHECKIN_2))
 
         presenceTracingRiskRepository.apply {
             coEvery { deleteAllMatches() } just Runs
@@ -89,7 +89,7 @@ class PresenceTracingWarningTaskTest : BaseTest() {
         coVerifySequence {
             syncTool.syncPackages()
             presenceTracingRiskRepository.deleteStaleData()
-            checkInsRepository.allCheckIns
+            checkInsRepository.checkInsWithinRetention
             traceWarningRepository.unprocessedWarningPackages
 
             checkInWarningMatcher.process(any(), any())
@@ -120,14 +120,14 @@ class PresenceTracingWarningTaskTest : BaseTest() {
 
     @Test
     fun `there are no check-ins to match against`() = runBlockingTest {
-        coEvery { checkInsRepository.allCheckIns } returns flowOf(emptyList())
+        coEvery { checkInsRepository.checkInsWithinRetention } returns flowOf(emptyList())
 
         createInstance().run(mockk()) shouldNotBe null
 
         coVerifySequence {
             syncTool.syncPackages()
             presenceTracingRiskRepository.deleteStaleData()
-            checkInsRepository.allCheckIns
+            checkInsRepository.checkInsWithinRetention
 
             presenceTracingRiskRepository.deleteAllMatches()
             presenceTracingRiskRepository.reportCalculation(successful = true)
@@ -143,13 +143,33 @@ class PresenceTracingWarningTaskTest : BaseTest() {
         coVerifySequence {
             syncTool.syncPackages()
             presenceTracingRiskRepository.deleteStaleData()
-            checkInsRepository.allCheckIns
+            checkInsRepository.checkInsWithinRetention
             traceWarningRepository.unprocessedWarningPackages
 
             presenceTracingRiskRepository.reportCalculation(successful = true)
         }
     }
 
+    @Test
+    fun `report failure if downloads fail`() = runBlockingTest {
+        coEvery { syncTool.syncPackages() } returns TraceWarningPackageSyncTool.SyncResult(successful = false)
+
+        createInstance().run(mockk()) shouldNotBe null
+
+        coVerifySequence {
+            syncTool.syncPackages()
+
+            presenceTracingRiskRepository.reportCalculation(
+                successful = false,
+                overlaps = emptyList()
+            )
+        }
+
+        coVerify(exactly = 0) {
+            traceWarningRepository.markPackagesProcessed(any())
+        }
+    }
+
     @Test
     fun `report failure if matching throws exception`() = runBlockingTest {
         coEvery { checkInWarningMatcher.process(any(), any()) } throws IllegalArgumentException()
@@ -160,7 +180,7 @@ class PresenceTracingWarningTaskTest : BaseTest() {
         coVerifySequence {
             syncTool.syncPackages()
             presenceTracingRiskRepository.deleteStaleData()
-            checkInsRepository.allCheckIns
+            checkInsRepository.checkInsWithinRetention
             traceWarningRepository.unprocessedWarningPackages
 
             checkInWarningMatcher.process(any(), any())
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/BaseRiskLevelStorageTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/BaseRiskLevelStorageTest.kt
index 03c6758900c2520d87a5dbf7fa83f0224ad034a7..fdff4062dbc0aefef65a35dc69770f9fb3462280 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/BaseRiskLevelStorageTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/BaseRiskLevelStorageTest.kt
@@ -220,7 +220,7 @@ class BaseRiskLevelStorageTest : BaseTest() {
             riskLevelResults.size shouldBe 2
 
             riskLevelResults[0].calculatedAt shouldBe calculatedAt
-            riskLevelResults[0].riskState shouldBe RiskState.INCREASED_RISK
+            riskLevelResults[0].riskState shouldBe RiskState.CALCULATION_FAILED
             riskLevelResults[1].calculatedAt shouldBe ewCalculatedAt
             riskLevelResults[1].riskState shouldBe RiskState.INCREASED_RISK
 
@@ -241,7 +241,7 @@ class BaseRiskLevelStorageTest : BaseTest() {
                 PtRiskLevelResult(
                     calculatedAt = calculatedAt,
                     presenceTracingDayRisk = null,
-                    riskState = RiskState.CALCULATION_FAILED
+                    riskState = RiskState.LOW_RISK
                 )
             )
         )
@@ -303,12 +303,12 @@ class BaseRiskLevelStorageTest : BaseTest() {
                 PtRiskLevelResult(
                     calculatedAt = calculatedAt,
                     presenceTracingDayRisk = null,
-                    riskState = RiskState.CALCULATION_FAILED
+                    riskState = RiskState.INCREASED_RISK
                 ),
                 PtRiskLevelResult(
                     calculatedAt = calculatedAt.minus(400L),
                     presenceTracingDayRisk = null,
-                    riskState = RiskState.LOW_RISK
+                    riskState = RiskState.CALCULATION_FAILED
                 )
             )
         )
@@ -319,7 +319,7 @@ class BaseRiskLevelStorageTest : BaseTest() {
             riskLevelResults.size shouldBe 2
 
             riskLevelResults[0].calculatedAt shouldBe ewCalculatedAt
-            riskLevelResults[0].riskState shouldBe RiskState.LOW_RISK
+            riskLevelResults[0].riskState shouldBe RiskState.INCREASED_RISK
             riskLevelResults[1].calculatedAt shouldBe ewCalculatedAt.minus(200L)
             riskLevelResults[1].riskState shouldBe RiskState.INCREASED_RISK
 
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/CombineRiskTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/CombineRiskTest.kt
index a1099568aa19e32b4143ce8da45613664c804346..9e1122826a32e6f43db61015975e11d0421c3a17 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/CombineRiskTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/CombineRiskTest.kt
@@ -17,7 +17,11 @@ class CombineRiskTest {
 
     @Test
     fun `combineRisk works`() {
-        val ptRisk = PresenceTracingDayRisk(
+        val ptRisk0 = PresenceTracingDayRisk(
+            localDateUtc = LocalDate(2021, 3, 19),
+            riskState = RiskState.LOW_RISK
+        )
+        val ptRisk1 = PresenceTracingDayRisk(
             localDateUtc = LocalDate(2021, 3, 20),
             riskState = RiskState.INCREASED_RISK
         )
@@ -29,50 +33,81 @@ class CombineRiskTest {
             localDateUtc = LocalDate(2021, 3, 22),
             riskState = RiskState.CALCULATION_FAILED
         )
-        val ewRisk = ExposureWindowDayRisk(
-            dateMillisSinceEpoch = Instant.parse("2021-03-22T14:00:00.000Z").millis,
+        val ptRisk4 = PresenceTracingDayRisk(
+            localDateUtc = LocalDate(2021, 3, 23),
+            riskState = RiskState.LOW_RISK
+        )
+        val ptRisk5 = PresenceTracingDayRisk(
+            localDateUtc = LocalDate(2021, 3, 24),
+            riskState = RiskState.INCREASED_RISK
+        )
+
+        val ewRisk0 = ExposureWindowDayRisk(
+            dateMillisSinceEpoch = Instant.parse("2021-03-24T14:00:00.000Z").millis,
+            riskLevel = RiskLevel.HIGH,
+            0,
+            0
+        )
+        val ewRisk1 = ExposureWindowDayRisk(
+            dateMillisSinceEpoch = Instant.parse("2021-03-23T14:00:00.000Z").millis,
             riskLevel = RiskLevel.HIGH,
             0,
             0
         )
         val ewRisk2 = ExposureWindowDayRisk(
+            dateMillisSinceEpoch = Instant.parse("2021-03-22T14:00:00.000Z").millis,
+            riskLevel = RiskLevel.HIGH,
+            0,
+            0
+        )
+        val ewRisk3 = ExposureWindowDayRisk(
             dateMillisSinceEpoch = Instant.parse("2021-03-19T14:00:00.000Z").millis,
             riskLevel = RiskLevel.LOW,
             0,
             0
         )
-        val ewRisk3 = ExposureWindowDayRisk(
+        val ewRisk4 = ExposureWindowDayRisk(
             dateMillisSinceEpoch = Instant.parse("2021-03-20T14:00:00.000Z").millis,
             riskLevel = RiskLevel.UNSPECIFIED,
             0,
             0
         )
-        val ewRisk4 = ExposureWindowDayRisk(
+        val ewRisk5 = ExposureWindowDayRisk(
             dateMillisSinceEpoch = Instant.parse("2021-03-15T14:00:00.000Z").millis,
             riskLevel = RiskLevel.UNSPECIFIED,
             0,
             0
         )
 
-        val ptDayRiskList: List<PresenceTracingDayRisk> = listOf(ptRisk, ptRisk2, ptRisk3)
-        val ewDayRiskList: List<ExposureWindowDayRisk> = listOf(ewRisk, ewRisk2, ewRisk3, ewRisk4)
+        val ptDayRiskList: List<PresenceTracingDayRisk> = listOf(ptRisk0, ptRisk1, ptRisk2, ptRisk3, ptRisk4, ptRisk5)
+        val ewDayRiskList: List<ExposureWindowDayRisk> = listOf(ewRisk0, ewRisk1, ewRisk2, ewRisk3, ewRisk4, ewRisk5)
         val result = combineRisk(ptDayRiskList, ewDayRiskList)
-        result.size shouldBe 5
-        result.find {
+        result.size shouldBe 7
+
+        result.single {
             it.localDate == LocalDate(2021, 3, 15)
-        }!!.riskState shouldBe RiskState.CALCULATION_FAILED
-        result.find {
+        }.riskState shouldBe RiskState.CALCULATION_FAILED
+        result.single {
             it.localDate == LocalDate(2021, 3, 19)
-        }!!.riskState shouldBe RiskState.LOW_RISK
-        result.find {
+        }.riskState shouldBe RiskState.LOW_RISK
+        result.single {
             it.localDate == LocalDate(2021, 3, 20)
-        }!!.riskState shouldBe RiskState.INCREASED_RISK
-        result.find {
+        }.riskState shouldBe RiskState.CALCULATION_FAILED
+        result.single {
             it.localDate == LocalDate(2021, 3, 21)
-        }!!.riskState shouldBe RiskState.LOW_RISK
-        result.find {
+        }.riskState shouldBe RiskState.LOW_RISK
+        result.single {
+            it.localDate == LocalDate(2021, 3, 22)
+        }.riskState shouldBe RiskState.CALCULATION_FAILED
+        result.single {
             it.localDate == LocalDate(2021, 3, 22)
-        }!!.riskState shouldBe RiskState.INCREASED_RISK
+        }.riskState shouldBe RiskState.CALCULATION_FAILED
+        result.single {
+            it.localDate == LocalDate(2021, 3, 23)
+        }.riskState shouldBe RiskState.INCREASED_RISK
+        result.single {
+            it.localDate == LocalDate(2021, 3, 24)
+        }.riskState shouldBe RiskState.INCREASED_RISK
     }
 
     @Test
@@ -85,7 +120,7 @@ class CombineRiskTest {
         )
         val ptResult2 = PtRiskLevelResult(
             calculatedAt = startInstant.plus(3000L),
-            riskState = RiskState.CALCULATION_FAILED
+            riskState = RiskState.LOW_RISK
         )
         val ptResult3 = PtRiskLevelResult(
             calculatedAt = startInstant.plus(6000L),
@@ -99,7 +134,7 @@ class CombineRiskTest {
         val ptResults = listOf(ptResult, ptResult2, ptResult4, ptResult3)
         val ewResult = createEwRiskLevelResult(
             calculatedAt = startInstant.plus(2000L),
-            riskState = RiskState.CALCULATION_FAILED
+            riskState = RiskState.LOW_RISK
         )
         val ewResult2 = createEwRiskLevelResult(
             calculatedAt = startInstant.plus(4000L),
@@ -126,11 +161,11 @@ class CombineRiskTest {
         result[3].calculatedAt shouldBe startInstant.plus(5000L)
         result[4].riskState shouldBe RiskState.INCREASED_RISK
         result[4].calculatedAt shouldBe startInstant.plus(4000L)
-        result[5].riskState shouldBe RiskState.CALCULATION_FAILED
+        result[5].riskState shouldBe RiskState.LOW_RISK
         result[5].calculatedAt shouldBe startInstant.plus(3000L)
         result[6].riskState shouldBe RiskState.LOW_RISK
         result[6].calculatedAt shouldBe startInstant.plus(2000L)
-        result[7].riskState shouldBe RiskState.LOW_RISK
+        result[7].riskState shouldBe RiskState.CALCULATION_FAILED
         result[7].calculatedAt shouldBe startInstant.plus(1000L)
     }
 
@@ -138,11 +173,11 @@ class CombineRiskTest {
     fun `max RiskState works`() {
         combine(RiskState.INCREASED_RISK, RiskState.INCREASED_RISK) shouldBe RiskState.INCREASED_RISK
         combine(RiskState.INCREASED_RISK, RiskState.LOW_RISK) shouldBe RiskState.INCREASED_RISK
-        combine(RiskState.INCREASED_RISK, RiskState.CALCULATION_FAILED) shouldBe RiskState.INCREASED_RISK
+        combine(RiskState.INCREASED_RISK, RiskState.CALCULATION_FAILED) shouldBe RiskState.CALCULATION_FAILED
         combine(RiskState.LOW_RISK, RiskState.INCREASED_RISK) shouldBe RiskState.INCREASED_RISK
-        combine(RiskState.CALCULATION_FAILED, RiskState.INCREASED_RISK) shouldBe RiskState.INCREASED_RISK
+        combine(RiskState.CALCULATION_FAILED, RiskState.INCREASED_RISK) shouldBe RiskState.CALCULATION_FAILED
         combine(RiskState.LOW_RISK, RiskState.LOW_RISK) shouldBe RiskState.LOW_RISK
-        combine(RiskState.CALCULATION_FAILED, RiskState.LOW_RISK) shouldBe RiskState.LOW_RISK
+        combine(RiskState.CALCULATION_FAILED, RiskState.LOW_RISK) shouldBe RiskState.CALCULATION_FAILED
         combine(RiskState.CALCULATION_FAILED, RiskState.CALCULATION_FAILED) shouldBe RiskState.CALCULATION_FAILED
     }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt
index 2802029978aae963e691b4abaa25e40ec5cac9cd..778d26c72e6670b9339992f8fcdeb119a7fc115b 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt
@@ -4,6 +4,7 @@ import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey
 import de.rki.coronawarnapp.appconfig.AppConfigProvider
 import de.rki.coronawarnapp.appconfig.ConfigData
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
+import de.rki.coronawarnapp.eventregistration.checkins.CheckIn
 import de.rki.coronawarnapp.eventregistration.checkins.CheckInRepository
 import de.rki.coronawarnapp.eventregistration.checkins.CheckInsTransformer
 import de.rki.coronawarnapp.exception.NoRegistrationTokenSetException
@@ -73,6 +74,25 @@ class SubmissionTaskTest : BaseTest() {
 
     private val settingLastUserActivityUTC: FlowPreference<Instant> = mockFlowPreference(Instant.EPOCH.plus(1))
 
+    private val testCheckIn1 = CheckIn(
+        id = 1L,
+        traceLocationId = mockk(),
+        version = 1,
+        type = 2,
+        description = "brothers birthday",
+        address = "Malibu",
+        traceLocationStart = Instant.EPOCH,
+        traceLocationEnd = null,
+        defaultCheckInLengthInMinutes = null,
+        cryptographicSeed = mockk(),
+        cnPublicKey = "cnPublicKey",
+        checkInStart = Instant.EPOCH,
+        checkInEnd = Instant.EPOCH.plus(9000),
+        completed = false,
+        createJournalEntry = false,
+        isSubmitted = true
+    )
+
     @BeforeEach
     fun setup() {
         MockKAnnotations.init(this)
@@ -113,8 +133,7 @@ class SubmissionTaskTest : BaseTest() {
 
         every { timeStamper.nowUTC } returns Instant.EPOCH.plus(Duration.standardHours(1))
 
-        every { checkInRepository.allCheckIns } returns flowOf(emptyList())
-        coEvery { checkInRepository.clear() } just Runs
+        every { checkInRepository.checkInsWithinRetention } returns flowOf(listOf(testCheckIn1))
         coEvery { checkInsTransformer.transform(any(), any()) } returns emptyList()
     }
 
@@ -159,7 +178,7 @@ class SubmissionTaskTest : BaseTest() {
             settingSymptomsPreference.value
 
             tekHistoryCalculations.transformToKeyHistoryInExternalFormat(listOf(tek), userSymptoms)
-            checkInRepository.allCheckIns
+            checkInRepository.checkInsWithinRetention
             checkInsTransformer.transform(any(), any())
 
             appConfigProvider.getAppConfig()
@@ -177,10 +196,11 @@ class SubmissionTaskTest : BaseTest() {
             analyticsKeySubmissionCollector.reportSubmittedInBackground()
 
             tekHistoryStorage.clear()
-            checkInRepository.clear()
             submissionSettings.symptoms
             settingSymptomsPreference.update(match { it.invoke(mockk()) == null })
 
+            checkInRepository.markCheckInAsSubmitted(testCheckIn1.id)
+
             autoSubmission.updateMode(AutoSubmission.Mode.DISABLED)
 
             backgroundWorkScheduler.stopWorkScheduler()
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/tracing/ui/details/TracingDetailsItemProviderTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/tracing/ui/details/TracingDetailsItemProviderTest.kt
index daf12a7211a3c53bb238e1cb84de4f73bda21e4c..1be311fd3e44adab39c9b2480871a5471191892c 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/tracing/ui/details/TracingDetailsItemProviderTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/tracing/ui/details/TracingDetailsItemProviderTest.kt
@@ -87,7 +87,7 @@ class TracingDetailsItemProviderTest : BaseTest() {
             exposureWindows = listOf(exposureWindow)
         )
 
-        every { combinedResult.ewRiskLevelResult } returns ewRiskLevelTaskResult
+        every { combinedResult.matchedRiskCount } returns matchedKeyCount
 
         val lastCombined = LastCombinedRiskResults(
             lastCalculated = combinedResult,
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModelTest.kt
index bfbd074700697d48cbfc6eebf01d6c887164530c..c1adf45da1f8b75e2e530e7cd7bb86f1d120bf61 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModelTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModelTest.kt
@@ -46,7 +46,7 @@ class CheckInsViewModelTest : BaseTest() {
     fun setup() {
         MockKAnnotations.init(this)
         every { savedState.set(any(), any<String>()) } just Runs
-        every { checkInsRepository.allCheckIns } returns flowOf()
+        every { checkInsRepository.checkInsWithinRetention } returns flowOf()
         every { cameraPermissionProvider.deniedPermanently } returns flowOf(false)
     }
 
@@ -120,7 +120,7 @@ class CheckInsViewModelTest : BaseTest() {
         }
 
         val checkIns = listOf(checkIn1, checkIn2, checkIn3, checkIn4)
-        every { checkInsRepository.allCheckIns } returns flowOf(checkIns)
+        every { checkInsRepository.checkInsWithinRetention } returns flowOf(checkIns)
 
         createInstance(deepLink = null, scope = this).apply {
             checkins.getOrAwaitValue().apply {
@@ -155,7 +155,7 @@ class CheckInsViewModelTest : BaseTest() {
             every { completed } returns false
         }
 
-        every { checkInsRepository.allCheckIns } returns flowOf(listOf(checkIn))
+        every { checkInsRepository.checkInsWithinRetention } returns flowOf(listOf(checkIn))
         every { cameraPermissionProvider.deniedPermanently } returns flowOf(true)
 
         createInstance(deepLink = null, scope = this).apply {
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/DataResetTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/DataResetTest.kt
index 71a57686eb2e2999f67071e2bdb18e99af8e9b60..742faf11606a3d64d9aaf813fb81ce1a47744d93 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/DataResetTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/DataResetTest.kt
@@ -15,6 +15,7 @@ import de.rki.coronawarnapp.eventregistration.checkins.CheckInRepository
 import de.rki.coronawarnapp.eventregistration.storage.repo.TraceLocationRepository
 import de.rki.coronawarnapp.main.CWASettings
 import de.rki.coronawarnapp.nearby.modules.detectiontracker.ExposureDetectionTracker
+import de.rki.coronawarnapp.presencetracing.warning.storage.TraceWarningRepository
 import de.rki.coronawarnapp.risk.storage.RiskLevelStorage
 import de.rki.coronawarnapp.statistics.source.StatisticsProvider
 import de.rki.coronawarnapp.storage.OnboardingSettings
@@ -52,6 +53,7 @@ internal class DataResetTest : BaseTest() {
     @MockK lateinit var onboardingSettings: OnboardingSettings
     @MockK lateinit var submissionSettings: SubmissionSettings
     @MockK lateinit var traceLocationRepository: TraceLocationRepository
+    @MockK lateinit var traceWarningRepository: TraceWarningRepository
     @MockK lateinit var checkInRepository: CheckInRepository
     @MockK lateinit var traceLocationSettings: TraceLocationSettings
 
@@ -82,7 +84,8 @@ internal class DataResetTest : BaseTest() {
         submissionSettings = submissionSettings,
         traceLocationRepository = traceLocationRepository,
         checkInRepository = checkInRepository,
-        traceLocationSettings = traceLocationSettings
+        traceLocationSettings = traceLocationSettings,
+        traceWarningRepository = traceWarningRepository
     )
 
     @Test
@@ -112,7 +115,7 @@ internal class DataResetTest : BaseTest() {
         coVerify(exactly = 1) { statisticsProvider.clear() }
 
         coVerify(exactly = 1) { bugReportingSettings.clear() }
-
+        coVerify(exactly = 1) { traceWarningRepository.clear() }
         coVerify(exactly = 1) { traceLocationRepository.deleteAllTraceLocations() }
         coVerify(exactly = 1) { checkInRepository.clear() }
     }
diff --git a/Server-Protocol-Buffer/src/main/proto/internal/pt/qr_code_poster_template.proto b/Server-Protocol-Buffer/src/main/proto/internal/pt/qr_code_poster_template.proto
index 6fdbbcdd9957131b034b0d8c5c6cecda1b1d447d..65363477ac14139f8c9a6548c21120f7ed7be883 100644
--- a/Server-Protocol-Buffer/src/main/proto/internal/pt/qr_code_poster_template.proto
+++ b/Server-Protocol-Buffer/src/main/proto/internal/pt/qr_code_poster_template.proto
@@ -36,6 +36,7 @@ message QRCodePosterTemplateIOS {
   uint32 qrCodeSideLength = 4;
 
   QRCodeTextBoxIOS descriptionTextBox = 5;
+  QRCodeTextBoxIOS addressTextBox = 6;
 
   message QRCodeTextBoxIOS {
     uint32 offsetX = 1;