diff --git a/app/build.gradle b/app/build.gradle
index 93a1c7c3f6..a7b05f11f0 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -198,33 +198,37 @@ android {
     }
 
     buildTypes {
-        debug {
-            minifyEnabled true
-            proguardFiles getDefaultProguardFile('proguard-android.txt'),
-                          'proguard/proguard-dagger.pro',
-                          'proguard/proguard-jackson.pro',
-                          'proguard/proguard-jna.pro',
-                          'proguard/proguard-sqlite.pro',
-                          'proguard/proguard-appcompat-v7.pro',
-                          'proguard/proguard-square-okhttp.pro',
-                          'proguard/proguard-square-okio.pro',
-                          'proguard/proguard-spongycastle.pro',
-                          'proguard/proguard-rounded-image-view.pro',
-                          'proguard/proguard-glide.pro',
-                          'proguard/proguard-shortcutbadger.pro',
-                          'proguard/proguard-retrofit.pro',
-                          'proguard/proguard-webrtc.pro',
-                          'proguard/proguard-klinker.pro',
-                          'proguard/proguard-retrolambda.pro',
-                          'proguard/proguard-okhttp.pro',
-                          'proguard/proguard-ez-vcard.pro',
-                          'proguard/proguard.pro'
-            testProguardFiles 'proguard/proguard-automation.pro',
-                              'proguard/proguard.cfg'
-        }
         release {
             minifyEnabled true
-            proguardFiles = buildTypes.debug.proguardFiles
+
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
+                    'proguard/proguard-dagger.pro',
+                    'proguard/proguard-jackson.pro',
+                    'proguard/proguard-jna.pro',
+                    'proguard/proguard-sqlite.pro',
+                    'proguard/proguard-appcompat-v7.pro',
+                    'proguard/proguard-square-okhttp.pro',
+                    'proguard/proguard-square-okio.pro',
+                    'proguard/proguard-spongycastle.pro',
+                    'proguard/proguard-rounded-image-view.pro',
+                    'proguard/proguard-glide.pro',
+                    'proguard/proguard-shortcutbadger.pro',
+                    'proguard/proguard-retrofit.pro',
+                    'proguard/proguard-webrtc.pro',
+                    'proguard/proguard-klinker.pro',
+                    'proguard/proguard-retrolambda.pro',
+                    'proguard/proguard-okhttp.pro',
+                    'proguard/proguard-ez-vcard.pro',
+                    'proguard/proguard.pro'
+            testProguardFiles 'proguard/proguard-automation.pro'
+        }
+        debug {
+            minifyEnabled false
+
+            proguardFiles = buildTypes.release.proguardFiles + [
+                    'proguard/proguard-debug.pro'
+            ]
+            testProguardFiles = buildTypes.release.testProguardFiles
         }
     }
 
diff --git a/app/proguard/proguard-debug.pro b/app/proguard/proguard-debug.pro
new file mode 100644
index 0000000000..0674e77454
--- /dev/null
+++ b/app/proguard/proguard-debug.pro
@@ -0,0 +1 @@
+-dontobfuscate
\ No newline at end of file
diff --git a/app/src/main/java/org/thoughtcrime/securesms/ConversationListItem.java b/app/src/main/java/org/thoughtcrime/securesms/ConversationListItem.java
index 70423ab6a4..b2ab627659 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/ConversationListItem.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/ConversationListItem.java
@@ -30,7 +30,7 @@ import android.view.View;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
-import org.thoughtcrime.securesms.components.AlertView;
+import org.thoughtcrime.securesms.components.ConversationItemAlertView;
 import org.thoughtcrime.securesms.components.AvatarImageView;
 import org.thoughtcrime.securesms.components.DeliveryStatusView;
 import org.thoughtcrime.securesms.components.FromTextView;
@@ -78,7 +78,7 @@ public class ConversationListItem extends RelativeLayout
   private TextView            dateView;
   private TextView            archivedView;
   private DeliveryStatusView  deliveryStatusIndicator;
-  private AlertView           alertView;
+  private ConversationItemAlertView alertView;
   private TextView            unreadIndicator;
   private long                lastSeen;
 
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/BubbleDrawableBuilder.java b/app/src/main/java/org/thoughtcrime/securesms/components/BubbleDrawableBuilder.java
deleted file mode 100644
index 78b6b71b0e..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/components/BubbleDrawableBuilder.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.thoughtcrime.securesms.components;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.GradientDrawable;
-import android.graphics.drawable.LayerDrawable;
-
-import network.loki.messenger.R;
-
-public class BubbleDrawableBuilder {
-  private int color;
-  private int shadowColor;
-  private boolean hasShadow = true;
-  private boolean[] corners = new boolean[]{true,true,true,true};
-
-  protected BubbleDrawableBuilder() { }
-
-  public BubbleDrawableBuilder setColor(int color) {
-    this.color = color;
-    return this;
-  }
-
-  public BubbleDrawableBuilder setShadowColor(int shadowColor) {
-    this.shadowColor = shadowColor;
-    return this;
-  }
-
-  public BubbleDrawableBuilder setHasShadow(boolean hasShadow) {
-    this.hasShadow = hasShadow;
-    return this;
-  }
-
-  public BubbleDrawableBuilder setCorners(boolean[] corners) {
-    this.corners = corners;
-    return this;
-  }
-
-  public Drawable create(Context context) {
-    final GradientDrawable bubble = new GradientDrawable();
-    final int              radius = context.getResources().getDimensionPixelSize(R.dimen.message_bubble_corner_radius);
-    final float[]          radii  = cornerBooleansToRadii(corners, radius);
-
-    bubble.setColor(color);
-    bubble.setCornerRadii(radii);
-
-    if (!hasShadow) {
-      return bubble;
-    } else {
-      final GradientDrawable shadow   = new GradientDrawable();
-      final int              distance = context.getResources().getDimensionPixelSize(R.dimen.message_bubble_shadow_distance);
-
-      shadow.setColor(shadowColor);
-      shadow.setCornerRadii(radii);
-
-      final LayerDrawable layers = new LayerDrawable(new Drawable[]{shadow, bubble});
-      layers.setLayerInset(1, 0, 0, 0, distance);
-      return layers;
-    }
-  }
-
-  private float[] cornerBooleansToRadii(boolean[] corners, int radius) {
-    if (corners == null || corners.length != 4) {
-      throw new AssertionError("there are four corners in a rectangle, silly");
-    }
-
-    float[] radii = new float[8];
-    int     i     = 0;
-    for (boolean corner : corners) {
-      radii[i] = radii[i+1] = corner ? radius : 0;
-      i += 2;
-    }
-
-    return radii;
-  }
-
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/AlertView.java b/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemAlertView.java
similarity index 83%
rename from app/src/main/java/org/thoughtcrime/securesms/components/AlertView.java
rename to app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemAlertView.java
index 5c0942bd8a..88bd1718a1 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/components/AlertView.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemAlertView.java
@@ -4,7 +4,6 @@ import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.os.Build.VERSION_CODES;
-import androidx.core.content.ContextCompat;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.ImageView;
@@ -12,24 +11,24 @@ import android.widget.LinearLayout;
 
 import network.loki.messenger.R;
 
-public class AlertView extends LinearLayout {
+public class ConversationItemAlertView extends LinearLayout {
 
-  private static final String TAG = AlertView.class.getSimpleName();
+  private static final String TAG = ConversationItemAlertView.class.getSimpleName();
 
   private ImageView approvalIndicator;
   private ImageView failedIndicator;
 
-  public AlertView(Context context) {
+  public ConversationItemAlertView(Context context) {
     this(context, null);
   }
 
-  public AlertView(Context context, AttributeSet attrs) {
+  public ConversationItemAlertView(Context context, AttributeSet attrs) {
     super(context, attrs);
     initialize(attrs);
   }
 
   @TargetApi(VERSION_CODES.HONEYCOMB)
-  public AlertView(final Context context, AttributeSet attrs, int defStyle) {
+  public ConversationItemAlertView(final Context context, AttributeSet attrs, int defStyle) {
     super(context, attrs, defStyle);
     initialize(attrs);
   }
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ExpiredBuildReminder.java b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ExpiredBuildReminder.java
deleted file mode 100644
index bb9ad20c3f..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ExpiredBuildReminder.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package org.thoughtcrime.securesms.components.reminder;
-
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import org.thoughtcrime.securesms.logging.Log;
-import android.widget.Toast;
-
-import network.loki.messenger.R;
-import org.thoughtcrime.securesms.util.Util;
-
-public class ExpiredBuildReminder extends Reminder {
-  @SuppressWarnings("unused")
-  private static final String TAG = ExpiredBuildReminder.class.getSimpleName();
-
-  public ExpiredBuildReminder(final Context context) {
-    super(context.getString(R.string.reminder_header_expired_build),
-          context.getString(R.string.reminder_header_expired_build_details));
-    setOkListener(v -> {
-      try {
-        context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + context.getPackageName())));
-      } catch (android.content.ActivityNotFoundException anfe) {
-        try {
-          context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + context.getPackageName())));
-        } catch (android.content.ActivityNotFoundException anfe2) {
-          Log.w(TAG, anfe2);
-          Toast.makeText(context, R.string.OutdatedBuildReminder_no_web_browser_installed, Toast.LENGTH_SHORT).show();
-        }
-      }
-    });
-  }
-
-  @Override
-  public boolean isDismissable() {
-    return false;
-  }
-
-  public static boolean isEligible() {
-    return Util.getDaysTillBuildExpiry() <= 0;
-  }
-
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/OutdatedBuildReminder.java b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/OutdatedBuildReminder.java
deleted file mode 100644
index ad8657b915..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/OutdatedBuildReminder.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package org.thoughtcrime.securesms.components.reminder;
-
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import org.thoughtcrime.securesms.logging.Log;
-
-import android.widget.Toast;
-
-import network.loki.messenger.R;
-import org.thoughtcrime.securesms.util.Util;
-
-public class OutdatedBuildReminder extends Reminder {
-
-  private static final String TAG = OutdatedBuildReminder.class.getSimpleName();
-
-  public OutdatedBuildReminder(final Context context) {
-    super(context.getString(R.string.reminder_header_outdated_build),
-          getPluralsText(context));
-    setOkListener(v -> {
-      try {
-        context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + context.getPackageName())));
-      } catch (ActivityNotFoundException anfe) {
-        try {
-          context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + context.getPackageName())));
-        } catch (ActivityNotFoundException anfe2) {
-          Log.w(TAG, anfe2);
-          Toast.makeText(context, R.string.OutdatedBuildReminder_no_web_browser_installed, Toast.LENGTH_LONG).show();
-        }
-      }
-    });
-  }
-
-  private static CharSequence getPluralsText(final Context context) {
-    int days = Util.getDaysTillBuildExpiry() - 1;
-    if (days == 0) {
-      return context.getString(R.string.reminder_header_outdated_build_details_today);
-    }
-    return context.getResources().getQuantityString(R.plurals.reminder_header_outdated_build_details, days, days);
-  }
-
-  @Override
-  public boolean isDismissable() {
-    return false;
-  }
-
-  public static boolean isEligible() {
-    return Util.getDaysTillBuildExpiry() <= 10;
-  }
-
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ServiceOutageReminder.java b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ServiceOutageReminder.java
deleted file mode 100644
index 5559caf6f6..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ServiceOutageReminder.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.thoughtcrime.securesms.components.reminder;
-
-import android.content.Context;
-import androidx.annotation.NonNull;
-
-import network.loki.messenger.R;
-import org.thoughtcrime.securesms.util.TextSecurePreferences;
-
-public class ServiceOutageReminder extends Reminder {
-
-  public ServiceOutageReminder(@NonNull Context context) {
-    super(null,
-          context.getString(R.string.reminder_header_service_outage_text));
-  }
-
-  public static boolean isEligible(@NonNull Context context) {
-    return TextSecurePreferences.getServiceOutage(context);
-  }
-
-  @Override
-  public boolean isDismissable() {
-    return false;
-  }
-
-  @NonNull
-  @Override
-  public Importance getImportance() {
-    return Importance.ERROR;
-  }
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java
index 77dfde63e1..ed62cbc9bf 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java
@@ -114,9 +114,7 @@ import org.thoughtcrime.securesms.components.identity.UntrustedSendDialog;
 import org.thoughtcrime.securesms.components.identity.UnverifiedBannerView;
 import org.thoughtcrime.securesms.components.identity.UnverifiedSendDialog;
 import org.thoughtcrime.securesms.components.location.SignalPlace;
-import org.thoughtcrime.securesms.components.reminder.ExpiredBuildReminder;
 import org.thoughtcrime.securesms.components.reminder.ReminderView;
-import org.thoughtcrime.securesms.components.reminder.ServiceOutageReminder;
 import org.thoughtcrime.securesms.contacts.ContactAccessor;
 import org.thoughtcrime.securesms.contacts.ContactAccessor.ContactData;
 import org.thoughtcrime.securesms.contactshare.Contact;
@@ -145,7 +143,6 @@ import org.thoughtcrime.securesms.database.model.StickerRecord;
 import org.thoughtcrime.securesms.events.ReminderUpdateEvent;
 import org.thoughtcrime.securesms.giph.ui.GiphyActivity;
 import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob;
-import org.thoughtcrime.securesms.jobs.ServiceOutageDetectionJob;
 import org.thoughtcrime.securesms.linkpreview.LinkPreview;
 import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository;
 import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil;
@@ -207,9 +204,7 @@ import org.thoughtcrime.securesms.stickers.StickerManagementActivity;
 import org.thoughtcrime.securesms.stickers.StickerPackInstallEvent;
 import org.thoughtcrime.securesms.stickers.StickerSearchRepository;
 import org.thoughtcrime.securesms.util.BitmapUtil;
-import org.thoughtcrime.securesms.util.CommunicationActions;
 import org.thoughtcrime.securesms.util.DateUtils;
-import org.thoughtcrime.securesms.util.Dialogs;
 import org.thoughtcrime.securesms.util.DynamicLanguage;
 import org.thoughtcrime.securesms.util.ExpirationUtil;
 import org.thoughtcrime.securesms.util.IdentityUtil;
@@ -1518,12 +1513,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
   protected void updateReminders(boolean seenInvite) {
     Log.i(TAG, "updateReminders(" + seenInvite + ")");
 
-    if (ExpiredBuildReminder.isEligible()) {
-      reminderView.get().showReminder(new ExpiredBuildReminder(this));
-    } else if (ServiceOutageReminder.isEligible(this)) {
-      ApplicationContext.getInstance(this).getJobManager().add(new ServiceOutageDetectionJob());
-      reminderView.get().showReminder(new ServiceOutageReminder(this));
-    } else if (reminderView.resolved()) {
+   if (reminderView.resolved()) {
       reminderView.get().hide();
     }
   }
diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java
index 5a38afeafa..79dca0dcdc 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java
@@ -59,17 +59,15 @@ import org.thoughtcrime.securesms.ConfirmIdentityDialog;
 import org.thoughtcrime.securesms.MediaPreviewActivity;
 import org.thoughtcrime.securesms.MessageDetailsActivity;
 import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
-import org.thoughtcrime.securesms.components.AlertView;
+import org.thoughtcrime.securesms.components.ConversationItemAlertView;
 import org.thoughtcrime.securesms.loki.views.MessageAudioView;
 import org.thoughtcrime.securesms.components.ConversationItemFooter;
 import org.thoughtcrime.securesms.components.ConversationItemThumbnail;
 import org.thoughtcrime.securesms.components.DocumentView;
 import org.thoughtcrime.securesms.components.LinkPreviewView;
 import org.thoughtcrime.securesms.components.QuoteView;
-import org.thoughtcrime.securesms.components.SharedContactView;
 import org.thoughtcrime.securesms.components.StickerView;
 import org.thoughtcrime.securesms.components.emoji.EmojiTextView;
-import org.thoughtcrime.securesms.contactshare.Contact;
 import org.thoughtcrime.securesms.database.AttachmentDatabase;
 import org.thoughtcrime.securesms.database.DatabaseFactory;
 import org.thoughtcrime.securesms.database.MmsDatabase;
@@ -155,7 +153,7 @@ public class ConversationItem extends TapJackingProofLinearLayout
   private   ProfilePictureView     profilePictureView;
   private   ImageView              moderatorIconImageView;
   private   ViewGroup              contactPhotoHolder;
-  private   AlertView              alertView;
+  private ConversationItemAlertView alertView;
   private   ViewGroup              container;
 
   private @NonNull  Set<MessageRecord>              batchSelected = new HashSet<>();
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java
index b0d7256bdd..0c313e71ab 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java
@@ -51,6 +51,7 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
 import org.session.libsignal.service.loki.api.opengroups.PublicChat;
 
 import java.io.File;
+import java.util.Arrays;
 
 public class SQLCipherOpenHelper extends SQLiteOpenHelper {
 
@@ -95,8 +96,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
   private static final int lokiV16                          = 37;
   private static final int lokiV17                          = 38;
   private static final int lokiV18_CLEAR_BG_POLL_JOBS       = 39;
+  private static final int lokiV19_OLD_CODE_CLEANUP         = 40; //TODO Change back to 40 when the refactoring is over.
 
-  private static final int    DATABASE_VERSION = lokiV18_CLEAR_BG_POLL_JOBS; // Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes
+  private static final int    DATABASE_VERSION = lokiV19_OLD_CODE_CLEANUP; // Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes
   private static final String DATABASE_NAME    = "signal.db";
 
   private final Context        context;
@@ -651,6 +653,18 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
         db.execSQL("DELETE FROM constraint_spec WHERE factory_key = 'BackgroundPollJob'");
       }
 
+      if (oldVersion < lokiV19_OLD_CODE_CLEANUP) {
+        // Many classes were removed. We need to update D structure and data to match the code changes.
+
+        String[] deletedJobKeys = {
+                "ServiceOutageDetectionJob",
+        };
+        for (String jobKey : deletedJobKeys) {
+          db.execSQL("DELETE FROM job_spec WHERE factory_key = ?", new String[]{jobKey});
+          db.execSQL("DELETE FROM constraint_spec WHERE factory_key = ?", new String[]{jobKey});
+        }
+      }
+
       db.setTransactionSuccessful();
     } finally {
       db.endTransaction();
diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java
index b6c05d95ed..df9459cc8d 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java
@@ -37,7 +37,6 @@ import org.thoughtcrime.securesms.jobs.RotateProfileKeyJob;
 import org.thoughtcrime.securesms.jobs.RotateSignedPreKeyJob;
 import org.thoughtcrime.securesms.jobs.SendDeliveryReceiptJob;
 import org.thoughtcrime.securesms.jobs.SendReadReceiptJob;
-import org.thoughtcrime.securesms.jobs.ServiceOutageDetectionJob;
 import org.thoughtcrime.securesms.jobs.SmsReceiveJob;
 import org.thoughtcrime.securesms.jobs.SmsSendJob;
 import org.thoughtcrime.securesms.jobs.SmsSentJob;
@@ -94,7 +93,6 @@ public class WorkManagerFactoryMappings {
     put(RotateSignedPreKeyJob.class.getName(), RotateSignedPreKeyJob.KEY);
     put(SendDeliveryReceiptJob.class.getName(), SendDeliveryReceiptJob.KEY);
     put(SendReadReceiptJob.class.getName(), SendReadReceiptJob.KEY);
-    put(ServiceOutageDetectionJob.class.getName(), ServiceOutageDetectionJob.KEY);
     put(SessionRequestMessageSendJob.class.getName(), SessionRequestMessageSendJob.KEY);
     put(SmsReceiveJob.class.getName(), SmsReceiveJob.KEY);
     put(SmsSendJob.class.getName(), SmsSendJob.KEY);
diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java
index e6f63503df..4af3c467b2 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java
@@ -69,7 +69,6 @@ public final class JobManagerFactories {
       put(RotateSignedPreKeyJob.KEY,                 new RotateSignedPreKeyJob.Factory());
       put(SendDeliveryReceiptJob.KEY,                new SendDeliveryReceiptJob.Factory());
       put(SendReadReceiptJob.KEY,                    new SendReadReceiptJob.Factory());
-      put(ServiceOutageDetectionJob.KEY,             new ServiceOutageDetectionJob.Factory());
       put(SessionRequestMessageSendJob.KEY,          new SessionRequestMessageSendJob.Factory());
       put(SmsReceiveJob.KEY,                         new SmsReceiveJob.Factory());
       put(SmsSendJob.KEY,                            new SmsSendJob.Factory());
diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java
index 26b0cf7d3e..d24964f526 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java
@@ -86,11 +86,6 @@ public abstract class PushSendJob extends SendJob {
   public void onRetry() {
     super.onRetry();
     Log.i(TAG, "onRetry()");
-
-    if (getRunAttempt() > 1) {
-      Log.i(TAG, "Scheduling service outage detection job.");
-      ApplicationContext.getInstance(context).getJobManager().add(new ServiceOutageDetectionJob());
-    }
   }
 
   protected Optional<byte[]> getProfileKey(@NonNull Recipient recipient) {
diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendJob.java
index 5c0b6b480f..c755e2443c 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendJob.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendJob.java
@@ -3,8 +3,6 @@ package org.thoughtcrime.securesms.jobs;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import network.loki.messenger.BuildConfig;
-import org.thoughtcrime.securesms.TextSecureExpiredException;
 import org.thoughtcrime.securesms.attachments.Attachment;
 import org.thoughtcrime.securesms.database.AttachmentDatabase;
 import org.thoughtcrime.securesms.database.DatabaseFactory;
@@ -16,7 +14,6 @@ import org.thoughtcrime.securesms.mms.MediaStream;
 import org.thoughtcrime.securesms.mms.MmsException;
 import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
 import org.thoughtcrime.securesms.util.MediaUtil;
-import org.thoughtcrime.securesms.util.Util;
 
 import java.io.IOException;
 import java.util.LinkedList;
@@ -33,12 +30,6 @@ public abstract class SendJob extends BaseJob {
 
   @Override
   public final void onRun() throws Exception {
-    if (Util.getDaysTillBuildExpiry() <= 0) {
-      throw new TextSecureExpiredException(String.format("TextSecure expired (build %d, now %d)",
-                                                         BuildConfig.BUILD_TIMESTAMP,
-                                                         System.currentTimeMillis()));
-    }
-
     Log.i(TAG, "Starting message send attempt");
     onSend();
     Log.i(TAG, "Message send completed");
diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ServiceOutageDetectionJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/ServiceOutageDetectionJob.java
deleted file mode 100644
index 4669365a97..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ServiceOutageDetectionJob.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package org.thoughtcrime.securesms.jobs;
-
-import androidx.annotation.NonNull;
-
-import org.greenrobot.eventbus.EventBus;
-import org.thoughtcrime.securesms.events.ReminderUpdateEvent;
-import org.thoughtcrime.securesms.jobmanager.Data;
-import org.thoughtcrime.securesms.jobmanager.Job;
-import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
-import org.thoughtcrime.securesms.logging.Log;
-import org.thoughtcrime.securesms.transport.RetryLaterException;
-import org.thoughtcrime.securesms.util.TextSecurePreferences;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-import network.loki.messenger.BuildConfig;
-
-public class ServiceOutageDetectionJob extends BaseJob {
-
-  public static final String KEY = "ServiceOutageDetectionJob";
-
-  private static final String TAG = ServiceOutageDetectionJob.class.getSimpleName();
-
-  private static final String IP_SUCCESS = "127.0.0.1";
-  private static final String IP_FAILURE = "127.0.0.2";
-  private static final long   CHECK_TIME = 1000 * 60;
-
-  public ServiceOutageDetectionJob() {
-    this(new Job.Parameters.Builder()
-                           .setQueue("ServiceOutageDetectionJob")
-                           .addConstraint(NetworkConstraint.KEY)
-                           .setMaxAttempts(3)
-                           .setMaxInstances(1)
-                           .build());
-  }
-
-  private ServiceOutageDetectionJob(@NonNull Job.Parameters parameters) {
-    super(parameters);
-  }
-
-  @Override
-  public @NonNull Data serialize() {
-    return Data.EMPTY;
-  }
-
-  @Override
-  public @NonNull String getFactoryKey() {
-    return KEY;
-  }
-
-  @Override
-  public void onRun() throws RetryLaterException {
-    Log.i(TAG, "onRun()");
-
-    long timeSinceLastCheck = System.currentTimeMillis() - TextSecurePreferences.getLastOutageCheckTime(context);
-    if (timeSinceLastCheck < CHECK_TIME) {
-      Log.w(TAG, "Skipping service outage check. Too soon.");
-      return;
-    }
-
-    try {
-      InetAddress address = InetAddress.getByName(BuildConfig.SIGNAL_SERVICE_STATUS_URL);
-      Log.i(TAG, "Received outage check address: " + address.getHostAddress());
-
-      if (IP_SUCCESS.equals(address.getHostAddress())) {
-        Log.i(TAG, "Service is available.");
-        TextSecurePreferences.setServiceOutage(context, false);
-      } else if (IP_FAILURE.equals(address.getHostAddress())) {
-        Log.w(TAG, "Service is down.");
-        TextSecurePreferences.setServiceOutage(context, true);
-      } else {
-        Log.w(TAG, "Service status check returned an unrecognized IP address. Could be a weird network state. Prompting retry.");
-        throw new RetryLaterException(new Exception("Unrecognized service outage IP address."));
-      }
-
-      TextSecurePreferences.setLastOutageCheckTime(context, System.currentTimeMillis());
-      EventBus.getDefault().post(new ReminderUpdateEvent());
-    } catch (UnknownHostException e) {
-      throw new RetryLaterException(e);
-    }
-  }
-
-  @Override
-  public boolean onShouldRetry(@NonNull Exception e) {
-    return e instanceof RetryLaterException;
-  }
-
-  @Override
-  public void onCanceled() {
-    Log.i(TAG, "Service status check could not complete. Assuming success to avoid false positives due to bad network.");
-    TextSecurePreferences.setServiceOutage(context, false);
-    TextSecurePreferences.setLastOutageCheckTime(context, System.currentTimeMillis());
-    EventBus.getDefault().post(new ReminderUpdateEvent());
-  }
-
-  public static final class Factory implements Job.Factory<ServiceOutageDetectionJob> {
-    @Override
-    public @NonNull ServiceOutageDetectionJob create(@NonNull Parameters parameters, @NonNull Data data) {
-      return new ServiceOutageDetectionJob(parameters);
-    }
-  }
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java
index 055d828514..c48511040f 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java
@@ -162,9 +162,6 @@ public class TextSecurePreferences {
   private static final String REGISTRATION_LOCK_LAST_REMINDER_TIME     = "pref_registration_lock_last_reminder_time";
   private static final String REGISTRATION_LOCK_NEXT_REMINDER_INTERVAL = "pref_registration_lock_next_reminder_interval";
 
-  private static final String SERVICE_OUTAGE         = "pref_service_outage";
-  private static final String LAST_OUTAGE_CHECK_TIME = "pref_last_outage_check_time";
-
   private static final String LAST_FULL_CONTACT_SYNC_TIME = "pref_last_full_contact_sync_time";
   private static final String NEEDS_FULL_CONTACT_SYNC     = "pref_needs_full_contact_sync";
 
@@ -1079,22 +1076,6 @@ public class TextSecurePreferences {
                                   new HashSet<>(Arrays.asList(context.getResources().getStringArray(defaultValuesRes))));
   }
 
-  public static void setLastOutageCheckTime(Context context, long timestamp) {
-    setLongPreference(context, LAST_OUTAGE_CHECK_TIME, timestamp);
-  }
-
-  public static long getLastOutageCheckTime(Context context) {
-    return getLongPreference(context, LAST_OUTAGE_CHECK_TIME, 0);
-  }
-
-  public static void setServiceOutage(Context context, boolean isOutage) {
-    setBooleanPreference(context, SERVICE_OUTAGE, isOutage);
-  }
-
-  public static boolean getServiceOutage(Context context) {
-    return getBooleanPreference(context, SERVICE_OUTAGE, false);
-  }
-
   public static long getLastFullContactSyncTime(Context context) {
     return getLongPreference(context, LAST_FULL_CONTACT_SYNC_TIME, 0);
   }
diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/Util.java b/app/src/main/java/org/thoughtcrime/securesms/util/Util.java
index 45e034d098..01dcb02a1b 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/util/Util.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/util/Util.java
@@ -371,11 +371,6 @@ public class Util {
     return new SecureRandom();
   }
 
-  public static int getDaysTillBuildExpiry() {
-    int age = (int) TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis() - BuildConfig.BUILD_TIMESTAMP);
-    return 90 - age;
-  }
-
   @TargetApi(VERSION_CODES.LOLLIPOP)
   public static boolean isMmsCapable(Context context) {
     return (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) || OutgoingLegacyMmsConnection.isConnectionPossible(context);
diff --git a/app/src/main/res/layout/conversation_item_received.xml b/app/src/main/res/layout/conversation_item_received.xml
index 2414ec06a4..f0c853828c 100644
--- a/app/src/main/res/layout/conversation_item_received.xml
+++ b/app/src/main/res/layout/conversation_item_received.xml
@@ -202,7 +202,7 @@
 
         </LinearLayout>
 
-        <org.thoughtcrime.securesms.components.AlertView
+        <org.thoughtcrime.securesms.components.ConversationItemAlertView
             android:id="@+id/indicators_parent"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
diff --git a/app/src/main/res/layout/conversation_item_sent.xml b/app/src/main/res/layout/conversation_item_sent.xml
index 7ec8b58e2a..9dc10706b1 100644
--- a/app/src/main/res/layout/conversation_item_sent.xml
+++ b/app/src/main/res/layout/conversation_item_sent.xml
@@ -155,7 +155,7 @@
 
         </LinearLayout>
 
-        <org.thoughtcrime.securesms.components.AlertView
+        <org.thoughtcrime.securesms.components.ConversationItemAlertView
             android:id="@+id/indicators_parent"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
diff --git a/app/src/main/res/layout/conversation_list_item_view.xml b/app/src/main/res/layout/conversation_list_item_view.xml
index 75dde68581..9bcd7db0da 100644
--- a/app/src/main/res/layout/conversation_list_item_view.xml
+++ b/app/src/main/res/layout/conversation_list_item_view.xml
@@ -68,7 +68,7 @@
                   android:layout_marginBottom="2dp"
                   android:drawablePadding="5dp"/>
 
-        <org.thoughtcrime.securesms.components.AlertView
+        <org.thoughtcrime.securesms.components.ConversationItemAlertView
                 android:id="@+id/indicators_parent"
                 android:layout_width="18dp"
                 android:layout_height="18dp"