]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blobdiff - app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java
First wrong button text in View Headers in night theme. https://redmine.stoutner...
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / activities / MainWebViewActivity.java
diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java
deleted file mode 100644 (file)
index 1595f4a..0000000
+++ /dev/null
@@ -1,6482 +0,0 @@
-/*
- * Copyright © 2015-2020 Soren Stoutner <soren@stoutner.com>.
- *
- * Download cookie code contributed 2017 Hendrik Knackstedt.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
- *
- * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
- *
- * Privacy Browser is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Privacy Browser is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package com.stoutner.privacybrowser.activities;
-
-import android.Manifest;
-import android.annotation.SuppressLint;
-import android.app.Activity;
-import android.app.Dialog;
-import android.app.DownloadManager;
-import android.app.SearchManager;
-import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
-import android.content.ClipData;
-import android.content.ClipboardManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Typeface;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.net.http.SslCertificate;
-import android.net.http.SslError;
-import android.os.AsyncTask;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.preference.PreferenceManager;
-import android.print.PrintDocumentAdapter;
-import android.print.PrintManager;
-import android.text.Editable;
-import android.text.Spanned;
-import android.text.TextWatcher;
-import android.text.style.ForegroundColorSpan;
-import android.util.Patterns;
-import android.util.TypedValue;
-import android.view.ContextMenu;
-import android.view.GestureDetector;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.inputmethod.InputMethodManager;
-import android.webkit.CookieManager;
-import android.webkit.HttpAuthHandler;
-import android.webkit.SslErrorHandler;
-import android.webkit.ValueCallback;
-import android.webkit.WebBackForwardList;
-import android.webkit.WebChromeClient;
-import android.webkit.WebResourceResponse;
-import android.webkit.WebSettings;
-import android.webkit.WebStorage;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-import android.webkit.WebViewDatabase;
-import android.widget.ArrayAdapter;
-import android.widget.CursorAdapter;
-import android.widget.EditText;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.ProgressBar;
-import android.widget.RadioButton;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.ActionBar;
-import androidx.appcompat.app.ActionBarDrawerToggle;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.appcompat.app.AppCompatDelegate;
-import androidx.appcompat.widget.Toolbar;
-import androidx.coordinatorlayout.widget.CoordinatorLayout;
-import androidx.core.app.ActivityCompat;
-import androidx.core.content.ContextCompat;
-import androidx.core.content.FileProvider;
-import androidx.core.content.res.ResourcesCompat;
-import androidx.core.view.GravityCompat;
-import androidx.drawerlayout.widget.DrawerLayout;
-import androidx.fragment.app.DialogFragment;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-import androidx.viewpager.widget.ViewPager;
-import androidx.webkit.WebSettingsCompat;
-import androidx.webkit.WebViewFeature;
-
-import com.google.android.material.appbar.AppBarLayout;
-import com.google.android.material.floatingactionbutton.FloatingActionButton;
-import com.google.android.material.navigation.NavigationView;
-import com.google.android.material.snackbar.Snackbar;
-import com.google.android.material.tabs.TabLayout;
-
-import com.stoutner.privacybrowser.BuildConfig;
-import com.stoutner.privacybrowser.R;
-import com.stoutner.privacybrowser.adapters.WebViewPagerAdapter;
-import com.stoutner.privacybrowser.asynctasks.GetHostIpAddresses;
-import com.stoutner.privacybrowser.asynctasks.PopulateBlocklists;
-import com.stoutner.privacybrowser.asynctasks.PrepareSaveDialog;
-import com.stoutner.privacybrowser.asynctasks.SaveUrl;
-import com.stoutner.privacybrowser.asynctasks.SaveWebpageImage;
-import com.stoutner.privacybrowser.dialogs.AdConsentDialog;
-import com.stoutner.privacybrowser.dialogs.CreateBookmarkDialog;
-import com.stoutner.privacybrowser.dialogs.CreateBookmarkFolderDialog;
-import com.stoutner.privacybrowser.dialogs.CreateHomeScreenShortcutDialog;
-import com.stoutner.privacybrowser.dialogs.EditBookmarkFolderDialog;
-import com.stoutner.privacybrowser.dialogs.FontSizeDialog;
-import com.stoutner.privacybrowser.dialogs.HttpAuthenticationDialog;
-import com.stoutner.privacybrowser.dialogs.OpenDialog;
-import com.stoutner.privacybrowser.dialogs.ProxyNotInstalledDialog;
-import com.stoutner.privacybrowser.dialogs.PinnedMismatchDialog;
-import com.stoutner.privacybrowser.dialogs.SaveWebpageDialog;
-import com.stoutner.privacybrowser.dialogs.SslCertificateErrorDialog;
-import com.stoutner.privacybrowser.dialogs.StoragePermissionDialog;
-import com.stoutner.privacybrowser.dialogs.UrlHistoryDialog;
-import com.stoutner.privacybrowser.dialogs.ViewSslCertificateDialog;
-import com.stoutner.privacybrowser.dialogs.WaitingForProxyDialog;
-import com.stoutner.privacybrowser.fragments.WebViewTabFragment;
-import com.stoutner.privacybrowser.helpers.AdHelper;
-import com.stoutner.privacybrowser.helpers.BlocklistHelper;
-import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper;
-import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper;
-import com.stoutner.privacybrowser.helpers.FileNameHelper;
-import com.stoutner.privacybrowser.helpers.ProxyHelper;
-import com.stoutner.privacybrowser.views.NestedScrollWebView;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-public class MainWebViewActivity extends AppCompatActivity implements CreateBookmarkDialog.CreateBookmarkListener, CreateBookmarkFolderDialog.CreateBookmarkFolderListener,
-        EditBookmarkFolderDialog.EditBookmarkFolderListener, FontSizeDialog.UpdateFontSizeListener, NavigationView.OnNavigationItemSelectedListener, OpenDialog.OpenListener,
-        PinnedMismatchDialog.PinnedMismatchListener, PopulateBlocklists.PopulateBlocklistsListener, SaveWebpageDialog.SaveWebpageListener, StoragePermissionDialog.StoragePermissionDialogListener,
-        UrlHistoryDialog.NavigateHistoryListener, WebViewTabFragment.NewTabListener {
-
-    // The executor service handles background tasks.  It is accessed from `ViewSourceActivity`.
-    public static ExecutorService executorService = Executors.newFixedThreadPool(4);
-
-    // `orbotStatus` is public static so it can be accessed from `OrbotProxyHelper`.  It is also used in `onCreate()`, `onResume()`, and `applyProxy()`.
-    public static String orbotStatus = "unknown";
-
-    // The WebView pager adapter is accessed from `HttpAuthenticationDialog`, `PinnedMismatchDialog`, and `SslCertificateErrorDialog`.  It is also used in `onCreate()`, `onResume()`, and `addTab()`.
-    public static WebViewPagerAdapter webViewPagerAdapter;
-
-    // `restartFromBookmarksActivity` is public static so it can be accessed from `BookmarksActivity`.  It is also used in `onRestart()`.
-    public static boolean restartFromBookmarksActivity;
-
-    // `currentBookmarksFolder` is public static so it can be accessed from `BookmarksActivity`.  It is also used in `onCreate()`, `onBackPressed()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`,
-    // `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, and `loadBookmarksFolder()`.
-    public static String currentBookmarksFolder;
-
-    // The user agent constants are public static so they can be accessed from `SettingsFragment`, `DomainsActivity`, and `DomainSettingsFragment`.
-    public final static int UNRECOGNIZED_USER_AGENT = -1;
-    public final static int SETTINGS_WEBVIEW_DEFAULT_USER_AGENT = 1;
-    public final static int SETTINGS_CUSTOM_USER_AGENT = 12;
-    public final static int DOMAINS_SYSTEM_DEFAULT_USER_AGENT = 0;
-    public final static int DOMAINS_WEBVIEW_DEFAULT_USER_AGENT = 2;
-    public final static int DOMAINS_CUSTOM_USER_AGENT = 13;
-
-    // Start activity for result request codes.  The public static entries are accessed from `OpenDialog()` and `SaveWebpageDialog()`.
-    public final static int BROWSE_OPEN_REQUEST_CODE = 0;
-    public final static int BROWSE_SAVE_WEBPAGE_REQUEST_CODE = 1;
-    private final int BROWSE_FILE_UPLOAD_REQUEST_CODE = 2;
-
-    // The proxy mode is public static so it can be accessed from `ProxyHelper()`.
-    // It is also used in `onRestart()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, `applyAppSettings()`, and `applyProxy()`.
-    // It will be updated in `applyAppSettings()`, but it needs to be initialized here or the first run of `onPrepareOptionsMenu()` crashes.
-    public static String proxyMode = ProxyHelper.NONE;
-
-    // Define the saved instance state constants.
-    private final String SAVED_STATE_ARRAY_LIST = "saved_state_array_list";
-    private final String SAVED_NESTED_SCROLL_WEBVIEW_STATE_ARRAY_LIST = "saved_nested_scroll_webview_state_array_list";
-    private final String SAVED_TAB_POSITION = "saved_tab_position";
-    private final String PROXY_MODE = "proxy_mode";
-
-    // Define the saved instance state variables.
-    private ArrayList<Bundle> savedStateArrayList;
-    private ArrayList<Bundle> savedNestedScrollWebViewStateArrayList;
-    private int savedTabPosition;
-    private String savedProxyMode;
-
-    // Define the class variables.
-    @SuppressWarnings("rawtypes")
-    AsyncTask populateBlocklists;
-
-    // The current WebView is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, `onCreateContextMenu()`, `findPreviousOnPage()`,
-    // `findNextOnPage()`, `closeFindOnPage()`, `loadUrlFromTextBox()`, `onSslMismatchBack()`, `applyProxy()`, and `applyDomainSettings()`.
-    private NestedScrollWebView currentWebView;
-
-    // `customHeader` is used in `onCreate()`, `onOptionsItemSelected()`, `onCreateContextMenu()`, and `loadUrl()`.
-    private final Map<String, String> customHeaders = new HashMap<>();
-
-    // The search URL is set in `applyAppSettings()` and used in `onNewIntent()`, `loadUrlFromTextBox()`, `initializeApp()`, and `initializeWebView()`.
-    private String searchURL;
-
-    // The options menu is set in `onCreateOptionsMenu()` and used in `onOptionsItemSelected()`, `updatePrivacyIcons()`, and `initializeWebView()`.
-    private Menu optionsMenu;
-
-    // The blocklists are populated in `finishedPopulatingBlocklists()` and accessed from `initializeWebView()`.
-    private ArrayList<List<String[]>> easyList;
-    private ArrayList<List<String[]>> easyPrivacy;
-    private ArrayList<List<String[]>> fanboysAnnoyanceList;
-    private ArrayList<List<String[]>> fanboysSocialList;
-    private ArrayList<List<String[]>> ultraList;
-    private ArrayList<List<String[]>> ultraPrivacy;
-
-    // `webViewDefaultUserAgent` is used in `onCreate()` and `onPrepareOptionsMenu()`.
-    private String webViewDefaultUserAgent;
-
-    // The incognito mode is set in `applyAppSettings()` and used in `initializeWebView()`.
-    private boolean incognitoModeEnabled;
-
-    // The full screen browsing mode tracker is set it `applyAppSettings()` and used in `initializeWebView()`.
-    private boolean fullScreenBrowsingModeEnabled;
-
-    // `inFullScreenBrowsingMode` is used in `onCreate()`, `onConfigurationChanged()`, and `applyAppSettings()`.
-    private boolean inFullScreenBrowsingMode;
-
-    // The app bar trackers are set in `applyAppSettings()` and used in `initializeWebView()`.
-    private boolean hideAppBar;
-    private boolean scrollAppBar;
-
-    // The loading new intent tracker is set in `onNewIntent()` and used in `setCurrentWebView()`.
-    private boolean loadingNewIntent;
-
-    // `reapplyDomainSettingsOnRestart` is used in `onCreate()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, and `onAddDomain()`, .
-    private boolean reapplyDomainSettingsOnRestart;
-
-    // `reapplyAppSettingsOnRestart` is used in `onNavigationItemSelected()` and `onRestart()`.
-    private boolean reapplyAppSettingsOnRestart;
-
-    // `displayingFullScreenVideo` is used in `onCreate()` and `onResume()`.
-    private boolean displayingFullScreenVideo;
-
-    // `orbotStatusBroadcastReceiver` is used in `onCreate()` and `onDestroy()`.
-    private BroadcastReceiver orbotStatusBroadcastReceiver;
-
-    // The waiting for proxy boolean is used in `onResume()`, `initializeApp()` and `applyProxy()`.
-    private boolean waitingForProxy = false;
-
-    // The action bar drawer toggle is initialized in `onCreate()` and used in `onResume()`.
-    private ActionBarDrawerToggle actionBarDrawerToggle;
-
-    // The color spans are used in `onCreate()` and `highlightUrlText()`.
-    private ForegroundColorSpan redColorSpan;
-    private ForegroundColorSpan initialGrayColorSpan;
-    private ForegroundColorSpan finalGrayColorSpan;
-
-    // `bookmarksDatabaseHelper` is used in `onCreate()`, `onDestroy`, `onOptionsItemSelected()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`,
-    // and `loadBookmarksFolder()`.
-    private BookmarksDatabaseHelper bookmarksDatabaseHelper;
-
-    // `bookmarksCursor` is used in `onDestroy()`, `onOptionsItemSelected()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, and `loadBookmarksFolder()`.
-    private Cursor bookmarksCursor;
-
-    // `bookmarksCursorAdapter` is used in `onCreateBookmark()`, `onCreateBookmarkFolder()` `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, and `loadBookmarksFolder()`.
-    private CursorAdapter bookmarksCursorAdapter;
-
-    // `oldFolderNameString` is used in `onCreate()` and `onSaveEditBookmarkFolder()`.
-    private String oldFolderNameString;
-
-    // `fileChooserCallback` is used in `onCreate()` and `onActivityResult()`.
-    private ValueCallback<Uri[]> fileChooserCallback;
-
-    // The default progress view offsets are set in `onCreate()` and used in `initializeWebView()`.
-    private int appBarHeight;
-    private int defaultProgressViewStartOffset;
-    private int defaultProgressViewEndOffset;
-
-    // The URL sanitizers are set in `applyAppSettings()` and used in `sanitizeUrl()`.
-    private boolean sanitizeGoogleAnalytics;
-    private boolean sanitizeFacebookClickIds;
-    private boolean sanitizeTwitterAmpRedirects;
-
-    // The file path strings are used in `onSaveWebpage()` and `onRequestPermissionResult()`
-    private String openFilePath;
-    private String saveWebpageUrl;
-    private String saveWebpageFilePath;
-
-    // Declare the class views.
-    private DrawerLayout drawerLayout;
-    private AppBarLayout appBarLayout;
-    private Toolbar toolbar;
-    private LinearLayout findOnPageLinearLayout;
-    private LinearLayout tabsLinearLayout;
-    private TabLayout tabLayout;
-    private SwipeRefreshLayout swipeRefreshLayout;
-    private ViewPager webViewPager;
-
-    @Override
-    // Remove the warning about needing to override `performClick()` when using an `OnTouchListener` with `WebView`.
-    @SuppressLint("ClickableViewAccessibility")
-    protected void onCreate(Bundle savedInstanceState) {
-        // Run the default commands.
-        super.onCreate(savedInstanceState);
-
-        // Check to see if the activity has been restarted.
-        if (savedInstanceState != null) {
-            // Store the saved instance state variables.
-            savedStateArrayList = savedInstanceState.getParcelableArrayList(SAVED_STATE_ARRAY_LIST);
-            savedNestedScrollWebViewStateArrayList = savedInstanceState.getParcelableArrayList(SAVED_NESTED_SCROLL_WEBVIEW_STATE_ARRAY_LIST);
-            savedTabPosition = savedInstanceState.getInt(SAVED_TAB_POSITION);
-            savedProxyMode = savedInstanceState.getString(PROXY_MODE);
-        }
-
-        // Initialize the default preference values the first time the program is run.  `false` keeps this command from resetting any current preferences back to default.
-        PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
-
-        // Get a handle for the shared preferences.
-        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
-
-        // Get the screenshot preference.
-        String appTheme = sharedPreferences.getString("app_theme", getString(R.string.app_theme_default_value));
-        boolean allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false);
-
-        // Get the theme entry values string array.
-        String[] appThemeEntryValuesStringArray = getResources().getStringArray(R.array.app_theme_entry_values);
-
-        // Set the app theme according to the preference.  A switch statement cannot be used because the theme entry values string array is not a compile time constant.
-        if (appTheme.equals(appThemeEntryValuesStringArray[1])) {  // The light theme is selected.
-            // Apply the light theme.
-            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
-        } else if (appTheme.equals(appThemeEntryValuesStringArray[2])) {  // The dark theme is selected.
-            // Apply the dark theme.
-            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
-        } else {  // The system default theme is selected.
-            if (Build.VERSION.SDK_INT >= 28) {  // The system default theme is supported.
-                // Follow the system default theme.
-                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
-            } else {  // The system default theme is not supported.
-                // Follow the battery saver mode.
-                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY);
-            }
-        }
-
-        // Disable screenshots if not allowed.
-        if (!allowScreenshots) {
-            getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
-        }
-
-        // Enable the drawing of the entire webpage.  This makes it possible to save a website image.  This must be done before anything else happens with the WebView.
-        if (Build.VERSION.SDK_INT >= 21) {
-            WebView.enableSlowWholeDocumentDraw();
-        }
-
-        // Set the theme.
-        setTheme(R.style.PrivacyBrowser);
-
-        // Set the content view.
-        setContentView(R.layout.main_framelayout);
-
-        // Get handles for the views.
-        drawerLayout = findViewById(R.id.drawerlayout);
-        appBarLayout = findViewById(R.id.appbar_layout);
-        toolbar = findViewById(R.id.toolbar);
-        findOnPageLinearLayout = findViewById(R.id.find_on_page_linearlayout);
-        tabsLinearLayout = findViewById(R.id.tabs_linearlayout);
-        tabLayout = findViewById(R.id.tablayout);
-        swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
-        webViewPager = findViewById(R.id.webviewpager);
-
-        // Get a handle for the app compat delegate.
-        AppCompatDelegate appCompatDelegate = getDelegate();
-
-        // Set the support action bar.
-        appCompatDelegate.setSupportActionBar(toolbar);
-
-        // Get a handle for the action bar.
-        ActionBar actionBar = appCompatDelegate.getSupportActionBar();
-
-        // This is needed to get rid of the Android Studio warning that the action bar might be null.
-        assert actionBar != null;
-
-        // Add the custom layout, which shows the URL text bar.
-        actionBar.setCustomView(R.layout.url_app_bar);
-        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
-
-        // Create the hamburger icon at the start of the AppBar.
-        actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open_navigation_drawer, R.string.close_navigation_drawer);
-
-        // Initially disable the sliding drawers.  They will be enabled once the blocklists are loaded.
-        drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
-
-        // Initialize the web view pager adapter.
-        webViewPagerAdapter = new WebViewPagerAdapter(getSupportFragmentManager());
-
-        // Set the pager adapter on the web view pager.
-        webViewPager.setAdapter(webViewPagerAdapter);
-
-        // Store up to 100 tabs in memory.
-        webViewPager.setOffscreenPageLimit(100);
-
-        // Initialize the app.
-        initializeApp();
-
-        // Apply the app settings from the shared preferences.
-        applyAppSettings();
-
-        // Populate the blocklists.
-        populateBlocklists = new PopulateBlocklists(this, this).execute();
-    }
-
-    @Override
-    protected void onNewIntent(Intent intent) {
-        // Run the default commands.
-        super.onNewIntent(intent);
-
-        // Replace the intent that started the app with this one.
-        setIntent(intent);
-
-        // Check to see if the app is being restarted from a saved state.
-        if (savedStateArrayList == null || savedStateArrayList.size() == 0) {  // The activity is not being restarted from a saved state.
-            // Get the information from the intent.
-            String intentAction = intent.getAction();
-            Uri intentUriData = intent.getData();
-            String intentStringExtra = intent.getStringExtra(Intent.EXTRA_TEXT);
-
-            // Determine if this is a web search.
-            boolean isWebSearch = ((intentAction != null) && intentAction.equals(Intent.ACTION_WEB_SEARCH));
-
-            // Only process the URI if it contains data or it is a web search.  If the user pressed the desktop icon after the app was already running the URI will be null.
-            if (intentUriData != null || intentStringExtra != null || isWebSearch) {
-                // Get the shared preferences.
-                SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
-
-                // Create a URL string.
-                String url;
-
-                // If the intent action is a web search, perform the search.
-                if (isWebSearch) {  // The intent is a web search.
-                    // Create an encoded URL string.
-                    String encodedUrlString;
-
-                    // Sanitize the search input and convert it to a search.
-                    try {
-                        encodedUrlString = URLEncoder.encode(intent.getStringExtra(SearchManager.QUERY), "UTF-8");
-                    } catch (UnsupportedEncodingException exception) {
-                        encodedUrlString = "";
-                    }
-
-                    // Add the base search URL.
-                    url = searchURL + encodedUrlString;
-                } else if (intentUriData != null) {  // The intent contains a URL formatted as a URI.
-                    // Set the intent data as the URL.
-                    url = intentUriData.toString();
-                } else {  // The intent contains a string, which might be a URL.
-                    // Set the intent string as the URL.
-                    url = intentStringExtra;
-                }
-
-                // Add a new tab if specified in the preferences.
-                if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) {  // Load the URL in a new tab.
-                    // Set the loading new intent flag.
-                    loadingNewIntent = true;
-
-                    // Add a new tab.
-                    addNewTab(url, true);
-                } else {  // Load the URL in the current tab.
-                    // Make it so.
-                    loadUrl(currentWebView, url);
-                }
-
-                // Close the navigation drawer if it is open.
-                if (drawerLayout.isDrawerVisible(GravityCompat.START)) {
-                    drawerLayout.closeDrawer(GravityCompat.START);
-                }
-
-                // Close the bookmarks drawer if it is open.
-                if (drawerLayout.isDrawerVisible(GravityCompat.END)) {
-                    drawerLayout.closeDrawer(GravityCompat.END);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void onRestart() {
-        // Run the default commands.
-        super.onRestart();
-
-        // Apply the app settings if returning from the Settings activity.
-        if (reapplyAppSettingsOnRestart) {
-            // Reset the reapply app settings on restart tracker.
-            reapplyAppSettingsOnRestart = false;
-
-            // Apply the app settings.
-            applyAppSettings();
-        }
-
-        // Apply the domain settings if returning from the settings or domains activity.
-        if (reapplyDomainSettingsOnRestart) {
-            // Reset the reapply domain settings on restart tracker.
-            reapplyDomainSettingsOnRestart = false;
-
-            // Reapply the domain settings for each tab.
-            for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
-                // Get the WebView tab fragment.
-                WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
-
-                // Get the fragment view.
-                View fragmentView = webViewTabFragment.getView();
-
-                // Only reload the WebViews if they exist.
-                if (fragmentView != null) {
-                    // Get the nested scroll WebView from the tab fragment.
-                    NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
-
-                    // Reset the current domain name so the domain settings will be reapplied.
-                    nestedScrollWebView.resetCurrentDomainName();
-
-                    // Reapply the domain settings if the URL is not null, which can happen if an empty tab is active when returning from settings.
-                    if (nestedScrollWebView.getUrl() != null) {
-                        applyDomainSettings(nestedScrollWebView, nestedScrollWebView.getUrl(), false, true, false);
-                    }
-                }
-            }
-        }
-
-        // Update the bookmarks drawer if returning from the Bookmarks activity.
-        if (restartFromBookmarksActivity) {
-            // Close the bookmarks drawer.
-            drawerLayout.closeDrawer(GravityCompat.END);
-
-            // Reload the bookmarks drawer.
-            loadBookmarksFolder();
-
-            // Reset `restartFromBookmarksActivity`.
-            restartFromBookmarksActivity = false;
-        }
-
-        // Update the privacy icon.  `true` runs `invalidateOptionsMenu` as the last step.  This can be important if the screen was rotated.
-        updatePrivacyIcons(true);
-    }
-
-    // `onResume()` runs after `onStart()`, which runs after `onCreate()` and `onRestart()`.
-    @Override
-    public void onResume() {
-        // Run the default commands.
-        super.onResume();
-
-        // Resume any WebViews.
-        for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
-            // Get the WebView tab fragment.
-            WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
-
-            // Get the fragment view.
-            View fragmentView = webViewTabFragment.getView();
-
-            // Only resume the WebViews if they exist (they won't when the app is first created).
-            if (fragmentView != null) {
-                // Get the nested scroll WebView from the tab fragment.
-                NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
-
-                // Resume the nested scroll WebView.
-                nestedScrollWebView.onResume();
-            }
-        }
-
-        // Resume the nested scroll WebView JavaScript timers.  This is a global command that resumes JavaScript timers on all WebViews.
-        if (currentWebView != null) {
-            currentWebView.resumeTimers();
-        }
-
-        // Reapply the proxy settings if the system is using a proxy.  This redisplays the appropriate alert dialog.
-        if (!proxyMode.equals(ProxyHelper.NONE)) {
-            applyProxy(false);
-        }
-
-        // Reapply any system UI flags and the ad in the free flavor.
-        if (displayingFullScreenVideo || inFullScreenBrowsingMode) {  // The system is displaying a website or a video in full screen mode.
-            // Get a handle for the root frame layouts.
-            FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout);
-
-            /* Hide the system bars.
-             * SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen.
-             * SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN makes the root frame layout fill the area that is normally reserved for the status bar.
-             * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen.
-             * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically re-hides them after they are shown.
-             */
-            rootFrameLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
-                    View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
-        } else if (BuildConfig.FLAVOR.contentEquals("free")) {  // The system in not in full screen mode.
-            // Resume the ad.
-            AdHelper.resumeAd(findViewById(R.id.adview));
-        }
-    }
-
-    @Override
-    public void onPause() {
-        // Run the default commands.
-        super.onPause();
-
-        for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
-            // Get the WebView tab fragment.
-            WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
-
-            // Get the fragment view.
-            View fragmentView = webViewTabFragment.getView();
-
-            // Only pause the WebViews if they exist (they won't when the app is first created).
-            if (fragmentView != null) {
-                // Get the nested scroll WebView from the tab fragment.
-                NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
-
-                // Pause the nested scroll WebView.
-                nestedScrollWebView.onPause();
-            }
-        }
-
-        // Pause the WebView JavaScript timers.  This is a global command that pauses JavaScript on all WebViews.
-        if (currentWebView != null) {
-            currentWebView.pauseTimers();
-        }
-
-        // Pause the ad or it will continue to consume resources in the background on the free flavor.
-        if (BuildConfig.FLAVOR.contentEquals("free")) {
-            // Pause the ad.
-            AdHelper.pauseAd(findViewById(R.id.adview));
-        }
-    }
-
-    @Override
-    public void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
-        // Run the default commands.
-        super.onSaveInstanceState(savedInstanceState);
-
-        // Create the saved state array lists.
-        ArrayList<Bundle> savedStateArrayList = new ArrayList<>();
-        ArrayList<Bundle> savedNestedScrollWebViewStateArrayList = new ArrayList<>();
-
-        // Get the URLs from each tab.
-        for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
-            // Get the WebView tab fragment.
-            WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
-
-            // Get the fragment view.
-            View fragmentView = webViewTabFragment.getView();
-
-            if (fragmentView != null) {
-                // Get the nested scroll WebView from the tab fragment.
-                NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
-
-                // Create saved state bundle.
-                Bundle savedStateBundle = new Bundle();
-
-                // Get the current states.
-                nestedScrollWebView.saveState(savedStateBundle);
-                Bundle savedNestedScrollWebViewStateBundle = nestedScrollWebView.saveNestedScrollWebViewState();
-
-                // Store the saved states in the array lists.
-                savedStateArrayList.add(savedStateBundle);
-                savedNestedScrollWebViewStateArrayList.add(savedNestedScrollWebViewStateBundle);
-            }
-        }
-
-        // Get the current tab position.
-        int currentTabPosition = tabLayout.getSelectedTabPosition();
-
-        // Store the saved states in the bundle.
-        savedInstanceState.putParcelableArrayList(SAVED_STATE_ARRAY_LIST, savedStateArrayList);
-        savedInstanceState.putParcelableArrayList(SAVED_NESTED_SCROLL_WEBVIEW_STATE_ARRAY_LIST, savedNestedScrollWebViewStateArrayList);
-        savedInstanceState.putInt(SAVED_TAB_POSITION, currentTabPosition);
-        savedInstanceState.putString(PROXY_MODE, proxyMode);
-    }
-
-    @Override
-    public void onDestroy() {
-        // Unregister the orbot status broadcast receiver if it exists.
-        if (orbotStatusBroadcastReceiver != null) {
-            this.unregisterReceiver(orbotStatusBroadcastReceiver);
-        }
-
-        // Close the bookmarks cursor if it exists.
-        if (bookmarksCursor != null) {
-            bookmarksCursor.close();
-        }
-
-        // Close the bookmarks database if it exists.
-        if (bookmarksDatabaseHelper != null) {
-            bookmarksDatabaseHelper.close();
-        }
-
-        // Stop populating the blocklists if the AsyncTask is running in the background.
-        if (populateBlocklists != null) {
-            populateBlocklists.cancel(true);
-        }
-
-        // Run the default commands.
-        super.onDestroy();
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        // Inflate the menu.  This adds items to the action bar if it is present.
-        getMenuInflater().inflate(R.menu.webview_options_menu, menu);
-
-        // Store a handle for the options menu so it can be used by `onOptionsItemSelected()` and `updatePrivacyIcons()`.
-        optionsMenu = menu;
-
-        // Set the initial status of the privacy icons.  `false` does not call `invalidateOptionsMenu` as the last step.
-        updatePrivacyIcons(false);
-
-        // Get handles for the menu items.
-        MenuItem bookmarksMenuItem = menu.findItem(R.id.bookmarks);
-        MenuItem toggleFirstPartyCookiesMenuItem = menu.findItem(R.id.toggle_first_party_cookies);
-        MenuItem toggleThirdPartyCookiesMenuItem = menu.findItem(R.id.toggle_third_party_cookies);
-        MenuItem toggleSaveFormDataMenuItem = menu.findItem(R.id.toggle_save_form_data);  // Form data can be removed once the minimum API >= 26.
-        MenuItem clearFormDataMenuItem = menu.findItem(R.id.clear_form_data);  // Form data can be removed once the minimum API >= 26.
-        MenuItem refreshMenuItem = menu.findItem(R.id.refresh);
-        MenuItem darkWebViewMenuItem = menu.findItem(R.id.dark_webview);
-        MenuItem adConsentMenuItem = menu.findItem(R.id.ad_consent);
-
-        // Only display third-party cookies if API >= 21
-        toggleThirdPartyCookiesMenuItem.setVisible(Build.VERSION.SDK_INT >= 21);
-
-        // Only display the form data menu items if the API < 26.
-        toggleSaveFormDataMenuItem.setVisible(Build.VERSION.SDK_INT < 26);
-        clearFormDataMenuItem.setVisible(Build.VERSION.SDK_INT < 26);
-
-        // Disable the clear form data menu item if the API >= 26 so that the status of the main Clear Data is calculated correctly.
-        clearFormDataMenuItem.setEnabled(Build.VERSION.SDK_INT < 26);
-
-        // Only display the dark WebView menu item if API >= 21.
-        darkWebViewMenuItem.setVisible(Build.VERSION.SDK_INT >= 21);
-
-        // Only show Ad Consent if this is the free flavor.
-        adConsentMenuItem.setVisible(BuildConfig.FLAVOR.contentEquals("free"));
-
-        // Get the shared preferences.
-        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
-
-        // Get the dark theme and app bar preferences.
-        boolean displayAdditionalAppBarIcons = sharedPreferences.getBoolean(getString(R.string.display_additional_app_bar_icons_key), false);
-
-        // Set the status of the additional app bar icons.  Setting the refresh menu item to `SHOW_AS_ACTION_ALWAYS` makes it appear even on small devices like phones.
-        if (displayAdditionalAppBarIcons) {
-            refreshMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
-            bookmarksMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
-            toggleFirstPartyCookiesMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
-        } else { //Do not display the additional icons.
-            refreshMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
-            bookmarksMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
-            toggleFirstPartyCookiesMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
-        }
-
-        // Replace Refresh with Stop if a URL is already loading.
-        if (currentWebView != null && currentWebView.getProgress() != 100) {
-            // Set the title.
-            refreshMenuItem.setTitle(R.string.stop);
-
-            // Set the icon if it is displayed in the app bar.
-            if (displayAdditionalAppBarIcons) {
-                // Get the current theme status.
-                int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
-                // Set the icon according to the current theme status.
-                if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
-                    refreshMenuItem.setIcon(R.drawable.close_blue_day);
-                } else {
-                    refreshMenuItem.setIcon(R.drawable.close_blue_night);
-                }
-            }
-        }
-
-        // Done.
-        return true;
-    }
-
-    @Override
-    public boolean onPrepareOptionsMenu(Menu menu) {
-        // Get handles for the menu items.
-        MenuItem addOrEditDomain = menu.findItem(R.id.add_or_edit_domain);
-        MenuItem firstPartyCookiesMenuItem = menu.findItem(R.id.toggle_first_party_cookies);
-        MenuItem thirdPartyCookiesMenuItem = menu.findItem(R.id.toggle_third_party_cookies);
-        MenuItem domStorageMenuItem = menu.findItem(R.id.toggle_dom_storage);
-        MenuItem saveFormDataMenuItem = menu.findItem(R.id.toggle_save_form_data);  // Form data can be removed once the minimum API >= 26.
-        MenuItem clearDataMenuItem = menu.findItem(R.id.clear_data);
-        MenuItem clearCookiesMenuItem = menu.findItem(R.id.clear_cookies);
-        MenuItem clearDOMStorageMenuItem = menu.findItem(R.id.clear_dom_storage);
-        MenuItem clearFormDataMenuItem = menu.findItem(R.id.clear_form_data);  // Form data can be removed once the minimum API >= 26.
-        MenuItem blocklistsMenuItem = menu.findItem(R.id.blocklists);
-        MenuItem easyListMenuItem = menu.findItem(R.id.easylist);
-        MenuItem easyPrivacyMenuItem = menu.findItem(R.id.easyprivacy);
-        MenuItem fanboysAnnoyanceListMenuItem = menu.findItem(R.id.fanboys_annoyance_list);
-        MenuItem fanboysSocialBlockingListMenuItem = menu.findItem(R.id.fanboys_social_blocking_list);
-        MenuItem ultraListMenuItem = menu.findItem(R.id.ultralist);
-        MenuItem ultraPrivacyMenuItem = menu.findItem(R.id.ultraprivacy);
-        MenuItem blockAllThirdPartyRequestsMenuItem = menu.findItem(R.id.block_all_third_party_requests);
-        MenuItem proxyMenuItem = menu.findItem(R.id.proxy);
-        MenuItem userAgentMenuItem = menu.findItem(R.id.user_agent);
-        MenuItem fontSizeMenuItem = menu.findItem(R.id.font_size);
-        MenuItem swipeToRefreshMenuItem = menu.findItem(R.id.swipe_to_refresh);
-        MenuItem wideViewportMenuItem = menu.findItem(R.id.wide_viewport);
-        MenuItem displayImagesMenuItem = menu.findItem(R.id.display_images);
-        MenuItem darkWebViewMenuItem = menu.findItem(R.id.dark_webview);
-
-        // Get a handle for the cookie manager.
-        CookieManager cookieManager = CookieManager.getInstance();
-
-        // Initialize the current user agent string and the font size.
-        String currentUserAgent = getString(R.string.user_agent_privacy_browser);
-        int fontSize = 100;
-
-        // Set items that require the current web view to be populated.  It will be null when the program is first opened, as `onPrepareOptionsMenu()` is called before the first WebView is initialized.
-        if (currentWebView != null) {
-            // Set the add or edit domain text.
-            if (currentWebView.getDomainSettingsApplied()) {
-                addOrEditDomain.setTitle(R.string.edit_domain_settings);
-            } else {
-                addOrEditDomain.setTitle(R.string.add_domain_settings);
-            }
-
-            // Get the current user agent from the WebView.
-            currentUserAgent = currentWebView.getSettings().getUserAgentString();
-
-            // Get the current font size from the
-            fontSize = currentWebView.getSettings().getTextZoom();
-
-            // Set the status of the menu item checkboxes.
-            domStorageMenuItem.setChecked(currentWebView.getSettings().getDomStorageEnabled());
-            saveFormDataMenuItem.setChecked(currentWebView.getSettings().getSaveFormData());  // Form data can be removed once the minimum API >= 26.
-            easyListMenuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.EASYLIST));
-            easyPrivacyMenuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.EASYPRIVACY));
-            fanboysAnnoyanceListMenuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST));
-            fanboysSocialBlockingListMenuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST));
-            ultraListMenuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.ULTRALIST));
-            ultraPrivacyMenuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.ULTRAPRIVACY));
-            blockAllThirdPartyRequestsMenuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.THIRD_PARTY_REQUESTS));
-            swipeToRefreshMenuItem.setChecked(currentWebView.getSwipeToRefresh());
-            wideViewportMenuItem.setChecked(currentWebView.getSettings().getUseWideViewPort());
-            displayImagesMenuItem.setChecked(currentWebView.getSettings().getLoadsImagesAutomatically());
-
-            // Initialize the display names for the blocklists with the number of blocked requests.
-            blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + currentWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
-            easyListMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.EASYLIST) + " - " + getString(R.string.easylist));
-            easyPrivacyMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.EASYPRIVACY) + " - " + getString(R.string.easyprivacy));
-            fanboysAnnoyanceListMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST) + " - " + getString(R.string.fanboys_annoyance_list));
-            fanboysSocialBlockingListMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST) + " - " + getString(R.string.fanboys_social_blocking_list));
-            ultraListMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.ULTRALIST) + " - " + getString(R.string.ultralist));
-            ultraPrivacyMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.ULTRAPRIVACY) + " - " + getString(R.string.ultraprivacy));
-            blockAllThirdPartyRequestsMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.THIRD_PARTY_REQUESTS) + " - " + getString(R.string.block_all_third_party_requests));
-
-            // Only modify third-party cookies if the API >= 21.
-            if (Build.VERSION.SDK_INT >= 21) {
-                // Set the status of the third-party cookies checkbox.
-                thirdPartyCookiesMenuItem.setChecked(cookieManager.acceptThirdPartyCookies(currentWebView));
-
-                // Enable third-party cookies if first-party cookies are enabled.
-                thirdPartyCookiesMenuItem.setEnabled(cookieManager.acceptCookie());
-            }
-
-            // Enable DOM Storage if JavaScript is enabled.
-            domStorageMenuItem.setEnabled(currentWebView.getSettings().getJavaScriptEnabled());
-
-            // Set the checkbox status for dark WebView if the WebView supports it.
-            if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
-                darkWebViewMenuItem.setChecked(WebSettingsCompat.getForceDark(currentWebView.getSettings()) == WebSettingsCompat.FORCE_DARK_ON);
-            }
-        }
-
-        // Set the checked status of the first party cookies menu item.
-        firstPartyCookiesMenuItem.setChecked(cookieManager.acceptCookie());
-
-        // Enable Clear Cookies if there are any.
-        clearCookiesMenuItem.setEnabled(cookieManager.hasCookies());
-
-        // Get the application's private data directory, which will be something like `/data/user/0/com.stoutner.privacybrowser.standard`, which links to `/data/data/com.stoutner.privacybrowser.standard`.
-        String privateDataDirectoryString = getApplicationInfo().dataDir;
-
-        // Get a count of the number of files in the Local Storage directory.
-        File localStorageDirectory = new File (privateDataDirectoryString + "/app_webview/Local Storage/");
-        int localStorageDirectoryNumberOfFiles = 0;
-        if (localStorageDirectory.exists()) {
-            // `Objects.requireNonNull` removes a lint warning that `localStorageDirectory.list` might produce a null pointed exception if it is dereferenced.
-            localStorageDirectoryNumberOfFiles = Objects.requireNonNull(localStorageDirectory.list()).length;
-        }
-
-        // Get a count of the number of files in the IndexedDB directory.
-        File indexedDBDirectory = new File (privateDataDirectoryString + "/app_webview/IndexedDB");
-        int indexedDBDirectoryNumberOfFiles = 0;
-        if (indexedDBDirectory.exists()) {
-            // `Objects.requireNonNull` removes a lint warning that `indexedDBDirectory.list` might produce a null pointed exception if it is dereferenced.
-            indexedDBDirectoryNumberOfFiles = Objects.requireNonNull(indexedDBDirectory.list()).length;
-        }
-
-        // Enable Clear DOM Storage if there is any.
-        clearDOMStorageMenuItem.setEnabled(localStorageDirectoryNumberOfFiles > 0 || indexedDBDirectoryNumberOfFiles > 0);
-
-        // Enable Clear Form Data is there is any.  This can be removed once the minimum API >= 26.
-        if (Build.VERSION.SDK_INT < 26) {
-            // Get the WebView database.
-            WebViewDatabase webViewDatabase = WebViewDatabase.getInstance(this);
-
-            // Enable the clear form data menu item if there is anything to clear.
-            clearFormDataMenuItem.setEnabled(webViewDatabase.hasFormData());
-        }
-
-        // Enable Clear Data if any of the submenu items are enabled.
-        clearDataMenuItem.setEnabled(clearCookiesMenuItem.isEnabled() || clearDOMStorageMenuItem.isEnabled() || clearFormDataMenuItem.isEnabled());
-
-        // Disable Fanboy's Social Blocking List menu item if Fanboy's Annoyance List is checked.
-        fanboysSocialBlockingListMenuItem.setEnabled(!fanboysAnnoyanceListMenuItem.isChecked());
-
-        // Set the proxy title and check the applied proxy.
-        switch (proxyMode) {
-            case ProxyHelper.NONE:
-                // Set the proxy title.
-                proxyMenuItem.setTitle(getString(R.string.proxy) + " - " + getString(R.string.proxy_none));
-
-                // Check the proxy None radio button.
-                menu.findItem(R.id.proxy_none).setChecked(true);
-                break;
-
-            case ProxyHelper.TOR:
-                // Set the proxy title.
-                proxyMenuItem.setTitle(getString(R.string.proxy) + " - " + getString(R.string.proxy_tor));
-
-                // Check the proxy Tor radio button.
-                menu.findItem(R.id.proxy_tor).setChecked(true);
-                break;
-
-            case ProxyHelper.I2P:
-                // Set the proxy title.
-                proxyMenuItem.setTitle(getString(R.string.proxy) + " - " + getString(R.string.proxy_i2p));
-
-                // Check the proxy I2P radio button.
-                menu.findItem(R.id.proxy_i2p).setChecked(true);
-                break;
-
-            case ProxyHelper.CUSTOM:
-                // Set the proxy title.
-                proxyMenuItem.setTitle(getString(R.string.proxy) + " - " + getString(R.string.proxy_custom));
-
-                // Check the proxy Custom radio button.
-                menu.findItem(R.id.proxy_custom).setChecked(true);
-                break;
-        }
-
-        // Select the current user agent menu item.  A switch statement cannot be used because the user agents are not compile time constants.
-        if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[0])) {  // Privacy Browser.
-            // Update the user agent menu item title.
-            userAgentMenuItem.setTitle(getString(R.string.options_user_agent) + " - " + getString(R.string.user_agent_privacy_browser));
-
-            // Select the Privacy Browser radio box.
-            menu.findItem(R.id.user_agent_privacy_browser).setChecked(true);
-        } else if (currentUserAgent.equals(webViewDefaultUserAgent)) {  // WebView Default.
-            // Update the user agent menu item title.
-            userAgentMenuItem.setTitle(getString(R.string.options_user_agent) + " - " + getString(R.string.user_agent_webview_default));
-
-            // Select the WebView Default radio box.
-            menu.findItem(R.id.user_agent_webview_default).setChecked(true);
-        } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[2])) {  // Firefox on Android.
-            // Update the user agent menu item title.
-            userAgentMenuItem.setTitle(getString(R.string.options_user_agent) + " - " + getString(R.string.user_agent_firefox_on_android));
-
-            // Select the Firefox on Android radio box.
-            menu.findItem(R.id.user_agent_firefox_on_android).setChecked(true);
-        } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[3])) {  // Chrome on Android.
-            // Update the user agent menu item title.
-            userAgentMenuItem.setTitle(getString(R.string.options_user_agent) + " - " + getString(R.string.user_agent_chrome_on_android));
-
-            // Select the Chrome on Android radio box.
-            menu.findItem(R.id.user_agent_chrome_on_android).setChecked(true);
-        } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[4])) {  // Safari on iOS.
-            // Update the user agent menu item title.
-            userAgentMenuItem.setTitle(getString(R.string.options_user_agent) + " - " + getString(R.string.user_agent_safari_on_ios));
-
-            // Select the Safari on iOS radio box.
-            menu.findItem(R.id.user_agent_safari_on_ios).setChecked(true);
-        } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[5])) {  // Firefox on Linux.
-            // Update the user agent menu item title.
-            userAgentMenuItem.setTitle(getString(R.string.options_user_agent) + " - " + getString(R.string.user_agent_firefox_on_linux));
-
-            // Select the Firefox on Linux radio box.
-            menu.findItem(R.id.user_agent_firefox_on_linux).setChecked(true);
-        } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[6])) {  // Chromium on Linux.
-            // Update the user agent menu item title.
-            userAgentMenuItem.setTitle(getString(R.string.options_user_agent) + " - " + getString(R.string.user_agent_chromium_on_linux));
-
-            // Select the Chromium on Linux radio box.
-            menu.findItem(R.id.user_agent_chromium_on_linux).setChecked(true);
-        } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[7])) {  // Firefox on Windows.
-            // Update the user agent menu item title.
-            userAgentMenuItem.setTitle(getString(R.string.options_user_agent) + " - " + getString(R.string.user_agent_firefox_on_windows));
-
-            // Select the Firefox on Windows radio box.
-            menu.findItem(R.id.user_agent_firefox_on_windows).setChecked(true);
-        } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[8])) {  // Chrome on Windows.
-            // Update the user agent menu item title.
-            userAgentMenuItem.setTitle(getString(R.string.options_user_agent) + " - " + getString(R.string.user_agent_chrome_on_windows));
-
-            // Select the Chrome on Windows radio box.
-            menu.findItem(R.id.user_agent_chrome_on_windows).setChecked(true);
-        } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[9])) {  // Edge on Windows.
-            // Update the user agent menu item title.
-            userAgentMenuItem.setTitle(getString(R.string.options_user_agent) + " - " + getString(R.string.user_agent_edge_on_windows));
-
-            // Select the Edge on Windows radio box.
-            menu.findItem(R.id.user_agent_edge_on_windows).setChecked(true);
-        } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[10])) {  // Internet Explorer on Windows.
-            // Update the user agent menu item title.
-            userAgentMenuItem.setTitle(getString(R.string.options_user_agent) + " - " + getString(R.string.user_agent_internet_explorer_on_windows));
-
-            // Select the Internet on Windows radio box.
-            menu.findItem(R.id.user_agent_internet_explorer_on_windows).setChecked(true);
-        } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[11])) {  // Safari on macOS.
-            // Update the user agent menu item title.
-            userAgentMenuItem.setTitle(getString(R.string.options_user_agent) + " - " + getString(R.string.user_agent_safari_on_macos));
-
-            // Select the Safari on macOS radio box.
-            menu.findItem(R.id.user_agent_safari_on_macos).setChecked(true);
-        } else {  // Custom user agent.
-            // Update the user agent menu item title.
-            userAgentMenuItem.setTitle(getString(R.string.options_user_agent) + " - " + getString(R.string.user_agent_custom));
-
-            // Select the Custom radio box.
-            menu.findItem(R.id.user_agent_custom).setChecked(true);
-        }
-
-        // Set the font size title.
-        fontSizeMenuItem.setTitle(getString(R.string.font_size) + " - " + fontSize + "%");
-
-        // Run all the other default commands.
-        super.onPrepareOptionsMenu(menu);
-
-        // Display the menu.
-        return true;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem menuItem) {
-        // Get a handle for the shared preferences.
-        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
-
-        // Get a handle for the cookie manager.
-        CookieManager cookieManager = CookieManager.getInstance();
-
-        // Get the selected menu item ID.
-        int menuItemId = menuItem.getItemId();
-
-        // Run the commands that correlate to the selected menu item.
-        if (menuItemId == R.id.toggle_javascript) {  // JavaScript.
-            // Toggle the JavaScript status.
-            currentWebView.getSettings().setJavaScriptEnabled(!currentWebView.getSettings().getJavaScriptEnabled());
-
-            // Update the privacy icon.
-            updatePrivacyIcons(true);
-
-            // Display a `Snackbar`.
-            if (currentWebView.getSettings().getJavaScriptEnabled()) {  // JavaScrip is enabled.
-                Snackbar.make(webViewPager, R.string.javascript_enabled, Snackbar.LENGTH_SHORT).show();
-            } else if (cookieManager.acceptCookie()) {  // JavaScript is disabled, but first-party cookies are enabled.
-                Snackbar.make(webViewPager, R.string.javascript_disabled, Snackbar.LENGTH_SHORT).show();
-            } else {  // Privacy mode.
-                Snackbar.make(webViewPager, R.string.privacy_mode, Snackbar.LENGTH_SHORT).show();
-            }
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.refresh) {  // Refresh.
-            // Run the command that correlates to the current status of the menu item.
-            if (menuItem.getTitle().equals(getString(R.string.refresh))) {  // The refresh button was pushed.
-                // Reload the current WebView.
-                currentWebView.reload();
-            } else {  // The stop button was pushed.
-                // Stop the loading of the WebView.
-                currentWebView.stopLoading();
-            }
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.bookmarks) {  // Bookmarks.
-            // Open the bookmarks drawer.
-            drawerLayout.openDrawer(GravityCompat.END);
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.toggle_first_party_cookies) {  // First-party cookies.
-            // Switch the first-party cookie status.
-            cookieManager.setAcceptCookie(!cookieManager.acceptCookie());
-
-            // Store the first-party cookie status.
-            currentWebView.setAcceptFirstPartyCookies(cookieManager.acceptCookie());
-
-            // Update the menu checkbox.
-            menuItem.setChecked(cookieManager.acceptCookie());
-
-            // Update the privacy icon.
-            updatePrivacyIcons(true);
-
-            // Display a snackbar.
-            if (cookieManager.acceptCookie()) {  // First-party cookies are enabled.
-                Snackbar.make(webViewPager, R.string.first_party_cookies_enabled, Snackbar.LENGTH_SHORT).show();
-            } else if (currentWebView.getSettings().getJavaScriptEnabled()) {  // JavaScript is still enabled.
-                Snackbar.make(webViewPager, R.string.first_party_cookies_disabled, Snackbar.LENGTH_SHORT).show();
-            } else {  // Privacy mode.
-                Snackbar.make(webViewPager, R.string.privacy_mode, Snackbar.LENGTH_SHORT).show();
-            }
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.toggle_third_party_cookies) {  // Third-party cookies.
-            // Only act if the API >= 21.  Otherwise, there are no third-party cookie controls.
-            if (Build.VERSION.SDK_INT >= 21) {
-                // Toggle the status of thirdPartyCookiesEnabled.
-                cookieManager.setAcceptThirdPartyCookies(currentWebView, !cookieManager.acceptThirdPartyCookies(currentWebView));
-
-                // Update the menu checkbox.
-                menuItem.setChecked(cookieManager.acceptThirdPartyCookies(currentWebView));
-
-                // Display a snackbar.
-                if (cookieManager.acceptThirdPartyCookies(currentWebView)) {
-                    Snackbar.make(webViewPager, R.string.third_party_cookies_enabled, Snackbar.LENGTH_SHORT).show();
-                } else {
-                    Snackbar.make(webViewPager, R.string.third_party_cookies_disabled, Snackbar.LENGTH_SHORT).show();
-                }
-
-                // Reload the current WebView.
-                currentWebView.reload();
-            }
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.toggle_dom_storage) {  // DOM storage.
-            // Toggle the status of domStorageEnabled.
-            currentWebView.getSettings().setDomStorageEnabled(!currentWebView.getSettings().getDomStorageEnabled());
-
-            // Update the menu checkbox.
-            menuItem.setChecked(currentWebView.getSettings().getDomStorageEnabled());
-
-            // Update the privacy icon.
-            updatePrivacyIcons(true);
-
-            // Display a snackbar.
-            if (currentWebView.getSettings().getDomStorageEnabled()) {
-                Snackbar.make(webViewPager, R.string.dom_storage_enabled, Snackbar.LENGTH_SHORT).show();
-            } else {
-                Snackbar.make(webViewPager, R.string.dom_storage_disabled, Snackbar.LENGTH_SHORT).show();
-            }
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.toggle_save_form_data) {  // Form data.  This can be removed once the minimum API >= 26.
-            // Switch the status of saveFormDataEnabled.
-            currentWebView.getSettings().setSaveFormData(!currentWebView.getSettings().getSaveFormData());
-
-            // Update the menu checkbox.
-            menuItem.setChecked(currentWebView.getSettings().getSaveFormData());
-
-            // Display a snackbar.
-            if (currentWebView.getSettings().getSaveFormData()) {
-                Snackbar.make(webViewPager, R.string.form_data_enabled, Snackbar.LENGTH_SHORT).show();
-            } else {
-                Snackbar.make(webViewPager, R.string.form_data_disabled, Snackbar.LENGTH_SHORT).show();
-            }
-
-            // Update the privacy icon.
-            updatePrivacyIcons(true);
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.clear_cookies) {  // Clear cookies.
-            // Create a snackbar.
-            Snackbar.make(webViewPager, R.string.cookies_deleted, Snackbar.LENGTH_LONG)
-                    .setAction(R.string.undo, v -> {
-                        // Do nothing because everything will be handled by `onDismissed()` below.
-                    })
-                    .addCallback(new Snackbar.Callback() {
-                        @Override
-                        public void onDismissed(Snackbar snackbar, int event) {
-                            if (event != Snackbar.Callback.DISMISS_EVENT_ACTION) {  // The snackbar was dismissed without the undo button being pushed.
-                                // Delete the cookies, which command varies by SDK.
-                                if (Build.VERSION.SDK_INT < 21) {
-                                    cookieManager.removeAllCookie();
-                                } else {
-                                    cookieManager.removeAllCookies(null);
-                                }
-                            }
-                        }
-                    })
-                    .show();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.clear_dom_storage) {  // Clear DOM storage.
-            // Create a snackbar.
-            Snackbar.make(webViewPager, R.string.dom_storage_deleted, Snackbar.LENGTH_LONG)
-                    .setAction(R.string.undo, v -> {
-                        // Do nothing because everything will be handled by `onDismissed()` below.
-                    })
-                    .addCallback(new Snackbar.Callback() {
-                        @Override
-                        public void onDismissed(Snackbar snackbar, int event) {
-                            if (event != Snackbar.Callback.DISMISS_EVENT_ACTION) {  // The snackbar was dismissed without the undo button being pushed.
-                                // Delete the DOM Storage.
-                                WebStorage webStorage = WebStorage.getInstance();
-                                webStorage.deleteAllData();
-
-                                // Initialize a handler to manually delete the DOM storage files and directories.
-                                Handler deleteDomStorageHandler = new Handler();
-
-                                // Setup a runnable to manually delete the DOM storage files and directories.
-                                Runnable deleteDomStorageRunnable = () -> {
-                                    try {
-                                        // Get a handle for the runtime.
-                                        Runtime runtime = Runtime.getRuntime();
-
-                                        // Get the application's private data directory, which will be something like `/data/user/0/com.stoutner.privacybrowser.standard`,
-                                        // which links to `/data/data/com.stoutner.privacybrowser.standard`.
-                                        String privateDataDirectoryString = getApplicationInfo().dataDir;
-
-                                        // A string array must be used because the directory contains a space and `Runtime.exec` will otherwise not escape the string correctly.
-                                        Process deleteLocalStorageProcess = runtime.exec(new String[]{"rm", "-rf", privateDataDirectoryString + "/app_webview/Local Storage/"});
-
-                                        // Multiple commands must be used because `Runtime.exec()` does not like `*`.
-                                        Process deleteIndexProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/IndexedDB");
-                                        Process deleteQuotaManagerProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager");
-                                        Process deleteQuotaManagerJournalProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager-journal");
-                                        Process deleteDatabasesProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/databases");
-
-                                        // Wait for the processes to finish.
-                                        deleteLocalStorageProcess.waitFor();
-                                        deleteIndexProcess.waitFor();
-                                        deleteQuotaManagerProcess.waitFor();
-                                        deleteQuotaManagerJournalProcess.waitFor();
-                                        deleteDatabasesProcess.waitFor();
-                                    } catch (Exception exception) {
-                                        // Do nothing if an error is thrown.
-                                    }
-                                };
-
-                                // Manually delete the DOM storage files after 200 milliseconds.
-                                deleteDomStorageHandler.postDelayed(deleteDomStorageRunnable, 200);
-                            }
-                        }
-                    })
-                    .show();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.clear_form_data) {  // Clear form data.  This can be remove once the minimum API >= 26.
-            // Create a snackbar.
-            Snackbar.make(webViewPager, R.string.form_data_deleted, Snackbar.LENGTH_LONG)
-                    .setAction(R.string.undo, v -> {
-                        // Do nothing because everything will be handled by `onDismissed()` below.
-                    })
-                    .addCallback(new Snackbar.Callback() {
-                        @Override
-                        public void onDismissed(Snackbar snackbar, int event) {
-                            if (event != Snackbar.Callback.DISMISS_EVENT_ACTION) {  // The snackbar was dismissed without the undo button being pushed.
-                                // Get a handle for the webView database.
-                                WebViewDatabase webViewDatabase = WebViewDatabase.getInstance(getApplicationContext());
-
-                                // Delete the form data.
-                                webViewDatabase.clearFormData();
-                            }
-                        }
-                    })
-                    .show();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.easylist) {  // EasyList.
-            // Toggle the EasyList status.
-            currentWebView.enableBlocklist(NestedScrollWebView.EASYLIST, !currentWebView.isBlocklistEnabled(NestedScrollWebView.EASYLIST));
-
-            // Update the menu checkbox.
-            menuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.EASYLIST));
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.easyprivacy) {  // EasyPrivacy.
-            // Toggle the EasyPrivacy status.
-            currentWebView.enableBlocklist(NestedScrollWebView.EASYPRIVACY, !currentWebView.isBlocklistEnabled(NestedScrollWebView.EASYPRIVACY));
-
-            // Update the menu checkbox.
-            menuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.EASYPRIVACY));
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.fanboys_annoyance_list) {  // Fanboy's Annoyance List.
-            // Toggle Fanboy's Annoyance List status.
-            currentWebView.enableBlocklist(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST, !currentWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST));
-
-            // Update the menu checkbox.
-            menuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST));
-
-            // Get a handle for the Fanboy's Social Block List menu item.
-            MenuItem fanboysSocialBlockingListMenuItem = optionsMenu.findItem(R.id.fanboys_social_blocking_list);
-
-            // Update the staus of Fanboy's Social Blocking List.
-            fanboysSocialBlockingListMenuItem.setEnabled(!currentWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST));
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.fanboys_social_blocking_list) {  // Fanboy's Social Blocking List.
-            // Toggle Fanboy's Social Blocking List status.
-            currentWebView.enableBlocklist(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST, !currentWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST));
-
-            // Update the menu checkbox.
-            menuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST));
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.ultralist) {  // UltraList.
-            // Toggle the UltraList status.
-            currentWebView.enableBlocklist(NestedScrollWebView.ULTRALIST, !currentWebView.isBlocklistEnabled(NestedScrollWebView.ULTRALIST));
-
-            // Update the menu checkbox.
-            menuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.ULTRALIST));
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.ultraprivacy) {  // UltraPrivacy.
-            // Toggle the UltraPrivacy status.
-            currentWebView.enableBlocklist(NestedScrollWebView.ULTRAPRIVACY, !currentWebView.isBlocklistEnabled(NestedScrollWebView.ULTRAPRIVACY));
-
-            // Update the menu checkbox.
-            menuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.ULTRAPRIVACY));
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.block_all_third_party_requests) {  // Block all third-party requests.
-            //Toggle the third-party requests blocker status.
-            currentWebView.enableBlocklist(NestedScrollWebView.THIRD_PARTY_REQUESTS, !currentWebView.isBlocklistEnabled(NestedScrollWebView.THIRD_PARTY_REQUESTS));
-
-            // Update the menu checkbox.
-            menuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.THIRD_PARTY_REQUESTS));
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.proxy_none) {  // Proxy - None.
-            // Update the proxy mode.
-            proxyMode = ProxyHelper.NONE;
-
-            // Apply the proxy mode.
-            applyProxy(true);
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.proxy_tor) {  // Proxy - Tor.
-            // Update the proxy mode.
-            proxyMode = ProxyHelper.TOR;
-
-            // Apply the proxy mode.
-            applyProxy(true);
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.proxy_i2p) {  // Proxy - I2P.
-            // Update the proxy mode.
-            proxyMode = ProxyHelper.I2P;
-
-            // Apply the proxy mode.
-            applyProxy(true);
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.proxy_custom) {  // Proxy - Custom.
-            // Update the proxy mode.
-            proxyMode = ProxyHelper.CUSTOM;
-
-            // Apply the proxy mode.
-            applyProxy(true);
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.user_agent_privacy_browser) {  // User Agent - Privacy Browser.
-            // Update the user agent.
-            currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[0]);
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.user_agent_webview_default) {  // User Agent - WebView Default.
-            // Update the user agent.
-            currentWebView.getSettings().setUserAgentString("");
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.user_agent_firefox_on_android) {  // User Agent - Firefox on Android.
-            // Update the user agent.
-            currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[2]);
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.user_agent_chrome_on_android) {  // User Agent - Chrome on Android.
-            // Update the user agent.
-            currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[3]);
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.user_agent_safari_on_ios) {  // User Agent - Safari on iOS.
-            // Update the user agent.
-            currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[4]);
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.user_agent_firefox_on_linux) {  // User Agent - Firefox on Linux.
-            // Update the user agent.
-            currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[5]);
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.user_agent_chromium_on_linux) {  // User Agent - Chromium on Linux.
-            // Update the user agent.
-            currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[6]);
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.user_agent_firefox_on_windows) {  // User Agent - Firefox on Windows.
-            // Update the user agent.
-            currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[7]);
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.user_agent_chrome_on_windows) {  // User Agent - Chrome on Windows.
-            // Update the user agent.
-            currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[8]);
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.user_agent_edge_on_windows) {  // User Agent - Edge on Windows.
-            // Update the user agent.
-            currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[9]);
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.user_agent_internet_explorer_on_windows) {  // User Agent - Internet Explorer on Windows.
-            // Update the user agent.
-            currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[10]);
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.user_agent_safari_on_macos) {  // User Agent - Safari on macOS.
-            // Update the user agent.
-            currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[11]);
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.user_agent_custom) {  // User Agent - Custom.
-            // Update the user agent.
-            currentWebView.getSettings().setUserAgentString(sharedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
-
-            // Reload the current WebView.
-            currentWebView.reload();
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.font_size) {  // Font size.
-            // Instantiate the font size dialog.
-            DialogFragment fontSizeDialogFragment = FontSizeDialog.displayDialog(currentWebView.getSettings().getTextZoom());
-
-            // Show the font size dialog.
-            fontSizeDialogFragment.show(getSupportFragmentManager(), getString(R.string.font_size));
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.swipe_to_refresh) {  // Swipe to refresh.
-            // Toggle the stored status of swipe to refresh.
-            currentWebView.setSwipeToRefresh(!currentWebView.getSwipeToRefresh());
-
-            // Get a handle for the swipe refresh layout.
-            SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
-
-            // Update the swipe refresh layout.
-            if (currentWebView.getSwipeToRefresh()) {  // Swipe to refresh is enabled.
-                // Only enable the swipe refresh layout if the WebView is scrolled to the top.  It is updated every time the scroll changes.
-                swipeRefreshLayout.setEnabled(currentWebView.getY() == 0);
-            } else {  // Swipe to refresh is disabled.
-                // Disable the swipe refresh layout.
-                swipeRefreshLayout.setEnabled(false);
-            }
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.wide_viewport) {  // Wide viewport.
-            // Toggle the viewport.
-            currentWebView.getSettings().setUseWideViewPort(!currentWebView.getSettings().getUseWideViewPort());
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.display_images) {  // Display images.
-            // Toggle the displaying of images.
-            if (currentWebView.getSettings().getLoadsImagesAutomatically()) {  // Images are currently loaded automatically.
-                // Disable loading of images.
-                currentWebView.getSettings().setLoadsImagesAutomatically(false);
-
-                // Reload the website to remove existing images.
-                currentWebView.reload();
-            } else {  // Images are not currently loaded automatically.
-                // Enable loading of images.  Missing images will be loaded without the need for a reload.
-                currentWebView.getSettings().setLoadsImagesAutomatically(true);
-            }
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.dark_webview) {  // Dark WebView.
-            // Check to see if dark WebView is supported by this WebView.
-            if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
-                // Toggle the dark WebView setting.
-                if (WebSettingsCompat.getForceDark(currentWebView.getSettings()) == WebSettingsCompat.FORCE_DARK_ON) {  // Dark WebView is currently enabled.
-                    // Turn off dark WebView.
-                    WebSettingsCompat.setForceDark(currentWebView.getSettings(), WebSettingsCompat.FORCE_DARK_OFF);
-                } else {  // Dark WebView is currently disabled.
-                    // Turn on dark WebView.
-                    WebSettingsCompat.setForceDark(currentWebView.getSettings(), WebSettingsCompat.FORCE_DARK_ON);
-                }
-            }
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.find_on_page) {  // Find on page.
-            // Get a handle for the views.
-            Toolbar toolbar = findViewById(R.id.toolbar);
-            LinearLayout findOnPageLinearLayout = findViewById(R.id.find_on_page_linearlayout);
-            EditText findOnPageEditText = findViewById(R.id.find_on_page_edittext);
-
-            // Set the minimum height of the find on page linear layout to match the toolbar.
-            findOnPageLinearLayout.setMinimumHeight(toolbar.getHeight());
-
-            // Hide the toolbar.
-            toolbar.setVisibility(View.GONE);
-
-            // Show the find on page linear layout.
-            findOnPageLinearLayout.setVisibility(View.VISIBLE);
-
-            // Display the keyboard.  The app must wait 200 ms before running the command to work around a bug in Android.
-            // http://stackoverflow.com/questions/5520085/android-show-softkeyboard-with-showsoftinput-is-not-working
-            findOnPageEditText.postDelayed(() -> {
-                // Set the focus on the find on page edit text.
-                findOnPageEditText.requestFocus();
-
-                // Get a handle for the input method manager.
-                InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
-
-                // Remove the lint warning below that the input method manager might be null.
-                assert inputMethodManager != null;
-
-                // Display the keyboard.  `0` sets no input flags.
-                inputMethodManager.showSoftInput(findOnPageEditText, 0);
-            }, 200);
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.print) {  // Print.
-            // Get a print manager instance.
-            PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
-
-            // Remove the lint error below that print manager might be null.
-            assert printManager != null;
-
-            // Create a print document adapter from the current WebView.
-            PrintDocumentAdapter printDocumentAdapter = currentWebView.createPrintDocumentAdapter();
-
-            // Print the document.
-            printManager.print(getString(R.string.privacy_browser_web_page), printDocumentAdapter, null);
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.save_url) {  // Save URL.
-            // Prepare the save dialog.  The dialog will be displayed once the file size and the content disposition have been acquired.
-            new PrepareSaveDialog(this, this, getSupportFragmentManager(), StoragePermissionDialog.SAVE_URL, currentWebView.getSettings().getUserAgentString(),
-                    currentWebView.getAcceptFirstPartyCookies()).execute(currentWebView.getCurrentUrl());
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.save_archive) {  // Save archive.
-            // Instantiate the save dialog.
-            DialogFragment saveArchiveFragment = SaveWebpageDialog.saveWebpage(StoragePermissionDialog.SAVE_ARCHIVE, null, null, getString(R.string.webpage_mht), null,
-                    false);
-
-            // Show the save dialog.  It must be named `save_dialog` so that the file picker can update the file name.
-            saveArchiveFragment.show(getSupportFragmentManager(), getString(R.string.save_dialog));
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.save_image) {  // Save image.
-            // Instantiate the save dialog.
-            DialogFragment saveImageFragment = SaveWebpageDialog.saveWebpage(StoragePermissionDialog.SAVE_IMAGE, null, null, getString(R.string.webpage_png), null,
-                    false);
-
-            // Show the save dialog.  It must be named `save_dialog` so that the file picker can update the file name.
-            saveImageFragment.show(getSupportFragmentManager(), getString(R.string.save_dialog));
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.add_to_homescreen) {  // Add to homescreen.
-            // Instantiate the create home screen shortcut dialog.
-            DialogFragment createHomeScreenShortcutDialogFragment = CreateHomeScreenShortcutDialog.createDialog(currentWebView.getTitle(), currentWebView.getUrl(),
-                    currentWebView.getFavoriteOrDefaultIcon());
-
-            // Show the create home screen shortcut dialog.
-            createHomeScreenShortcutDialogFragment.show(getSupportFragmentManager(), getString(R.string.create_shortcut));
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.view_source) {  // View source.
-            // Create an intent to launch the view source activity.
-            Intent viewSourceIntent = new Intent(this, ViewSourceActivity.class);
-
-            // Add the variables to the intent.
-            viewSourceIntent.putExtra(ViewSourceActivityKt.CURRENT_URL, currentWebView.getUrl());
-            viewSourceIntent.putExtra(ViewSourceActivityKt.USER_AGENT, currentWebView.getSettings().getUserAgentString());
-
-            // Make it so.
-            startActivity(viewSourceIntent);
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.share_url) {  // Share URL.
-            // Setup the share string.
-            String shareString = currentWebView.getTitle() + " – " + currentWebView.getUrl();
-
-            // Create the share intent.
-            Intent shareIntent = new Intent(Intent.ACTION_SEND);
-
-            // Add the share string to the intent.
-            shareIntent.putExtra(Intent.EXTRA_TEXT, shareString);
-
-            // Set the MIME type.
-            shareIntent.setType("text/plain");
-
-            // Set the intent to open in a new task.
-            shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-            // Make it so.
-            startActivity(Intent.createChooser(shareIntent, getString(R.string.share_url)));
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.open_with_app) {  // Open with app.
-            // Open the URL with an outside app.
-            openWithApp(currentWebView.getUrl());
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.open_with_browser) {  // Open with browser.
-            // Open the URL with an outside browser.
-            openWithBrowser(currentWebView.getUrl());
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.add_or_edit_domain) {  // Add or edit domain.
-            // Check if domain settings currently exist.
-            if (currentWebView.getDomainSettingsApplied()) {  // Edit the current domain settings.
-                // Reapply the domain settings on returning to `MainWebViewActivity`.
-                reapplyDomainSettingsOnRestart = true;
-
-                // Create an intent to launch the domains activity.
-                Intent domainsIntent = new Intent(this, DomainsActivity.class);
-
-                // Add the extra information to the intent.
-                domainsIntent.putExtra("load_domain", currentWebView.getDomainSettingsDatabaseId());
-                domainsIntent.putExtra("close_on_back", true);
-                domainsIntent.putExtra("current_url", currentWebView.getUrl());
-
-                // Get the current certificate.
-                SslCertificate sslCertificate = currentWebView.getCertificate();
-
-                // Check to see if the SSL certificate is populated.
-                if (sslCertificate != null) {
-                    // Extract the certificate to strings.
-                    String issuedToCName = sslCertificate.getIssuedTo().getCName();
-                    String issuedToOName = sslCertificate.getIssuedTo().getOName();
-                    String issuedToUName = sslCertificate.getIssuedTo().getUName();
-                    String issuedByCName = sslCertificate.getIssuedBy().getCName();
-                    String issuedByOName = sslCertificate.getIssuedBy().getOName();
-                    String issuedByUName = sslCertificate.getIssuedBy().getUName();
-                    long startDateLong = sslCertificate.getValidNotBeforeDate().getTime();
-                    long endDateLong = sslCertificate.getValidNotAfterDate().getTime();
-
-                    // Add the certificate to the intent.
-                    domainsIntent.putExtra("ssl_issued_to_cname", issuedToCName);
-                    domainsIntent.putExtra("ssl_issued_to_oname", issuedToOName);
-                    domainsIntent.putExtra("ssl_issued_to_uname", issuedToUName);
-                    domainsIntent.putExtra("ssl_issued_by_cname", issuedByCName);
-                    domainsIntent.putExtra("ssl_issued_by_oname", issuedByOName);
-                    domainsIntent.putExtra("ssl_issued_by_uname", issuedByUName);
-                    domainsIntent.putExtra("ssl_start_date", startDateLong);
-                    domainsIntent.putExtra("ssl_end_date", endDateLong);
-                }
-
-                // Check to see if the current IP addresses have been received.
-                if (currentWebView.hasCurrentIpAddresses()) {
-                    // Add the current IP addresses to the intent.
-                    domainsIntent.putExtra("current_ip_addresses", currentWebView.getCurrentIpAddresses());
-                }
-
-                // Make it so.
-                startActivity(domainsIntent);
-            } else {  // Add a new domain.
-                // Apply the new domain settings on returning to `MainWebViewActivity`.
-                reapplyDomainSettingsOnRestart = true;
-
-                // Get the current domain
-                Uri currentUri = Uri.parse(currentWebView.getUrl());
-                String currentDomain = currentUri.getHost();
-
-                // Initialize the database handler.  The `0` specifies the database version, but that is ignored and set instead using a constant in `DomainsDatabaseHelper`.
-                DomainsDatabaseHelper domainsDatabaseHelper = new DomainsDatabaseHelper(this, null, null, 0);
-
-                // Create the domain and store the database ID.
-                int newDomainDatabaseId = domainsDatabaseHelper.addDomain(currentDomain);
-
-                // Create an intent to launch the domains activity.
-                Intent domainsIntent = new Intent(this, DomainsActivity.class);
-
-                // Add the extra information to the intent.
-                domainsIntent.putExtra("load_domain", newDomainDatabaseId);
-                domainsIntent.putExtra("close_on_back", true);
-                domainsIntent.putExtra("current_url", currentWebView.getUrl());
-
-                // Get the current certificate.
-                SslCertificate sslCertificate = currentWebView.getCertificate();
-
-                // Check to see if the SSL certificate is populated.
-                if (sslCertificate != null) {
-                    // Extract the certificate to strings.
-                    String issuedToCName = sslCertificate.getIssuedTo().getCName();
-                    String issuedToOName = sslCertificate.getIssuedTo().getOName();
-                    String issuedToUName = sslCertificate.getIssuedTo().getUName();
-                    String issuedByCName = sslCertificate.getIssuedBy().getCName();
-                    String issuedByOName = sslCertificate.getIssuedBy().getOName();
-                    String issuedByUName = sslCertificate.getIssuedBy().getUName();
-                    long startDateLong = sslCertificate.getValidNotBeforeDate().getTime();
-                    long endDateLong = sslCertificate.getValidNotAfterDate().getTime();
-
-                    // Add the certificate to the intent.
-                    domainsIntent.putExtra("ssl_issued_to_cname", issuedToCName);
-                    domainsIntent.putExtra("ssl_issued_to_oname", issuedToOName);
-                    domainsIntent.putExtra("ssl_issued_to_uname", issuedToUName);
-                    domainsIntent.putExtra("ssl_issued_by_cname", issuedByCName);
-                    domainsIntent.putExtra("ssl_issued_by_oname", issuedByOName);
-                    domainsIntent.putExtra("ssl_issued_by_uname", issuedByUName);
-                    domainsIntent.putExtra("ssl_start_date", startDateLong);
-                    domainsIntent.putExtra("ssl_end_date", endDateLong);
-                }
-
-                // Check to see if the current IP addresses have been received.
-                if (currentWebView.hasCurrentIpAddresses()) {
-                    // Add the current IP addresses to the intent.
-                    domainsIntent.putExtra("current_ip_addresses", currentWebView.getCurrentIpAddresses());
-                }
-
-                // Make it so.
-                startActivity(domainsIntent);
-            }
-
-            // Consume the event.
-            return true;
-        } else if (menuItemId == R.id.ad_consent) {  // Ad consent.
-            // Instantiate the ad consent dialog.
-            DialogFragment adConsentDialogFragment = new AdConsentDialog();
-
-            // Display the ad consent dialog.
-            adConsentDialogFragment.show(getSupportFragmentManager(), getString(R.string.ad_consent));
-
-            // Consume the event.
-            return true;
-        } else {  // There is no match with the options menu.  Pass the event up to the parent method.
-            // Don't consume the event.
-            return super.onOptionsItemSelected(menuItem);
-        }
-    }
-
-    // removeAllCookies is deprecated, but it is required for API < 21.
-    @Override
-    public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
-        // Get a handle for the shared preferences.
-        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
-
-        // Get the menu item ID.
-        int menuItemId = menuItem.getItemId();
-
-        // Run the commands that correspond to the selected menu item.
-        if (menuItemId == R.id.clear_and_exit) {  // Clear and exit.
-            // Clear and exit Privacy Browser.
-            clearAndExit();
-        } else if (menuItemId == R.id.home) {  // Home.
-            // Load the homepage.
-            loadUrl(currentWebView, sharedPreferences.getString("homepage", getString(R.string.homepage_default_value)));
-        } else if (menuItemId == R.id.back) {  // Back.
-            // Check if the WebView can go back.
-            if (currentWebView.canGoBack()) {
-                // Get the current web back forward list.
-                WebBackForwardList webBackForwardList = currentWebView.copyBackForwardList();
-
-                // Get the previous entry URL.
-                String previousUrl = webBackForwardList.getItemAtIndex(webBackForwardList.getCurrentIndex() - 1).getUrl();
-
-                // Apply the domain settings.
-                applyDomainSettings(currentWebView, previousUrl, false, false, false);
-
-                // Load the previous website in the history.
-                currentWebView.goBack();
-            }
-        } else if (menuItemId == R.id.forward) {  // Forward.
-            // Check if the WebView can go forward.
-            if (currentWebView.canGoForward()) {
-                // Get the current web back forward list.
-                WebBackForwardList webBackForwardList = currentWebView.copyBackForwardList();
-
-                // Get the next entry URL.
-                String nextUrl = webBackForwardList.getItemAtIndex(webBackForwardList.getCurrentIndex() + 1).getUrl();
-
-                // Apply the domain settings.
-                applyDomainSettings(currentWebView, nextUrl, false, false, false);
-
-                // Load the next website in the history.
-                currentWebView.goForward();
-            }
-        } else if (menuItemId == R.id.history) {  // History.
-            // Instantiate the URL history dialog.
-            DialogFragment urlHistoryDialogFragment = UrlHistoryDialog.loadBackForwardList(currentWebView.getWebViewFragmentId());
-
-            // Show the URL history dialog.
-            urlHistoryDialogFragment.show(getSupportFragmentManager(), getString(R.string.history));
-        } else if (menuItemId == R.id.open) {  // Open.
-            // Instantiate the open file dialog.
-            DialogFragment openDialogFragment = new OpenDialog();
-
-            // Show the open file dialog.
-            openDialogFragment.show(getSupportFragmentManager(), getString(R.string.open));
-        } else if (menuItemId == R.id.requests) {  // Requests.
-            // Populate the resource requests.
-            RequestsActivity.resourceRequests = currentWebView.getResourceRequests();
-
-            // Create an intent to launch the Requests activity.
-            Intent requestsIntent = new Intent(this, RequestsActivity.class);
-
-            // Add the block third-party requests status to the intent.
-            requestsIntent.putExtra("block_all_third_party_requests", currentWebView.isBlocklistEnabled(NestedScrollWebView.THIRD_PARTY_REQUESTS));
-
-            // Make it so.
-            startActivity(requestsIntent);
-        } else if (menuItemId == R.id.downloads) {  // Downloads.
-            // Launch the system Download Manager.
-            Intent downloadManagerIntent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
-
-            // Launch as a new task so that Download Manager and Privacy Browser show as separate windows in the recent tasks list.
-            downloadManagerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-            // Make it so.
-            startActivity(downloadManagerIntent);
-        } else if (menuItemId == R.id.domains) {  // Domains.
-            // Set the flag to reapply the domain settings on restart when returning from Domain Settings.
-            reapplyDomainSettingsOnRestart = true;
-
-            // Launch the domains activity.
-            Intent domainsIntent = new Intent(this, DomainsActivity.class);
-
-            // Add the extra information to the intent.
-            domainsIntent.putExtra("current_url", currentWebView.getUrl());
-
-            // Get the current certificate.
-            SslCertificate sslCertificate = currentWebView.getCertificate();
-
-            // Check to see if the SSL certificate is populated.
-            if (sslCertificate != null) {
-                // Extract the certificate to strings.
-                String issuedToCName = sslCertificate.getIssuedTo().getCName();
-                String issuedToOName = sslCertificate.getIssuedTo().getOName();
-                String issuedToUName = sslCertificate.getIssuedTo().getUName();
-                String issuedByCName = sslCertificate.getIssuedBy().getCName();
-                String issuedByOName = sslCertificate.getIssuedBy().getOName();
-                String issuedByUName = sslCertificate.getIssuedBy().getUName();
-                long startDateLong = sslCertificate.getValidNotBeforeDate().getTime();
-                long endDateLong = sslCertificate.getValidNotAfterDate().getTime();
-
-                // Add the certificate to the intent.
-                domainsIntent.putExtra("ssl_issued_to_cname", issuedToCName);
-                domainsIntent.putExtra("ssl_issued_to_oname", issuedToOName);
-                domainsIntent.putExtra("ssl_issued_to_uname", issuedToUName);
-                domainsIntent.putExtra("ssl_issued_by_cname", issuedByCName);
-                domainsIntent.putExtra("ssl_issued_by_oname", issuedByOName);
-                domainsIntent.putExtra("ssl_issued_by_uname", issuedByUName);
-                domainsIntent.putExtra("ssl_start_date", startDateLong);
-                domainsIntent.putExtra("ssl_end_date", endDateLong);
-            }
-
-            // Check to see if the current IP addresses have been received.
-            if (currentWebView.hasCurrentIpAddresses()) {
-                // Add the current IP addresses to the intent.
-                domainsIntent.putExtra("current_ip_addresses", currentWebView.getCurrentIpAddresses());
-            }
-
-            // Make it so.
-            startActivity(domainsIntent);
-        } else if (menuItemId == R.id.settings) {  // Settings.
-            // Set the flag to reapply app settings on restart when returning from Settings.
-            reapplyAppSettingsOnRestart = true;
-
-            // Set the flag to reapply the domain settings on restart when returning from Settings.
-            reapplyDomainSettingsOnRestart = true;
-
-            // Launch the settings activity.
-            Intent settingsIntent = new Intent(this, SettingsActivity.class);
-            startActivity(settingsIntent);
-        } else if (menuItemId == R.id.import_export) { // Import/Export.
-            // Create an intent to launch the import/export activity.
-            Intent importExportIntent = new Intent(this, ImportExportActivity.class);
-
-            // Make it so.
-            startActivity(importExportIntent);
-        } else if (menuItemId == R.id.logcat) {  // Logcat.
-            // Create an intent to launch the logcat activity.
-            Intent logcatIntent = new Intent(this, LogcatActivity.class);
-
-            // Make it so.
-            startActivity(logcatIntent);
-        } else if (menuItemId == R.id.guide) {  // Guide.
-            // Create an intent to launch the guide activity.
-            Intent guideIntent = new Intent(this, GuideActivity.class);
-
-            // Make it so.
-            startActivity(guideIntent);
-        } else if (menuItemId == R.id.about) {  // About
-            // Create an intent to launch the about activity.
-            Intent aboutIntent = new Intent(this, AboutActivity.class);
-
-            // Create a string array for the blocklist versions.
-            String[] blocklistVersions = new String[]{easyList.get(0).get(0)[0], easyPrivacy.get(0).get(0)[0], fanboysAnnoyanceList.get(0).get(0)[0], fanboysSocialList.get(0).get(0)[0],
-                    ultraList.get(0).get(0)[0], ultraPrivacy.get(0).get(0)[0]};
-
-            // Add the blocklist versions to the intent.
-            aboutIntent.putExtra("blocklist_versions", blocklistVersions);
-
-            // Make it so.
-            startActivity(aboutIntent);
-        }
-
-        // Close the navigation drawer.
-        drawerLayout.closeDrawer(GravityCompat.START);
-        return true;
-    }
-
-    @Override
-    public void onPostCreate(Bundle savedInstanceState) {
-        // Run the default commands.
-        super.onPostCreate(savedInstanceState);
-
-        // Sync the state of the DrawerToggle after the default `onRestoreInstanceState()` has finished.  This creates the navigation drawer icon.
-        actionBarDrawerToggle.syncState();
-    }
-
-    @Override
-    public void onConfigurationChanged(@NonNull Configuration newConfig) {
-        // Run the default commands.
-        super.onConfigurationChanged(newConfig);
-
-        // Reload the ad for the free flavor if not in full screen mode.
-        if (BuildConfig.FLAVOR.contentEquals("free") && !inFullScreenBrowsingMode) {
-            // Reload the ad.  The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
-            AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_unit_id));
-        }
-
-        // `invalidateOptionsMenu` should recalculate the number of action buttons from the menu to display on the app bar, but it doesn't because of the this bug:
-        // https://code.google.com/p/android/issues/detail?id=20493#c8
-        // ActivityCompat.invalidateOptionsMenu(this);
-    }
-
-    @Override
-    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
-        // Get the hit test result.
-        final WebView.HitTestResult hitTestResult = currentWebView.getHitTestResult();
-
-        // Define the URL strings.
-        final String imageUrl;
-        final String linkUrl;
-
-        // Get handles for the system managers.
-        final ClipboardManager clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
-
-        // Remove the lint errors below that the clipboard manager might be null.
-        assert clipboardManager != null;
-
-        // Process the link according to the type.
-        switch (hitTestResult.getType()) {
-            // `SRC_ANCHOR_TYPE` is a link.
-            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
-                // Get the target URL.
-                linkUrl = hitTestResult.getExtra();
-
-                // Set the target URL as the title of the `ContextMenu`.
-                menu.setHeaderTitle(linkUrl);
-
-                // Add an Open in New Tab entry.
-                menu.add(R.string.open_in_new_tab).setOnMenuItemClickListener((MenuItem item) -> {
-                    // Load the link URL in a new tab and move to it.
-                    addNewTab(linkUrl, true);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add an Open in Background entry.
-                menu.add(R.string.open_in_background).setOnMenuItemClickListener((MenuItem item) -> {
-                    // Load the link URL in a new tab but do not move to it.
-                    addNewTab(linkUrl, false);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add an Open with App entry.
-                menu.add(R.string.open_with_app).setOnMenuItemClickListener((MenuItem item) -> {
-                    openWithApp(linkUrl);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add an Open with Browser entry.
-                menu.add(R.string.open_with_browser).setOnMenuItemClickListener((MenuItem item) -> {
-                    openWithBrowser(linkUrl);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add a Copy URL entry.
-                menu.add(R.string.copy_url).setOnMenuItemClickListener((MenuItem item) -> {
-                    // Save the link URL in a `ClipData`.
-                    ClipData srcAnchorTypeClipData = ClipData.newPlainText(getString(R.string.url), linkUrl);
-
-                    // Set the `ClipData` as the clipboard's primary clip.
-                    clipboardManager.setPrimaryClip(srcAnchorTypeClipData);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add a Save URL entry.
-                menu.add(R.string.save_url).setOnMenuItemClickListener((MenuItem item) -> {
-                    // Prepare the save dialog.  The dialog will be displayed once the file size and the content disposition have been acquired.
-                    new PrepareSaveDialog(this, this, getSupportFragmentManager(), StoragePermissionDialog.SAVE_URL, currentWebView.getSettings().getUserAgentString(),
-                            currentWebView.getAcceptFirstPartyCookies()).execute(linkUrl);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add an empty Cancel entry, which by default closes the context menu.
-                menu.add(R.string.cancel);
-                break;
-
-            // `IMAGE_TYPE` is an image.
-            case WebView.HitTestResult.IMAGE_TYPE:
-                // Get the image URL.
-                imageUrl = hitTestResult.getExtra();
-
-                // Remove the incorrect lint warning below that the image URL might be null.
-                assert imageUrl != null;
-
-                // Set the context menu title.
-                if (imageUrl.startsWith("data:")) {  // The image data is contained in within the URL, making it exceedingly long.
-                    // Truncate the image URL before making it the title.
-                    menu.setHeaderTitle(imageUrl.substring(0, 100));
-                } else {  // The image URL does not contain the full image data.
-                    // Set the image URL as the title of the context menu.
-                    menu.setHeaderTitle(imageUrl);
-                }
-
-                // Add an Open in New Tab entry.
-                menu.add(R.string.open_image_in_new_tab).setOnMenuItemClickListener((MenuItem item) -> {
-                    // Load the image in a new tab.
-                    addNewTab(imageUrl, true);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add an Open with App entry.
-                menu.add(R.string.open_with_app).setOnMenuItemClickListener((MenuItem item) -> {
-                    // Open the image URL with an external app.
-                    openWithApp(imageUrl);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add an Open with Browser entry.
-                menu.add(R.string.open_with_browser).setOnMenuItemClickListener((MenuItem item) -> {
-                    // Open the image URL with an external browser.
-                    openWithBrowser(imageUrl);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add a View Image entry.
-                menu.add(R.string.view_image).setOnMenuItemClickListener(item -> {
-                    // Load the image in the current tab.
-                    loadUrl(currentWebView, imageUrl);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add a Save Image entry.
-                menu.add(R.string.save_image).setOnMenuItemClickListener((MenuItem item) -> {
-                   // Prepare the save dialog.  The dialog will be displayed once the file size and the content disposition have been acquired.
-                    new PrepareSaveDialog(this, this, getSupportFragmentManager(), StoragePermissionDialog.SAVE_URL, currentWebView.getSettings().getUserAgentString(),
-                            currentWebView.getAcceptFirstPartyCookies()).execute(imageUrl);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add a Copy URL entry.
-                menu.add(R.string.copy_url).setOnMenuItemClickListener((MenuItem item) -> {
-                    // Save the image URL in a clip data.
-                    ClipData imageTypeClipData = ClipData.newPlainText(getString(R.string.url), imageUrl);
-
-                    // Set the clip data as the clipboard's primary clip.
-                    clipboardManager.setPrimaryClip(imageTypeClipData);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add an empty Cancel entry, which by default closes the context menu.
-                menu.add(R.string.cancel);
-                break;
-
-            // `SRC_IMAGE_ANCHOR_TYPE` is an image that is also a link.
-            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
-                // Get the image URL.
-                imageUrl = hitTestResult.getExtra();
-
-                // Instantiate a handler.
-                Handler handler = new Handler();
-
-                // Get a message from the handler.
-                Message message = handler.obtainMessage();
-
-                // Request the image details from the last touched node be returned in the message.
-                currentWebView.requestFocusNodeHref(message);
-
-                // Get the link URL from the message data.
-                linkUrl = message.getData().getString("url");
-
-                // Set the link URL as the title of the context menu.
-                menu.setHeaderTitle(linkUrl);
-
-                // Add an Open in New Tab entry.
-                menu.add(R.string.open_in_new_tab).setOnMenuItemClickListener((MenuItem item) -> {
-                    // Load the link URL in a new tab and move to it.
-                    addNewTab(linkUrl, true);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add an Open in Background entry.
-                menu.add(R.string.open_in_background).setOnMenuItemClickListener((MenuItem item) -> {
-                    // Lod the link URL in a new tab but do not move to it.
-                    addNewTab(linkUrl, false);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add an Open Image in New Tab entry.
-                menu.add(R.string.open_image_in_new_tab).setOnMenuItemClickListener((MenuItem item) -> {
-                    // Load the image in a new tab and move to it.
-                    addNewTab(imageUrl, true);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add an Open with App entry.
-                menu.add(R.string.open_with_app).setOnMenuItemClickListener((MenuItem item) -> {
-                    // Open the link URL with an external app.
-                    openWithApp(linkUrl);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add an Open with Browser entry.
-                menu.add(R.string.open_with_browser).setOnMenuItemClickListener((MenuItem item) -> {
-                    // Open the link URL with an external browser.
-                    openWithBrowser(linkUrl);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add a View Image entry.
-                menu.add(R.string.view_image).setOnMenuItemClickListener((MenuItem item) -> {
-                   // View the image in the current tab.
-                   loadUrl(currentWebView, imageUrl);
-
-                   // Consume the event.
-                   return true;
-                });
-
-                // Add a Save Image entry.
-                menu.add(R.string.save_image).setOnMenuItemClickListener((MenuItem item) -> {
-                    // Prepare the save dialog.  The dialog will be displayed once the file size and the content disposition have been acquired.
-                    new PrepareSaveDialog(this, this, getSupportFragmentManager(), StoragePermissionDialog.SAVE_URL, currentWebView.getSettings().getUserAgentString(),
-                            currentWebView.getAcceptFirstPartyCookies()).execute(imageUrl);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add a Copy URL entry.
-                menu.add(R.string.copy_url).setOnMenuItemClickListener((MenuItem item) -> {
-                    // Save the link URL in a clip data.
-                    ClipData srcImageAnchorTypeClipData = ClipData.newPlainText(getString(R.string.url), linkUrl);
-
-                    // Set the clip data as the clipboard's primary clip.
-                    clipboardManager.setPrimaryClip(srcImageAnchorTypeClipData);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add a Save URL entry.
-                menu.add(R.string.save_url).setOnMenuItemClickListener((MenuItem item) -> {
-                    // Prepare the save dialog.  The dialog will be displayed once the file size and the content disposition have been acquired.
-                    new PrepareSaveDialog(this, this, getSupportFragmentManager(), StoragePermissionDialog.SAVE_URL, currentWebView.getSettings().getUserAgentString(),
-                            currentWebView.getAcceptFirstPartyCookies()).execute(linkUrl);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add an empty Cancel entry, which by default closes the context menu.
-                menu.add(R.string.cancel);
-                break;
-
-            case WebView.HitTestResult.EMAIL_TYPE:
-                // Get the target URL.
-                linkUrl = hitTestResult.getExtra();
-
-                // Set the target URL as the title of the `ContextMenu`.
-                menu.setHeaderTitle(linkUrl);
-
-                // Add a Write Email entry.
-                menu.add(R.string.write_email).setOnMenuItemClickListener(item -> {
-                    // Use `ACTION_SENDTO` instead of `ACTION_SEND` so that only email programs are launched.
-                    Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
-
-                    // Parse the url and set it as the data for the `Intent`.
-                    emailIntent.setData(Uri.parse("mailto:" + linkUrl));
-
-                    // `FLAG_ACTIVITY_NEW_TASK` opens the email program in a new task instead as part of Privacy Browser.
-                    emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-                    try {
-                        // Make it so.
-                        startActivity(emailIntent);
-                    } catch (ActivityNotFoundException exception) {
-                        // Display a snackbar.
-                        Snackbar.make(currentWebView, getString(R.string.error) + "  " + exception, Snackbar.LENGTH_INDEFINITE).show();
-                    }
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add a Copy Email Address entry.
-                menu.add(R.string.copy_email_address).setOnMenuItemClickListener(item -> {
-                    // Save the email address in a `ClipData`.
-                    ClipData srcEmailTypeClipData = ClipData.newPlainText(getString(R.string.email_address), linkUrl);
-
-                    // Set the `ClipData` as the clipboard's primary clip.
-                    clipboardManager.setPrimaryClip(srcEmailTypeClipData);
-
-                    // Consume the event.
-                    return true;
-                });
-
-                // Add an empty Cancel entry, which by default closes the context menu.
-                menu.add(R.string.cancel);
-                break;
-        }
-    }
-
-    @Override
-    public void onCreateBookmark(DialogFragment dialogFragment, Bitmap favoriteIconBitmap) {
-        // Get a handle for the bookmarks list view.
-        ListView bookmarksListView = findViewById(R.id.bookmarks_drawer_listview);
-
-        // Get the dialog.
-        Dialog dialog = dialogFragment.getDialog();
-
-        // Remove the incorrect lint warning below that the dialog might be null.
-        assert dialog != null;
-
-        // Get the views from the dialog fragment.
-        EditText createBookmarkNameEditText = dialog.findViewById(R.id.create_bookmark_name_edittext);
-        EditText createBookmarkUrlEditText = dialog.findViewById(R.id.create_bookmark_url_edittext);
-
-        // Extract the strings from the edit texts.
-        String bookmarkNameString = createBookmarkNameEditText.getText().toString();
-        String bookmarkUrlString = createBookmarkUrlEditText.getText().toString();
-
-        // Create a favorite icon byte array output stream.
-        ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
-
-        // Convert the favorite icon bitmap to a byte array.  `0` is for lossless compression (the only option for a PNG).
-        favoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream);
-
-        // Convert the favorite icon byte array stream to a byte array.
-        byte[] favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray();
-
-        // Display the new bookmark below the current items in the (0 indexed) list.
-        int newBookmarkDisplayOrder = bookmarksListView.getCount();
-
-        // Create the bookmark.
-        bookmarksDatabaseHelper.createBookmark(bookmarkNameString, bookmarkUrlString, currentBookmarksFolder, newBookmarkDisplayOrder, favoriteIconByteArray);
-
-        // Update the bookmarks cursor with the current contents of this folder.
-        bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentBookmarksFolder);
-
-        // Update the list view.
-        bookmarksCursorAdapter.changeCursor(bookmarksCursor);
-
-        // Scroll to the new bookmark.
-        bookmarksListView.setSelection(newBookmarkDisplayOrder);
-    }
-
-    @Override
-    public void onCreateBookmarkFolder(DialogFragment dialogFragment, @NonNull Bitmap favoriteIconBitmap) {
-        // Get a handle for the bookmarks list view.
-        ListView bookmarksListView = findViewById(R.id.bookmarks_drawer_listview);
-
-        // Get the dialog.
-        Dialog dialog = dialogFragment.getDialog();
-
-        // Remove the incorrect lint warning below that the dialog might be null.
-        assert dialog != null;
-
-        // Get handles for the views in the dialog fragment.
-        EditText createFolderNameEditText = dialog.findViewById(R.id.create_folder_name_edittext);
-        RadioButton defaultFolderIconRadioButton = dialog.findViewById(R.id.create_folder_default_icon_radiobutton);
-        ImageView folderIconImageView = dialog.findViewById(R.id.create_folder_default_icon);
-
-        // Get new folder name string.
-        String folderNameString = createFolderNameEditText.getText().toString();
-
-        // Create a folder icon bitmap.
-        Bitmap folderIconBitmap;
-
-        // Set the folder icon bitmap according to the dialog.
-        if (defaultFolderIconRadioButton.isChecked()) {  // Use the default folder icon.
-            // Get the default folder icon drawable.
-            Drawable folderIconDrawable = folderIconImageView.getDrawable();
-
-            // Convert the folder icon drawable to a bitmap drawable.
-            BitmapDrawable folderIconBitmapDrawable = (BitmapDrawable) folderIconDrawable;
-
-            // Convert the folder icon bitmap drawable to a bitmap.
-            folderIconBitmap = folderIconBitmapDrawable.getBitmap();
-        } else {  // Use the WebView favorite icon.
-            // Copy the favorite icon bitmap to the folder icon bitmap.
-            folderIconBitmap = favoriteIconBitmap;
-        }
-
-        // Create a folder icon byte array output stream.
-        ByteArrayOutputStream folderIconByteArrayOutputStream = new ByteArrayOutputStream();
-
-        // Convert the folder icon bitmap to a byte array.  `0` is for lossless compression (the only option for a PNG).
-        folderIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, folderIconByteArrayOutputStream);
-
-        // Convert the folder icon byte array stream to a byte array.
-        byte[] folderIconByteArray = folderIconByteArrayOutputStream.toByteArray();
-
-        // Move all the bookmarks down one in the display order.
-        for (int i = 0; i < bookmarksListView.getCount(); i++) {
-            int databaseId = (int) bookmarksListView.getItemIdAtPosition(i);
-            bookmarksDatabaseHelper.updateDisplayOrder(databaseId, i + 1);
-        }
-
-        // Create the folder, which will be placed at the top of the `ListView`.
-        bookmarksDatabaseHelper.createFolder(folderNameString, currentBookmarksFolder, folderIconByteArray);
-
-        // Update the bookmarks cursor with the current contents of this folder.
-        bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentBookmarksFolder);
-
-        // Update the `ListView`.
-        bookmarksCursorAdapter.changeCursor(bookmarksCursor);
-
-        // Scroll to the new folder.
-        bookmarksListView.setSelection(0);
-    }
-
-    @Override
-    public void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId, Bitmap favoriteIconBitmap) {
-        // Remove the incorrect lint warning below that the dialog fragment might be null.
-        assert dialogFragment != null;
-
-        // Get the dialog.
-        Dialog dialog = dialogFragment.getDialog();
-
-        // Remove the incorrect lint warning below that the dialog might be null.
-        assert dialog != null;
-
-        // Get handles for the views from the dialog.
-        EditText editFolderNameEditText = dialog.findViewById(R.id.edit_folder_name_edittext);
-        RadioButton currentFolderIconRadioButton = dialog.findViewById(R.id.edit_folder_current_icon_radiobutton);
-        RadioButton defaultFolderIconRadioButton = dialog.findViewById(R.id.edit_folder_default_icon_radiobutton);
-        ImageView defaultFolderIconImageView = dialog.findViewById(R.id.edit_folder_default_icon_imageview);
-
-        // Get the new folder name.
-        String newFolderNameString = editFolderNameEditText.getText().toString();
-
-        // Check if the favorite icon has changed.
-        if (currentFolderIconRadioButton.isChecked()) {  // Only the name has changed.
-            // Update the name in the database.
-            bookmarksDatabaseHelper.updateFolder(selectedFolderDatabaseId, oldFolderNameString, newFolderNameString);
-        } else if (!currentFolderIconRadioButton.isChecked() && newFolderNameString.equals(oldFolderNameString)) {  // Only the icon has changed.
-            // Create the new folder icon Bitmap.
-            Bitmap folderIconBitmap;
-
-            // Populate the new folder icon bitmap.
-            if (defaultFolderIconRadioButton.isChecked()) {
-                // Get the default folder icon drawable.
-                Drawable folderIconDrawable = defaultFolderIconImageView.getDrawable();
-
-                // Convert the folder icon drawable to a bitmap drawable.
-                BitmapDrawable folderIconBitmapDrawable = (BitmapDrawable) folderIconDrawable;
-
-                // Convert the folder icon bitmap drawable to a bitmap.
-                folderIconBitmap = folderIconBitmapDrawable.getBitmap();
-            } else {  // Use the `WebView` favorite icon.
-                // Copy the favorite icon bitmap to the folder icon bitmap.
-                folderIconBitmap = favoriteIconBitmap;
-            }
-
-            // Create a folder icon byte array output stream.
-            ByteArrayOutputStream newFolderIconByteArrayOutputStream = new ByteArrayOutputStream();
-
-            // Convert the folder icon bitmap to a byte array.  `0` is for lossless compression (the only option for a PNG).
-            folderIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, newFolderIconByteArrayOutputStream);
-
-            // Convert the folder icon byte array stream to a byte array.
-            byte[] newFolderIconByteArray = newFolderIconByteArrayOutputStream.toByteArray();
-
-            // Update the folder icon in the database.
-            bookmarksDatabaseHelper.updateFolder(selectedFolderDatabaseId, newFolderIconByteArray);
-        } else {  // The folder icon and the name have changed.
-            // Get the new folder icon `Bitmap`.
-            Bitmap folderIconBitmap;
-            if (defaultFolderIconRadioButton.isChecked()) {
-                // Get the default folder icon drawable.
-                Drawable folderIconDrawable = defaultFolderIconImageView.getDrawable();
-
-                // Convert the folder icon drawable to a bitmap drawable.
-                BitmapDrawable folderIconBitmapDrawable = (BitmapDrawable) folderIconDrawable;
-
-                // Convert the folder icon bitmap drawable to a bitmap.
-                folderIconBitmap = folderIconBitmapDrawable.getBitmap();
-            } else {  // Use the `WebView` favorite icon.
-                // Copy the favorite icon bitmap to the folder icon bitmap.
-                folderIconBitmap = favoriteIconBitmap;
-            }
-
-            // Create a folder icon byte array output stream.
-            ByteArrayOutputStream newFolderIconByteArrayOutputStream = new ByteArrayOutputStream();
-
-            // Convert the folder icon bitmap to a byte array.  `0` is for lossless compression (the only option for a PNG).
-            folderIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, newFolderIconByteArrayOutputStream);
-
-            // Convert the folder icon byte array stream to a byte array.
-            byte[] newFolderIconByteArray = newFolderIconByteArrayOutputStream.toByteArray();
-
-            // Update the folder name and icon in the database.
-            bookmarksDatabaseHelper.updateFolder(selectedFolderDatabaseId, oldFolderNameString, newFolderNameString, newFolderIconByteArray);
-        }
-
-        // Update the bookmarks cursor with the current contents of this folder.
-        bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentBookmarksFolder);
-
-        // Update the `ListView`.
-        bookmarksCursorAdapter.changeCursor(bookmarksCursor);
-    }
-
-    // Override `onBackPressed()` to handle the navigation drawer and and the WebViews.
-    @Override
-    public void onBackPressed() {
-        // Check the different options for processing `back`.
-        if (drawerLayout.isDrawerVisible(GravityCompat.START)) {  // The navigation drawer is open.
-            // Close the navigation drawer.
-            drawerLayout.closeDrawer(GravityCompat.START);
-        } else if (drawerLayout.isDrawerVisible(GravityCompat.END)){  // The bookmarks drawer is open.
-            // close the bookmarks drawer.
-            drawerLayout.closeDrawer(GravityCompat.END);
-        } else if (displayingFullScreenVideo) {  // A full screen video is shown.
-            // Get a handle for the layouts.
-            FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout);
-            RelativeLayout mainContentRelativeLayout = findViewById(R.id.main_content_relativelayout);
-            FrameLayout fullScreenVideoFrameLayout = findViewById(R.id.full_screen_video_framelayout);
-
-            // Re-enable the screen timeout.
-            fullScreenVideoFrameLayout.setKeepScreenOn(false);
-
-            // Unset the full screen video flag.
-            displayingFullScreenVideo = false;
-
-            // Remove all the views from the full screen video frame layout.
-            fullScreenVideoFrameLayout.removeAllViews();
-
-            // Hide the full screen video frame layout.
-            fullScreenVideoFrameLayout.setVisibility(View.GONE);
-
-            // Enable the sliding drawers.
-            drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
-
-            // Show the main content relative layout.
-            mainContentRelativeLayout.setVisibility(View.VISIBLE);
-
-            // Apply the appropriate full screen mode flags.
-            if (fullScreenBrowsingModeEnabled && inFullScreenBrowsingMode) {  // Privacy Browser is currently in full screen browsing mode.
-                // Hide the banner ad in the free flavor.
-                if (BuildConfig.FLAVOR.contentEquals("free")) {
-                    AdHelper.hideAd(findViewById(R.id.adview));
-                }
-
-                /* Hide the system bars.
-                 * SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen.
-                 * SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN makes the root frame layout fill the area that is normally reserved for the status bar.
-                 * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen.
-                 * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically re-hides them after they are shown.
-                 */
-                rootFrameLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
-                        View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
-
-                // Reload the website if the app bar is hidden.  Otherwise, there is some bug in Android that causes the WebView to be entirely black.
-                if (hideAppBar) {
-                    // Reload the WebView.
-                    currentWebView.reload();
-                }
-            } else {  // Switch to normal viewing mode.
-                // Remove the `SYSTEM_UI` flags from the root frame layout.
-                rootFrameLayout.setSystemUiVisibility(0);
-            }
-
-            // Reload the ad for the free flavor if not in full screen mode.
-            if (BuildConfig.FLAVOR.contentEquals("free") && !inFullScreenBrowsingMode) {
-                // Reload the ad.
-                AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_unit_id));
-            }
-        } else if (currentWebView.canGoBack()) {  // There is at least one item in the current WebView history.
-            // Get the current web back forward list.
-            WebBackForwardList webBackForwardList = currentWebView.copyBackForwardList();
-
-            // Get the previous entry URL.
-            String previousUrl = webBackForwardList.getItemAtIndex(webBackForwardList.getCurrentIndex() - 1).getUrl();
-
-            // Apply the domain settings.
-            applyDomainSettings(currentWebView, previousUrl, false, false, false);
-
-            // Go back.
-            currentWebView.goBack();
-        } else if (tabLayout.getTabCount() > 1) {  // There are at least two tabs.
-            // Close the current tab.
-            closeCurrentTab();
-        } else {  // There isn't anything to do in Privacy Browser.
-            // Close Privacy Browser.  `finishAndRemoveTask()` also removes Privacy Browser from the recent app list.
-            if (Build.VERSION.SDK_INT >= 21) {
-                finishAndRemoveTask();
-            } else {
-                finish();
-            }
-
-            // Manually kill Privacy Browser.  Otherwise, it is glitchy when restarted.
-            System.exit(0);
-        }
-    }
-
-    // Process the results of a file browse.
-    @Override
-    public void onActivityResult(int requestCode, int resultCode, Intent returnedIntent) {
-        // Run the default commands.
-        super.onActivityResult(requestCode, resultCode, returnedIntent);
-
-        // Run the commands that correlate to the specified request code.
-        switch (requestCode) {
-            case BROWSE_FILE_UPLOAD_REQUEST_CODE:
-                // File uploads only work on API >= 21.
-                if (Build.VERSION.SDK_INT >= 21) {
-                    // Pass the file to the WebView.
-                    fileChooserCallback.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, returnedIntent));
-                }
-                break;
-
-            case BROWSE_SAVE_WEBPAGE_REQUEST_CODE:
-                // Don't do anything if the user pressed back from the file picker.
-                if (resultCode == Activity.RESULT_OK) {
-                    // Get a handle for the save dialog fragment.
-                    DialogFragment saveWebpageDialogFragment = (DialogFragment) getSupportFragmentManager().findFragmentByTag(getString(R.string.save_dialog));
-
-                    // Only update the file name if the dialog still exists.
-                    if (saveWebpageDialogFragment != null) {
-                        // Get a handle for the save webpage dialog.
-                        Dialog saveWebpageDialog = saveWebpageDialogFragment.getDialog();
-
-                        // Remove the incorrect lint warning below that the dialog might be null.
-                        assert saveWebpageDialog != null;
-
-                        // Get a handle for the file name edit text.
-                        EditText fileNameEditText = saveWebpageDialog.findViewById(R.id.file_name_edittext);
-                        TextView fileExistsWarningTextView = saveWebpageDialog.findViewById(R.id.file_exists_warning_textview);
-
-                        // Instantiate the file name helper.
-                        FileNameHelper fileNameHelper = new FileNameHelper();
-
-                        // Get the file path if it isn't null.
-                        if (returnedIntent.getData() != null) {
-                            // Convert the file name URI to a file name path.
-                            String fileNamePath = fileNameHelper.convertUriToFileNamePath(returnedIntent.getData());
-
-                            // Set the file name path as the text of the file name edit text.
-                            fileNameEditText.setText(fileNamePath);
-
-                            // Move the cursor to the end of the file name edit text.
-                            fileNameEditText.setSelection(fileNamePath.length());
-
-                            // Hide the file exists warning.
-                            fileExistsWarningTextView.setVisibility(View.GONE);
-                        }
-                    }
-                }
-                break;
-
-            case BROWSE_OPEN_REQUEST_CODE:
-                // Don't do anything if the user pressed back from the file picker.
-                if (resultCode == Activity.RESULT_OK) {
-                    // Get a handle for the open dialog fragment.
-                    DialogFragment openDialogFragment = (DialogFragment) getSupportFragmentManager().findFragmentByTag(getString(R.string.open));
-
-                    // Only update the file name if the dialog still exists.
-                    if (openDialogFragment != null) {
-                        // Get a handle for the open dialog.
-                        Dialog openDialog = openDialogFragment.getDialog();
-
-                        // Remove the incorrect lint warning below that the dialog might be null.
-                        assert openDialog != null;
-
-                        // Get a handle for the file name edit text.
-                        EditText fileNameEditText = openDialog.findViewById(R.id.file_name_edittext);
-
-                        // Instantiate the file name helper.
-                        FileNameHelper fileNameHelper = new FileNameHelper();
-
-                        // Get the file path if it isn't null.
-                        if (returnedIntent.getData() != null) {
-                            // Convert the file name URI to a file name path.
-                            String fileNamePath = fileNameHelper.convertUriToFileNamePath(returnedIntent.getData());
-
-                            // Set the file name path as the text of the file name edit text.
-                            fileNameEditText.setText(fileNamePath);
-
-                            // Move the cursor to the end of the file name edit text.
-                            fileNameEditText.setSelection(fileNamePath.length());
-                        }
-                    }
-                }
-                break;
-        }
-    }
-
-    private void loadUrlFromTextBox() {
-        // Get a handle for the URL edit text.
-        EditText urlEditText = findViewById(R.id.url_edittext);
-
-        // Get the text from urlTextBox and convert it to a string.  trim() removes white spaces from the beginning and end of the string.
-        String unformattedUrlString = urlEditText.getText().toString().trim();
-
-        // Initialize the formatted URL string.
-        String url = "";
-
-        // Check to see if `unformattedUrlString` is a valid URL.  Otherwise, convert it into a search.
-        if (unformattedUrlString.startsWith("content://")) {  // This is a Content URL.
-            // Load the entire content URL.
-            url = unformattedUrlString;
-        } else if (Patterns.WEB_URL.matcher(unformattedUrlString).matches() || unformattedUrlString.startsWith("http://") || unformattedUrlString.startsWith("https://") ||
-                unformattedUrlString.startsWith("file://")) {  // This is a standard URL.
-            // Add `https://` at the beginning if there is no protocol.  Otherwise the app will segfault.
-            if (!unformattedUrlString.startsWith("http") && !unformattedUrlString.startsWith("file://") && !unformattedUrlString.startsWith("content://")) {
-                unformattedUrlString = "https://" + unformattedUrlString;
-            }
-
-            // Initialize `unformattedUrl`.
-            URL unformattedUrl = null;
-
-            // Convert `unformattedUrlString` to a `URL`, then to a `URI`, and then back to a `String`, which sanitizes the input and adds in any missing components.
-            try {
-                unformattedUrl = new URL(unformattedUrlString);
-            } catch (MalformedURLException e) {
-                e.printStackTrace();
-            }
-
-            // The ternary operator (? :) makes sure that a null pointer exception is not thrown, which would happen if `.get` was called on a `null` value.
-            String scheme = unformattedUrl != null ? unformattedUrl.getProtocol() : null;
-            String authority = unformattedUrl != null ? unformattedUrl.getAuthority() : null;
-            String path = unformattedUrl != null ? unformattedUrl.getPath() : null;
-            String query = unformattedUrl != null ? unformattedUrl.getQuery() : null;
-            String fragment = unformattedUrl != null ? unformattedUrl.getRef() : null;
-
-            // Build the URI.
-            Uri.Builder uri = new Uri.Builder();
-            uri.scheme(scheme).authority(authority).path(path).query(query).fragment(fragment);
-
-            // Decode the URI as a UTF-8 string in.
-            try {
-                url = URLDecoder.decode(uri.build().toString(), "UTF-8");
-            } catch (UnsupportedEncodingException exception) {
-                // Do nothing.  The formatted URL string will remain blank.
-            }
-        } else if (!unformattedUrlString.isEmpty()){  // This is not a URL, but rather a search string.
-            // Create an encoded URL String.
-            String encodedUrlString;
-
-            // Sanitize the search input.
-            try {
-                encodedUrlString = URLEncoder.encode(unformattedUrlString, "UTF-8");
-            } catch (UnsupportedEncodingException exception) {
-                encodedUrlString = "";
-            }
-
-            // Add the base search URL.
-            url = searchURL + encodedUrlString;
-        }
-
-        // Clear the focus from the URL edit text.  Otherwise, proximate typing in the box will retain the colorized formatting instead of being reset during refocus.
-        urlEditText.clearFocus();
-
-        // Make it so.
-        loadUrl(currentWebView, url);
-    }
-
-    private void loadUrl(NestedScrollWebView nestedScrollWebView, String url) {
-        // Sanitize the URL.
-        url = sanitizeUrl(url);
-
-        // Apply the domain settings and load the URL.
-        applyDomainSettings(nestedScrollWebView, url, true, false, true);
-    }
-
-    public void findPreviousOnPage(View view) {
-        // Go to the previous highlighted phrase on the page.  `false` goes backwards instead of forwards.
-        currentWebView.findNext(false);
-    }
-
-    public void findNextOnPage(View view) {
-        // Go to the next highlighted phrase on the page. `true` goes forwards instead of backwards.
-        currentWebView.findNext(true);
-    }
-
-    public void closeFindOnPage(View view) {
-        // Get a handle for the views.
-        Toolbar toolbar = findViewById(R.id.toolbar);
-        LinearLayout findOnPageLinearLayout = findViewById(R.id.find_on_page_linearlayout);
-        EditText findOnPageEditText = findViewById(R.id.find_on_page_edittext);
-
-        // Delete the contents of `find_on_page_edittext`.
-        findOnPageEditText.setText(null);
-
-        // Clear the highlighted phrases if the WebView is not null.
-        if (currentWebView != null) {
-            currentWebView.clearMatches();
-        }
-
-        // Hide the find on page linear layout.
-        findOnPageLinearLayout.setVisibility(View.GONE);
-
-        // Show the toolbar.
-        toolbar.setVisibility(View.VISIBLE);
-
-        // Get a handle for the input method manager.
-        InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
-
-        // Remove the lint warning below that the input method manager might be null.
-        assert inputMethodManager != null;
-
-        // Hide the keyboard.
-        inputMethodManager.hideSoftInputFromWindow(toolbar.getWindowToken(), 0);
-    }
-
-    @Override
-    public void onApplyNewFontSize(DialogFragment dialogFragment) {
-        // Remove the incorrect lint warning below that the dialog fragment might be null.
-        assert dialogFragment != null;
-
-        // Get the dialog.
-        Dialog dialog = dialogFragment.getDialog();
-
-        // Remove the incorrect lint warning below tha the dialog might be null.
-        assert dialog != null;
-
-        // Get a handle for the font size edit text.
-        EditText fontSizeEditText = dialog.findViewById(R.id.font_size_edittext);
-
-        // Initialize the new font size variable with the current font size.
-        int newFontSize = currentWebView.getSettings().getTextZoom();
-
-        // Get the font size from the edit text.
-        try {
-            newFontSize = Integer.parseInt(fontSizeEditText.getText().toString());
-        } catch (Exception exception) {
-            // If the edit text does not contain a valid font size do nothing.
-        }
-
-        // Apply the new font size.
-        currentWebView.getSettings().setTextZoom(newFontSize);
-    }
-
-    @Override
-    public void onOpen(DialogFragment dialogFragment) {
-        // Get the dialog.
-        Dialog dialog = dialogFragment.getDialog();
-
-        // Remove the incorrect lint warning below that the dialog might be null.
-        assert dialog != null;
-
-        // Get a handle for the file name edit text.
-        EditText fileNameEditText = dialog.findViewById(R.id.file_name_edittext);
-
-        // Get the file path string.
-        openFilePath = fileNameEditText.getText().toString();
-
-        // Apply the domain settings.  This resets the favorite icon and removes any domain settings.
-        applyDomainSettings(currentWebView, "file://" + openFilePath, true, false, false);
-
-        // Check to see if the storage permission is needed.
-        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {  // The storage permission has been granted.
-            // Open the file.
-            currentWebView.loadUrl("file://" + openFilePath);
-        } else {  // The storage permission has not been granted.
-            // Get the external private directory file.
-            File externalPrivateDirectoryFile = getExternalFilesDir(null);
-
-            // Remove the incorrect lint error below that the file might be null.
-            assert externalPrivateDirectoryFile != null;
-
-            // Get the external private directory string.
-            String externalPrivateDirectory = externalPrivateDirectoryFile.toString();
-
-            // Check to see if the file path is in the external private directory.
-            if (openFilePath.startsWith(externalPrivateDirectory)) {  // the file path is in the external private directory.
-                // Open the file.
-                currentWebView.loadUrl("file://" + openFilePath);
-            } else {  // The file path is in a public directory.
-                // Check if the user has previously denied the storage permission.
-                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {  // Show a dialog explaining the request first.
-                    // Instantiate the storage permission alert dialog.
-                    DialogFragment storagePermissionDialogFragment = StoragePermissionDialog.displayDialog(StoragePermissionDialog.OPEN);
-
-                    // Show the storage permission alert dialog.  The permission will be requested the the dialog is closed.
-                    storagePermissionDialogFragment.show(getSupportFragmentManager(), getString(R.string.storage_permission));
-                } else {  // Show the permission request directly.
-                    // Request the write external storage permission.  The file will be opened when it finishes.
-                    ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, StoragePermissionDialog.OPEN);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void onSaveWebpage(int saveType, String originalUrlString, DialogFragment dialogFragment) {
-        // Get the dialog.
-        Dialog dialog = dialogFragment.getDialog();
-
-        // Remove the incorrect lint warning below that the dialog might be null.
-        assert dialog != null;
-
-        // Get a handle for the edit texts.
-        EditText urlEditText = dialog.findViewById(R.id.url_edittext);
-        EditText fileNameEditText = dialog.findViewById(R.id.file_name_edittext);
-
-        // Store the URL.
-        if ((originalUrlString != null) && originalUrlString.startsWith("data:")) {
-            // Save the original URL.
-            saveWebpageUrl = originalUrlString;
-        } else {
-            // Get the URL from the edit text, which may have been modified.
-            saveWebpageUrl = urlEditText.getText().toString();
-        }
-
-        // Get the file path from the edit text.
-        saveWebpageFilePath = fileNameEditText.getText().toString();
-
-        // Check to see if the storage permission is needed.
-        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {  // The storage permission has been granted.
-            //Save the webpage according to the save type.
-            switch (saveType) {
-                case StoragePermissionDialog.SAVE_URL:
-                    // Save the URL.
-                    new SaveUrl(this, this, saveWebpageFilePath, currentWebView.getSettings().getUserAgentString(), currentWebView.getAcceptFirstPartyCookies()).execute(saveWebpageUrl);
-                    break;
-
-                case StoragePermissionDialog.SAVE_ARCHIVE:
-                    // Save the webpage archive.
-                    saveWebpageArchive(saveWebpageFilePath);
-                    break;
-
-                case StoragePermissionDialog.SAVE_IMAGE:
-                    // Save the webpage image.
-                    new SaveWebpageImage(this, this, saveWebpageFilePath, currentWebView).execute();
-                    break;
-            }
-
-            // Reset the strings.
-            saveWebpageUrl = "";
-            saveWebpageFilePath = "";
-        } else {  // The storage permission has not been granted.
-            // Get the external private directory file.
-            File externalPrivateDirectoryFile = getExternalFilesDir(null);
-
-            // Remove the incorrect lint error below that the file might be null.
-            assert externalPrivateDirectoryFile != null;
-
-            // Get the external private directory string.
-            String externalPrivateDirectory = externalPrivateDirectoryFile.toString();
-
-            // Check to see if the file path is in the external private directory.
-            if (saveWebpageFilePath.startsWith(externalPrivateDirectory)) {  // The file path is in the external private directory.
-                // Save the webpage according to the save type.
-                switch (saveType) {
-                    case StoragePermissionDialog.SAVE_URL:
-                        // Save the URL.
-                        new SaveUrl(this, this, saveWebpageFilePath, currentWebView.getSettings().getUserAgentString(), currentWebView.getAcceptFirstPartyCookies()).execute(saveWebpageUrl);
-                        break;
-
-                    case StoragePermissionDialog.SAVE_ARCHIVE:
-                        // Save the webpage archive.
-                        saveWebpageArchive(saveWebpageFilePath);
-                        break;
-
-                    case StoragePermissionDialog.SAVE_IMAGE:
-                        // Save the webpage image.
-                        new SaveWebpageImage(this, this, saveWebpageFilePath, currentWebView).execute();
-                        break;
-                }
-
-                // Reset the strings.
-                saveWebpageUrl = "";
-                saveWebpageFilePath = "";
-            } else {  // The file path is in a public directory.
-                // Check if the user has previously denied the storage permission.
-                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {  // Show a dialog explaining the request first.
-                    // Instantiate the storage permission alert dialog.
-                    DialogFragment storagePermissionDialogFragment = StoragePermissionDialog.displayDialog(saveType);
-
-                    // Show the storage permission alert dialog.  The permission will be requested when the dialog is closed.
-                    storagePermissionDialogFragment.show(getSupportFragmentManager(), getString(R.string.storage_permission));
-                } else {  // Show the permission request directly.
-                    // Request the write external storage permission according to the save type.  The URL will be saved when it finishes.
-                    ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, saveType);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void onCloseStoragePermissionDialog(int requestType) {
-        // Request the write external storage permission according to the request type.  The file will be opened when it finishes.
-        ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestType);
-
-    }
-
-    @Override
-    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
-        //Only process the results if they exist (this method is triggered when a dialog is presented the first time for an app, but no grant results are included).
-        if (grantResults.length > 0) {
-            switch (requestCode) {
-                case StoragePermissionDialog.OPEN:
-                    // Check to see if the storage permission was granted.  If the dialog was canceled the grant results will be empty.
-                    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {  // The storage permission was granted.
-                        // Load the file.
-                        currentWebView.loadUrl("file://" + openFilePath);
-                    } else {  // The storage permission was not granted.
-                        // Display an error snackbar.
-                        Snackbar.make(currentWebView, getString(R.string.cannot_use_location), Snackbar.LENGTH_LONG).show();
-                    }
-                    break;
-
-                case StoragePermissionDialog.SAVE_URL:
-                    // Check to see if the storage permission was granted.  If the dialog was canceled the grant results will be empty.
-                    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {  // The storage permission was granted.
-                        // Save the raw URL.
-                        new SaveUrl(this, this, saveWebpageFilePath, currentWebView.getSettings().getUserAgentString(), currentWebView.getAcceptFirstPartyCookies()).execute(saveWebpageUrl);
-                    } else {  // The storage permission was not granted.
-                        // Display an error snackbar.
-                        Snackbar.make(currentWebView, getString(R.string.cannot_use_location), Snackbar.LENGTH_LONG).show();
-                    }
-                    break;
-
-                case StoragePermissionDialog.SAVE_ARCHIVE:
-                    // Check to see if the storage permission was granted.  If the dialog was canceled the grant results will be empty.
-                    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {  // The storage permission was granted.
-                        // Save the webpage archive.
-                        saveWebpageArchive(saveWebpageFilePath);
-                    } else {  // The storage permission was not granted.
-                        // Display an error snackbar.
-                        Snackbar.make(currentWebView, getString(R.string.cannot_use_location), Snackbar.LENGTH_LONG).show();
-                    }
-                    break;
-
-                case StoragePermissionDialog.SAVE_IMAGE:
-                    // Check to see if the storage permission was granted.  If the dialog was canceled the grant results will be empty.
-                    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {  // The storage permission was granted.
-                        // Save the webpage image.
-                        new SaveWebpageImage(this, this, saveWebpageFilePath, currentWebView).execute();
-                    } else {  // The storage permission was not granted.
-                        // Display an error snackbar.
-                        Snackbar.make(currentWebView, getString(R.string.cannot_use_location), Snackbar.LENGTH_LONG).show();
-                    }
-                    break;
-            }
-
-            // Reset the strings.
-            openFilePath = "";
-            saveWebpageUrl = "";
-            saveWebpageFilePath = "";
-        }
-    }
-
-    private void initializeApp() {
-        // Get a handle for the input method.
-        InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
-
-        // Remove the lint warning below that the input method manager might be null.
-        assert inputMethodManager != null;
-
-        // Initialize the gray foreground color spans for highlighting the URLs.  The deprecated `getResources()` must be used until API >= 23.
-        initialGrayColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.gray_500));
-        finalGrayColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.gray_500));
-
-        // Get the current theme status.
-        int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
-        // Set the red color span according to the theme.
-        if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
-            redColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.red_a700));
-        } else {
-            redColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.red_900));
-        }
-
-        // Get handles for the URL views.
-        EditText urlEditText = findViewById(R.id.url_edittext);
-
-        // Remove the formatting from the URL edit text when the user is editing the text.
-        urlEditText.setOnFocusChangeListener((View v, boolean hasFocus) -> {
-            if (hasFocus) {  // The user is editing the URL text box.
-                // Remove the highlighting.
-                urlEditText.getText().removeSpan(redColorSpan);
-                urlEditText.getText().removeSpan(initialGrayColorSpan);
-                urlEditText.getText().removeSpan(finalGrayColorSpan);
-            } else {  // The user has stopped editing the URL text box.
-                // Move to the beginning of the string.
-                urlEditText.setSelection(0);
-
-                // Reapply the highlighting.
-                highlightUrlText();
-            }
-        });
-
-        // Set the go button on the keyboard to load the URL in `urlTextBox`.
-        urlEditText.setOnKeyListener((View v, int keyCode, KeyEvent event) -> {
-            // If the event is a key-down event on the `enter` button, load the URL.
-            if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
-                // Load the URL into the mainWebView and consume the event.
-                loadUrlFromTextBox();
-
-                // If the enter key was pressed, consume the event.
-                return true;
-            } else {
-                // If any other key was pressed, do not consume the event.
-                return false;
-            }
-        });
-
-        // Create an Orbot status broadcast receiver.
-        orbotStatusBroadcastReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                // Store the content of the status message in `orbotStatus`.
-                orbotStatus = intent.getStringExtra("org.torproject.android.intent.extra.STATUS");
-
-                // If Privacy Browser is waiting on the proxy, load the website now that Orbot is connected.
-                if ((orbotStatus != null) && orbotStatus.equals("ON") && waitingForProxy) {
-                    // Reset the waiting for proxy status.
-                    waitingForProxy = false;
-
-                    // Get a handle for the waiting for proxy dialog.
-                    DialogFragment waitingForProxyDialogFragment = (DialogFragment) getSupportFragmentManager().findFragmentByTag(getString(R.string.waiting_for_proxy_dialog));
-
-                    // Dismiss the waiting for proxy dialog if it is displayed.
-                    if (waitingForProxyDialogFragment != null) {
-                        waitingForProxyDialogFragment.dismiss();
-                    }
-
-                    // Reload existing URLs and load any URLs that are waiting for the proxy.
-                    for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
-                        // Get the WebView tab fragment.
-                        WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
-
-                        // Get the fragment view.
-                        View fragmentView = webViewTabFragment.getView();
-
-                        // Only process the WebViews if they exist.
-                        if (fragmentView != null) {
-                            // Get the nested scroll WebView from the tab fragment.
-                            NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
-
-                            // Get the waiting for proxy URL string.
-                            String waitingForProxyUrlString = nestedScrollWebView.getWaitingForProxyUrlString();
-
-                            // Load the pending URL if it exists.
-                            if (!waitingForProxyUrlString.isEmpty()) {  // A URL is waiting to be loaded.
-                                // Load the URL.
-                                loadUrl(nestedScrollWebView, waitingForProxyUrlString);
-
-                                // Reset the waiting for proxy URL string.
-                                nestedScrollWebView.resetWaitingForProxyUrlString();
-                            } else {  // No URL is waiting to be loaded.
-                                // Reload the existing URL.
-                                nestedScrollWebView.reload();
-                            }
-                        }
-                    }
-                }
-            }
-        };
-
-        // Register the Orbot status broadcast receiver on `this` context.
-        this.registerReceiver(orbotStatusBroadcastReceiver, new IntentFilter("org.torproject.android.intent.action.STATUS"));
-
-        // Get handles for views that need to be modified.
-        NavigationView navigationView = findViewById(R.id.navigationview);
-        SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
-        ListView bookmarksListView = findViewById(R.id.bookmarks_drawer_listview);
-        FloatingActionButton launchBookmarksActivityFab = findViewById(R.id.launch_bookmarks_activity_fab);
-        FloatingActionButton createBookmarkFolderFab = findViewById(R.id.create_bookmark_folder_fab);
-        FloatingActionButton createBookmarkFab = findViewById(R.id.create_bookmark_fab);
-        EditText findOnPageEditText = findViewById(R.id.find_on_page_edittext);
-
-        // Listen for touches on the navigation menu.
-        navigationView.setNavigationItemSelectedListener(this);
-
-        // Get handles for the navigation menu and the back and forward menu items.
-        Menu navigationMenu = navigationView.getMenu();
-        MenuItem navigationBackMenuItem = navigationMenu.findItem(R.id.back);
-        MenuItem navigationForwardMenuItem = navigationMenu.findItem(R.id.forward);
-        MenuItem navigationHistoryMenuItem = navigationMenu.findItem(R.id.history);
-        MenuItem navigationRequestsMenuItem = navigationMenu.findItem(R.id.requests);
-
-        // Update the web view pager every time a tab is modified.
-        webViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
-            @Override
-            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
-                // Do nothing.
-            }
-
-            @Override
-            public void onPageSelected(int position) {
-                // Close the find on page bar if it is open.
-                closeFindOnPage(null);
-
-                // Set the current WebView.
-                setCurrentWebView(position);
-
-                // Select the corresponding tab if it does not match the currently selected page.  This will happen if the page was scrolled by creating a new tab.
-                if (tabLayout.getSelectedTabPosition() != position) {
-                    // Wait until the new tab has been created.
-                    tabLayout.post(() -> {
-                        // Get a handle for the tab.
-                        TabLayout.Tab tab = tabLayout.getTabAt(position);
-
-                        // Assert that the tab is not null.
-                        assert tab != null;
-
-                        // Select the tab.
-                        tab.select();
-                    });
-                }
-            }
-
-            @Override
-            public void onPageScrollStateChanged(int state) {
-                // Do nothing.
-            }
-        });
-
-        // Display the View SSL Certificate dialog when the currently selected tab is reselected.
-        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
-            @Override
-            public void onTabSelected(TabLayout.Tab tab) {
-                // Select the same page in the view pager.
-                webViewPager.setCurrentItem(tab.getPosition());
-            }
-
-            @Override
-            public void onTabUnselected(TabLayout.Tab tab) {
-                // Do nothing.
-            }
-
-            @Override
-            public void onTabReselected(TabLayout.Tab tab) {
-                // Instantiate the View SSL Certificate dialog.
-                DialogFragment viewSslCertificateDialogFragment = ViewSslCertificateDialog.displayDialog(currentWebView.getWebViewFragmentId());
-
-                // Display the View SSL Certificate dialog.
-                viewSslCertificateDialogFragment.show(getSupportFragmentManager(), getString(R.string.view_ssl_certificate));
-            }
-        });
-
-        // Set the launch bookmarks activity FAB to launch the bookmarks activity.
-        launchBookmarksActivityFab.setOnClickListener(v -> {
-            // Get a copy of the favorite icon bitmap.
-            Bitmap favoriteIconBitmap = currentWebView.getFavoriteOrDefaultIcon();
-
-            // Create a favorite icon byte array output stream.
-            ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
-
-            // Convert the favorite icon bitmap to a byte array.  `0` is for lossless compression (the only option for a PNG).
-            favoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream);
-
-            // Convert the favorite icon byte array stream to a byte array.
-            byte[] favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray();
-
-            // Create an intent to launch the bookmarks activity.
-            Intent bookmarksIntent = new Intent(getApplicationContext(), BookmarksActivity.class);
-
-            // Add the extra information to the intent.
-            bookmarksIntent.putExtra("current_url", currentWebView.getUrl());
-            bookmarksIntent.putExtra("current_title", currentWebView.getTitle());
-            bookmarksIntent.putExtra("current_folder", currentBookmarksFolder);
-            bookmarksIntent.putExtra("favorite_icon_byte_array", favoriteIconByteArray);
-
-            // Make it so.
-            startActivity(bookmarksIntent);
-        });
-
-        // Set the create new bookmark folder FAB to display an alert dialog.
-        createBookmarkFolderFab.setOnClickListener(v -> {
-            // Create a create bookmark folder dialog.
-            DialogFragment createBookmarkFolderDialog = CreateBookmarkFolderDialog.createBookmarkFolder(currentWebView.getFavoriteOrDefaultIcon());
-
-            // Show the create bookmark folder dialog.
-            createBookmarkFolderDialog.show(getSupportFragmentManager(), getString(R.string.create_folder));
-        });
-
-        // Set the create new bookmark FAB to display an alert dialog.
-        createBookmarkFab.setOnClickListener(view -> {
-            // Instantiate the create bookmark dialog.
-            DialogFragment createBookmarkDialog = CreateBookmarkDialog.createBookmark(currentWebView.getUrl(), currentWebView.getTitle(), currentWebView.getFavoriteOrDefaultIcon());
-
-            // Display the create bookmark dialog.
-            createBookmarkDialog.show(getSupportFragmentManager(), getString(R.string.create_bookmark));
-        });
-
-        // Search for the string on the page whenever a character changes in the `findOnPageEditText`.
-        findOnPageEditText.addTextChangedListener(new TextWatcher() {
-            @Override
-            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-                // Do nothing.
-            }
-
-            @Override
-            public void onTextChanged(CharSequence s, int start, int before, int count) {
-                // Do nothing.
-            }
-
-            @Override
-            public void afterTextChanged(Editable s) {
-                // Search for the text in the WebView if it is not null.  Sometimes on resume after a period of non-use the WebView will be null.
-                if (currentWebView != null) {
-                    currentWebView.findAllAsync(findOnPageEditText.getText().toString());
-                }
-            }
-        });
-
-        // Set the `check mark` button for the `findOnPageEditText` keyboard to close the soft keyboard.
-        findOnPageEditText.setOnKeyListener((v, keyCode, event) -> {
-            if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {  // The `enter` key was pressed.
-                // Hide the soft keyboard.
-                inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0);
-
-                // Consume the event.
-                return true;
-            } else {  // A different key was pressed.
-                // Do not consume the event.
-                return false;
-            }
-        });
-
-        // Implement swipe to refresh.
-        swipeRefreshLayout.setOnRefreshListener(() -> currentWebView.reload());
-
-        // Store the default progress view offsets for use later in `initializeWebView()`.
-        defaultProgressViewStartOffset = swipeRefreshLayout.getProgressViewStartOffset();
-        defaultProgressViewEndOffset = swipeRefreshLayout.getProgressViewEndOffset();
-
-        // Set the refresh color scheme according to the theme.
-        if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
-            swipeRefreshLayout.setColorSchemeResources(R.color.blue_700);
-        } else {
-            swipeRefreshLayout.setColorSchemeResources(R.color.violet_500);
-        }
-
-        // Initialize a color background typed value.
-        TypedValue colorBackgroundTypedValue = new TypedValue();
-
-        // Get the color background from the theme.
-        getTheme().resolveAttribute(android.R.attr.colorBackground, colorBackgroundTypedValue, true);
-
-        // Get the color background int from the typed value.
-        int colorBackgroundInt = colorBackgroundTypedValue.data;
-
-        // Set the swipe refresh background color.
-        swipeRefreshLayout.setProgressBackgroundColorSchemeColor(colorBackgroundInt);
-
-        // The drawer titles identify the drawer layouts in accessibility mode.
-        drawerLayout.setDrawerTitle(GravityCompat.START, getString(R.string.navigation_drawer));
-        drawerLayout.setDrawerTitle(GravityCompat.END, getString(R.string.bookmarks));
-
-        // Initialize the bookmarks database helper.  The `0` specifies a database version, but that is ignored and set instead using a constant in `BookmarksDatabaseHelper`.
-        bookmarksDatabaseHelper = new BookmarksDatabaseHelper(this, null, null, 0);
-
-        // Initialize `currentBookmarksFolder`.  `""` is the home folder in the database.
-        currentBookmarksFolder = "";
-
-        // Load the home folder, which is `""` in the database.
-        loadBookmarksFolder();
-
-        bookmarksListView.setOnItemClickListener((parent, view, position, id) -> {
-            // Convert the id from long to int to match the format of the bookmarks database.
-            int databaseId = (int) id;
-
-            // Get the bookmark cursor for this ID.
-            Cursor bookmarkCursor = bookmarksDatabaseHelper.getBookmark(databaseId);
-
-            // Move the bookmark cursor to the first row.
-            bookmarkCursor.moveToFirst();
-
-            // Act upon the bookmark according to the type.
-            if (bookmarkCursor.getInt(bookmarkCursor.getColumnIndex(BookmarksDatabaseHelper.IS_FOLDER)) == 1) {  // The selected bookmark is a folder.
-                // Store the new folder name in `currentBookmarksFolder`.
-                currentBookmarksFolder = bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
-
-                // Load the new folder.
-                loadBookmarksFolder();
-            } else {  // The selected bookmark is not a folder.
-                // Load the bookmark URL.
-                loadUrl(currentWebView, bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_URL)));
-
-                // Close the bookmarks drawer.
-                drawerLayout.closeDrawer(GravityCompat.END);
-            }
-
-            // Close the `Cursor`.
-            bookmarkCursor.close();
-        });
-
-        bookmarksListView.setOnItemLongClickListener((parent, view, position, id) -> {
-            // Convert the database ID from `long` to `int`.
-            int databaseId = (int) id;
-
-            // Find out if the selected bookmark is a folder.
-            boolean isFolder = bookmarksDatabaseHelper.isFolder(databaseId);
-
-            if (isFolder) {
-                // Save the current folder name, which is used in `onSaveEditBookmarkFolder()`.
-                oldFolderNameString = bookmarksCursor.getString(bookmarksCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
-
-                // Instantiate the edit folder bookmark dialog.
-                DialogFragment editBookmarkFolderDialog = EditBookmarkFolderDialog.folderDatabaseId(databaseId, currentWebView.getFavoriteOrDefaultIcon());
-
-                // Show the edit folder bookmark dialog.
-                editBookmarkFolderDialog.show(getSupportFragmentManager(), getString(R.string.edit_folder));
-            } else {
-                // Get the bookmark cursor for this ID.
-                Cursor bookmarkCursor = bookmarksDatabaseHelper.getBookmark(databaseId);
-
-                // Move the bookmark cursor to the first row.
-                bookmarkCursor.moveToFirst();
-
-                // Load the bookmark in a new tab but do not switch to the tab or close the drawer.
-                addNewTab(bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_URL)), false);
-            }
-
-            // Consume the event.
-            return true;
-        });
-
-        // The drawer listener is used to update the navigation menu.
-        drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
-            @Override
-            public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
-            }
-
-            @Override
-            public void onDrawerOpened(@NonNull View drawerView) {
-            }
-
-            @Override
-            public void onDrawerClosed(@NonNull View drawerView) {
-            }
-
-            @Override
-            public void onDrawerStateChanged(int newState) {
-                if ((newState == DrawerLayout.STATE_SETTLING) || (newState == DrawerLayout.STATE_DRAGGING)) {  // A drawer is opening or closing.
-                    // Update the navigation menu items if the WebView is not null.
-                    if (currentWebView != null) {
-                        navigationBackMenuItem.setEnabled(currentWebView.canGoBack());
-                        navigationForwardMenuItem.setEnabled(currentWebView.canGoForward());
-                        navigationHistoryMenuItem.setEnabled((currentWebView.canGoBack() || currentWebView.canGoForward()));
-                        navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + currentWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
-
-                        // Hide the keyboard (if displayed).
-                        inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0);
-                    }
-
-                    // Clear the focus from from the URL text box and the WebView.  This removes any text selection markers and context menus, which otherwise draw above the open drawers.
-                    urlEditText.clearFocus();
-                    currentWebView.clearFocus();
-                }
-            }
-        });
-
-        // Replace the header that `WebView` creates for `X-Requested-With` with a null value.  The default value is the application ID (com.stoutner.privacybrowser.standard).
-        customHeaders.put("X-Requested-With", "");
-
-        // Inflate a bare WebView to get the default user agent.  It is not used to render content on the screen.
-        @SuppressLint("InflateParams") View webViewLayout = getLayoutInflater().inflate(R.layout.bare_webview, null, false);
-
-        // Get a handle for the WebView.
-        WebView bareWebView = webViewLayout.findViewById(R.id.bare_webview);
-
-        // Store the default user agent.
-        webViewDefaultUserAgent = bareWebView.getSettings().getUserAgentString();
-
-        // Destroy the bare WebView.
-        bareWebView.destroy();
-    }
-
-    private void applyAppSettings() {
-        // Get a handle for the shared preferences.
-        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
-
-        // Store the values from the shared preferences in variables.
-        incognitoModeEnabled = sharedPreferences.getBoolean("incognito_mode", false);
-        boolean doNotTrackEnabled = sharedPreferences.getBoolean("do_not_track", false);
-        sanitizeGoogleAnalytics = sharedPreferences.getBoolean("google_analytics", true);
-        sanitizeFacebookClickIds = sharedPreferences.getBoolean("facebook_click_ids", true);
-        sanitizeTwitterAmpRedirects = sharedPreferences.getBoolean("twitter_amp_redirects", true);
-        proxyMode = sharedPreferences.getString("proxy", getString(R.string.proxy_default_value));
-        fullScreenBrowsingModeEnabled = sharedPreferences.getBoolean("full_screen_browsing_mode", false);
-        hideAppBar = sharedPreferences.getBoolean("hide_app_bar", true);
-        scrollAppBar = sharedPreferences.getBoolean("scroll_app_bar", true);
-
-        // Apply the saved proxy mode if the app has been restarted.
-        if (savedProxyMode != null) {
-            // Apply the saved proxy mode.
-            proxyMode = savedProxyMode;
-
-            // Reset the saved proxy mode.
-            savedProxyMode = null;
-        }
-
-        // Get the search string.
-        String searchString = sharedPreferences.getString("search", getString(R.string.search_default_value));
-
-        // Set the search string.
-        if (searchString.equals("Custom URL")) {  // A custom search string is used.
-            searchURL = sharedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value));
-        } else {  // A custom search string is not used.
-            searchURL = searchString;
-        }
-
-        // Get a handle for the app compat delegate.
-        AppCompatDelegate appCompatDelegate = getDelegate();
-
-        // Get handles for the views that need to be modified.
-        FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout);
-        ActionBar actionBar = appCompatDelegate.getSupportActionBar();
-
-        // Remove the incorrect lint warning below that the action bar might be null.
-        assert actionBar != null;
-
-        // Apply the proxy.
-        applyProxy(false);
-
-        // Set Do Not Track status.
-        if (doNotTrackEnabled) {
-            customHeaders.put("DNT", "1");
-        } else {
-            customHeaders.remove("DNT");
-        }
-
-        // Get the current layout parameters.  Using coordinator layout parameters allows the `setBehavior()` command and using app bar layout parameters allows the `setScrollFlags()` command.
-        CoordinatorLayout.LayoutParams swipeRefreshLayoutParams = (CoordinatorLayout.LayoutParams) swipeRefreshLayout.getLayoutParams();
-        AppBarLayout.LayoutParams toolbarLayoutParams = (AppBarLayout.LayoutParams) toolbar.getLayoutParams();
-        AppBarLayout.LayoutParams findOnPageLayoutParams = (AppBarLayout.LayoutParams) findOnPageLinearLayout.getLayoutParams();
-        AppBarLayout.LayoutParams tabsLayoutParams = (AppBarLayout.LayoutParams) tabsLinearLayout.getLayoutParams();
-
-        // Add the scrolling behavior to the layout parameters.
-        if (scrollAppBar) {
-            // Enable scrolling of the app bar.
-            swipeRefreshLayoutParams.setBehavior(new AppBarLayout.ScrollingViewBehavior());
-            toolbarLayoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP);
-            findOnPageLayoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP);
-            tabsLayoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP);
-        } else {
-            // Disable scrolling of the app bar.
-            swipeRefreshLayoutParams.setBehavior(null);
-            toolbarLayoutParams.setScrollFlags(0);
-            findOnPageLayoutParams.setScrollFlags(0);
-            tabsLayoutParams.setScrollFlags(0);
-
-            // Expand the app bar if it is currently collapsed.
-            appBarLayout.setExpanded(true);
-        }
-
-        // Apply the modified layout parameters.
-        swipeRefreshLayout.setLayoutParams(swipeRefreshLayoutParams);
-        toolbar.setLayoutParams(toolbarLayoutParams);
-        findOnPageLinearLayout.setLayoutParams(findOnPageLayoutParams);
-        tabsLinearLayout.setLayoutParams(tabsLayoutParams);
-
-        // Set the app bar scrolling for each WebView.
-        for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
-            // Get the WebView tab fragment.
-            WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
-
-            // Get the fragment view.
-            View fragmentView = webViewTabFragment.getView();
-
-            // Only modify the WebViews if they exist.
-            if (fragmentView != null) {
-                // Get the nested scroll WebView from the tab fragment.
-                NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
-
-                // Set the app bar scrolling.
-                nestedScrollWebView.setNestedScrollingEnabled(scrollAppBar);
-            }
-        }
-
-        // Update the full screen browsing mode settings.
-        if (fullScreenBrowsingModeEnabled && inFullScreenBrowsingMode) {  // Privacy Browser is currently in full screen browsing mode.
-            // Update the visibility of the app bar, which might have changed in the settings.
-            if (hideAppBar) {
-                // Hide the tab linear layout.
-                tabsLinearLayout.setVisibility(View.GONE);
-
-                // Hide the action bar.
-                actionBar.hide();
-            } else {
-                // Show the tab linear layout.
-                tabsLinearLayout.setVisibility(View.VISIBLE);
-
-                // Show the action bar.
-                actionBar.show();
-            }
-
-            // Hide the banner ad in the free flavor.
-            if (BuildConfig.FLAVOR.contentEquals("free")) {
-                AdHelper.hideAd(findViewById(R.id.adview));
-            }
-
-            /* Hide the system bars.
-             * SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen.
-             * SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN makes the root frame layout fill the area that is normally reserved for the status bar.
-             * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen.
-             * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically re-hides them after they are shown.
-             */
-            rootFrameLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
-                    View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
-        } else {  // Privacy Browser is not in full screen browsing mode.
-            // Reset the full screen tracker, which could be true if Privacy Browser was in full screen mode before entering settings and full screen browsing was disabled.
-            inFullScreenBrowsingMode = false;
-
-            // Show the tab linear layout.
-            tabsLinearLayout.setVisibility(View.VISIBLE);
-
-            // Show the action bar.
-            actionBar.show();
-
-            // Show the banner ad in the free flavor.
-            if (BuildConfig.FLAVOR.contentEquals("free")) {
-                // Initialize the ads.  If this isn't the first run, `loadAd()` will be automatically called instead.
-                AdHelper.initializeAds(findViewById(R.id.adview), getApplicationContext(), getSupportFragmentManager(), getString(R.string.google_app_id), getString(R.string.ad_unit_id));
-            }
-
-            // Remove the `SYSTEM_UI` flags from the root frame layout.
-            rootFrameLayout.setSystemUiVisibility(0);
-        }
-    }
-
-    @Override
-    public void navigateHistory(String url, int steps) {
-        // Apply the domain settings.
-        applyDomainSettings(currentWebView, url, false, false, false);
-
-        // Load the history entry.
-        currentWebView.goBackOrForward(steps);
-    }
-
-    @Override
-    public void pinnedErrorGoBack() {
-        // Get the current web back forward list.
-        WebBackForwardList webBackForwardList = currentWebView.copyBackForwardList();
-
-        // Get the previous entry URL.
-        String previousUrl = webBackForwardList.getItemAtIndex(webBackForwardList.getCurrentIndex() - 1).getUrl();
-
-        // Apply the domain settings.
-        applyDomainSettings(currentWebView, previousUrl, false, false, false);
-
-        // Go back.
-        currentWebView.goBack();
-    }
-
-    // `reloadWebsite` is used if returning from the Domains activity.  Otherwise JavaScript might not function correctly if it is newly enabled.
-    @SuppressLint("SetJavaScriptEnabled")
-    private void applyDomainSettings(NestedScrollWebView nestedScrollWebView, String url, boolean resetTab, boolean reloadWebsite, boolean loadUrl) {
-        // Store the current URL.
-        nestedScrollWebView.setCurrentUrl(url);
-
-        // Parse the URL into a URI.
-        Uri uri = Uri.parse(url);
-
-        // Extract the domain from `uri`.
-        String newHostName = uri.getHost();
-
-        // Strings don't like to be null.
-        if (newHostName == null) {
-            newHostName = "";
-        }
-
-        // Apply the domain settings if a new domain is being loaded or if the new domain is blank.  This allows the user to set temporary settings for JavaScript, cookies, DOM storage, etc.
-        if (!nestedScrollWebView.getCurrentDomainName().equals(newHostName) || newHostName.equals("")) {
-            // Set the new host name as the current domain name.
-            nestedScrollWebView.setCurrentDomainName(newHostName);
-
-            // Reset the ignoring of pinned domain information.
-            nestedScrollWebView.setIgnorePinnedDomainInformation(false);
-
-            // Clear any pinned SSL certificate or IP addresses.
-            nestedScrollWebView.clearPinnedSslCertificate();
-            nestedScrollWebView.clearPinnedIpAddresses();
-
-            // Reset the favorite icon if specified.
-            if (resetTab) {
-                // Initialize the favorite icon.
-                nestedScrollWebView.initializeFavoriteIcon();
-
-                // Get the current page position.
-                int currentPagePosition = webViewPagerAdapter.getPositionForId(nestedScrollWebView.getWebViewFragmentId());
-
-                // Get the corresponding tab.
-                TabLayout.Tab tab = tabLayout.getTabAt(currentPagePosition);
-
-                // Update the tab if it isn't null, which sometimes happens when restarting from the background.
-                if (tab != null) {
-                    // Get the tab custom view.
-                    View tabCustomView = tab.getCustomView();
-
-                    // Remove the warning below that the tab custom view might be null.
-                    assert tabCustomView != null;
-
-                    // Get the tab views.
-                    ImageView tabFavoriteIconImageView = tabCustomView.findViewById(R.id.favorite_icon_imageview);
-                    TextView tabTitleTextView = tabCustomView.findViewById(R.id.title_textview);
-
-                    // Set the default favorite icon as the favorite icon for this tab.
-                    tabFavoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(nestedScrollWebView.getFavoriteOrDefaultIcon(), 64, 64, true));
-
-                    // Set the loading title text.
-                    tabTitleTextView.setText(R.string.loading);
-                }
-            }
-
-            // Initialize the database handler.  The `0` specifies the database version, but that is ignored and set instead using a constant in `DomainsDatabaseHelper`.
-            DomainsDatabaseHelper domainsDatabaseHelper = new DomainsDatabaseHelper(this, null, null, 0);
-
-            // Get a full cursor from `domainsDatabaseHelper`.
-            Cursor domainNameCursor = domainsDatabaseHelper.getDomainNameCursorOrderedByDomain();
-
-            // Initialize `domainSettingsSet`.
-            Set<String> domainSettingsSet = new HashSet<>();
-
-            // Get the domain name column index.
-            int domainNameColumnIndex = domainNameCursor.getColumnIndex(DomainsDatabaseHelper.DOMAIN_NAME);
-
-            // Populate `domainSettingsSet`.
-            for (int i = 0; i < domainNameCursor.getCount(); i++) {
-                // Move `domainsCursor` to the current row.
-                domainNameCursor.moveToPosition(i);
-
-                // Store the domain name in `domainSettingsSet`.
-                domainSettingsSet.add(domainNameCursor.getString(domainNameColumnIndex));
-            }
-
-            // Close `domainNameCursor.
-            domainNameCursor.close();
-
-            // Initialize the domain name in database variable.
-            String domainNameInDatabase = null;
-
-            // Check the hostname against the domain settings set.
-            if (domainSettingsSet.contains(newHostName)) {  // The hostname is contained in the domain settings set.
-                // Record the domain name in the database.
-                domainNameInDatabase = newHostName;
-
-                // Set the domain settings applied tracker to true.
-                nestedScrollWebView.setDomainSettingsApplied(true);
-            } else {  // The hostname is not contained in the domain settings set.
-                // Set the domain settings applied tracker to false.
-                nestedScrollWebView.setDomainSettingsApplied(false);
-            }
-
-            // Check all the subdomains of the host name against wildcard domains in the domain cursor.
-            while (!nestedScrollWebView.getDomainSettingsApplied() && newHostName.contains(".")) {  // Stop checking if domain settings are already applied or there are no more `.` in the host name.
-                if (domainSettingsSet.contains("*." + newHostName)) {  // Check the host name prepended by `*.`.
-                    // Set the domain settings applied tracker to true.
-                    nestedScrollWebView.setDomainSettingsApplied(true);
-
-                    // Store the applied domain names as it appears in the database.
-                    domainNameInDatabase = "*." + newHostName;
-                }
-
-                // Strip out the lowest subdomain of of the host name.
-                newHostName = newHostName.substring(newHostName.indexOf(".") + 1);
-            }
-
-
-            // Get a handle for the shared preferences.
-            SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
-
-            // Store the general preference information.
-            String defaultFontSizeString = sharedPreferences.getString("font_size", getString(R.string.font_size_default_value));
-            String defaultUserAgentName = sharedPreferences.getString("user_agent", getString(R.string.user_agent_default_value));
-            boolean defaultSwipeToRefresh = sharedPreferences.getBoolean("swipe_to_refresh", true);
-            String webViewTheme = sharedPreferences.getString("webview_theme", getString(R.string.webview_theme_default_value));
-            boolean wideViewport = sharedPreferences.getBoolean("wide_viewport", true);
-            boolean displayWebpageImages = sharedPreferences.getBoolean("display_webpage_images", true);
-
-            // Get the WebView theme entry values string array.
-            String[] webViewThemeEntryValuesStringArray = getResources().getStringArray(R.array.webview_theme_entry_values);
-
-            // Get a handle for the cookie manager.
-            CookieManager cookieManager = CookieManager.getInstance();
-
-            // Get handles for the views.
-            RelativeLayout urlRelativeLayout = findViewById(R.id.url_relativelayout);
-            SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
-
-            // Initialize the user agent array adapter and string array.
-            ArrayAdapter<CharSequence> userAgentNamesArray = ArrayAdapter.createFromResource(this, R.array.user_agent_names, R.layout.spinner_item);
-            String[] userAgentDataArray = getResources().getStringArray(R.array.user_agent_data);
-
-            if (nestedScrollWebView.getDomainSettingsApplied()) {  // The url has custom domain settings.
-                // Get a cursor for the current host and move it to the first position.
-                Cursor currentDomainSettingsCursor = domainsDatabaseHelper.getCursorForDomainName(domainNameInDatabase);
-                currentDomainSettingsCursor.moveToFirst();
-
-                // Get the settings from the cursor.
-                nestedScrollWebView.setDomainSettingsDatabaseId(currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper._ID)));
-                nestedScrollWebView.getSettings().setJavaScriptEnabled(currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_JAVASCRIPT)) == 1);
-                nestedScrollWebView.setAcceptFirstPartyCookies(currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FIRST_PARTY_COOKIES)) == 1);
-                boolean domainThirdPartyCookiesEnabled = (currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_THIRD_PARTY_COOKIES)) == 1);
-                nestedScrollWebView.getSettings().setDomStorageEnabled(currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_DOM_STORAGE)) == 1);
-                // Form data can be removed once the minimum API >= 26.
-                boolean saveFormData = (currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FORM_DATA)) == 1);
-                nestedScrollWebView.enableBlocklist(NestedScrollWebView.EASYLIST,
-                        currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_EASYLIST)) == 1);
-                nestedScrollWebView.enableBlocklist(NestedScrollWebView.EASYPRIVACY,
-                        currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_EASYPRIVACY)) == 1);
-                nestedScrollWebView.enableBlocklist(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST,
-                        currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FANBOYS_ANNOYANCE_LIST)) == 1);
-                nestedScrollWebView.enableBlocklist(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST,
-                        currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST)) == 1);
-                nestedScrollWebView.enableBlocklist(NestedScrollWebView.ULTRALIST, currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ULTRALIST)) == 1);
-                nestedScrollWebView.enableBlocklist(NestedScrollWebView.ULTRAPRIVACY,
-                        currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_ULTRAPRIVACY)) == 1);
-                nestedScrollWebView.enableBlocklist(NestedScrollWebView.THIRD_PARTY_REQUESTS,
-                        currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.BLOCK_ALL_THIRD_PARTY_REQUESTS)) == 1);
-                String userAgentName = currentDomainSettingsCursor.getString(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.USER_AGENT));
-                int fontSize = currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.FONT_SIZE));
-                int swipeToRefreshInt = currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SWIPE_TO_REFRESH));
-                int webViewThemeInt = currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.WEBVIEW_THEME));
-                int wideViewportInt = currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.WIDE_VIEWPORT));
-                int displayWebpageImagesInt = currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.DISPLAY_IMAGES));
-                boolean pinnedSslCertificate = (currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.PINNED_SSL_CERTIFICATE)) == 1);
-                String pinnedSslIssuedToCName = currentDomainSettingsCursor.getString(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_TO_COMMON_NAME));
-                String pinnedSslIssuedToOName = currentDomainSettingsCursor.getString(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_TO_ORGANIZATION));
-                String pinnedSslIssuedToUName = currentDomainSettingsCursor.getString(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_TO_ORGANIZATIONAL_UNIT));
-                String pinnedSslIssuedByCName = currentDomainSettingsCursor.getString(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_BY_COMMON_NAME));
-                String pinnedSslIssuedByOName = currentDomainSettingsCursor.getString(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_BY_ORGANIZATION));
-                String pinnedSslIssuedByUName = currentDomainSettingsCursor.getString(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_BY_ORGANIZATIONAL_UNIT));
-                boolean pinnedIpAddresses = (currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.PINNED_IP_ADDRESSES)) == 1);
-                String pinnedHostIpAddresses = currentDomainSettingsCursor.getString(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.IP_ADDRESSES));
-
-                // Get the pinned SSL date longs.
-                long pinnedSslStartDateLong = currentDomainSettingsCursor.getLong(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_START_DATE));
-                long pinnedSslEndDateLong = currentDomainSettingsCursor.getLong(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_END_DATE));
-
-                // Define the pinned SSL date variables.
-                Date pinnedSslStartDate;
-                Date pinnedSslEndDate;
-
-                // Set the pinned SSL certificate start date to `null` if the saved date long is 0 because creating a new date results in an error if the input is 0.
-                if (pinnedSslStartDateLong == 0) {
-                    pinnedSslStartDate = null;
-                } else {
-                    pinnedSslStartDate = new Date(pinnedSslStartDateLong);
-                }
-
-                // Set the pinned SSL certificate end date to `null` if the saved date long is 0 because creating a new date results in an error if the input is 0.
-                if (pinnedSslEndDateLong == 0) {
-                    pinnedSslEndDate = null;
-                } else {
-                    pinnedSslEndDate = new Date(pinnedSslEndDateLong);
-                }
-
-                // Close the current host domain settings cursor.
-                currentDomainSettingsCursor.close();
-
-                // If there is a pinned SSL certificate, store it in the WebView.
-                if (pinnedSslCertificate) {
-                    nestedScrollWebView.setPinnedSslCertificate(pinnedSslIssuedToCName, pinnedSslIssuedToOName, pinnedSslIssuedToUName, pinnedSslIssuedByCName, pinnedSslIssuedByOName, pinnedSslIssuedByUName,
-                            pinnedSslStartDate, pinnedSslEndDate);
-                }
-
-                // If there is a pinned IP address, store it in the WebView.
-                if (pinnedIpAddresses) {
-                    nestedScrollWebView.setPinnedIpAddresses(pinnedHostIpAddresses);
-                }
-
-                // Apply the cookie domain settings.
-                cookieManager.setAcceptCookie(nestedScrollWebView.getAcceptFirstPartyCookies());
-
-                // Set third-party cookies status if API >= 21.
-                if (Build.VERSION.SDK_INT >= 21) {
-                    cookieManager.setAcceptThirdPartyCookies(nestedScrollWebView, domainThirdPartyCookiesEnabled);
-                }
-
-                // Apply the form data setting if the API < 26.
-                if (Build.VERSION.SDK_INT < 26) {
-                    nestedScrollWebView.getSettings().setSaveFormData(saveFormData);
-                }
-
-                // Apply the font size.
-                try {  // Try the specified font size to see if it is valid.
-                    if (fontSize == 0) {  // Apply the default font size.
-                            // Try to set the font size from the value in the app settings.
-                            nestedScrollWebView.getSettings().setTextZoom(Integer.parseInt(defaultFontSizeString));
-                    } else {  // Apply the font size from domain settings.
-                        nestedScrollWebView.getSettings().setTextZoom(fontSize);
-                    }
-                } catch (Exception exception) {  // The specified font size is invalid
-                    // Set the font size to be 100%
-                    nestedScrollWebView.getSettings().setTextZoom(100);
-                }
-
-                // Set the user agent.
-                if (userAgentName.equals(getString(R.string.system_default_user_agent))) {  // Use the system default user agent.
-                    // Get the array position of the default user agent name.
-                    int defaultUserAgentArrayPosition = userAgentNamesArray.getPosition(defaultUserAgentName);
-
-                    // Set the user agent according to the system default.
-                    switch (defaultUserAgentArrayPosition) {
-                        case UNRECOGNIZED_USER_AGENT:  // The default user agent name is not on the canonical list.
-                            // This is probably because it was set in an older version of Privacy Browser before the switch to persistent user agent names.
-                            nestedScrollWebView.getSettings().setUserAgentString(defaultUserAgentName);
-                            break;
-
-                        case SETTINGS_WEBVIEW_DEFAULT_USER_AGENT:
-                            // Set the user agent to `""`, which uses the default value.
-                            nestedScrollWebView.getSettings().setUserAgentString("");
-                            break;
-
-                        case SETTINGS_CUSTOM_USER_AGENT:
-                            // Set the default custom user agent.
-                            nestedScrollWebView.getSettings().setUserAgentString(sharedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
-                            break;
-
-                        default:
-                            // Get the user agent string from the user agent data array
-                            nestedScrollWebView.getSettings().setUserAgentString(userAgentDataArray[defaultUserAgentArrayPosition]);
-                    }
-                } else {  // Set the user agent according to the stored name.
-                    // Get the array position of the user agent name.
-                    int userAgentArrayPosition = userAgentNamesArray.getPosition(userAgentName);
-
-                    switch (userAgentArrayPosition) {
-                        case UNRECOGNIZED_USER_AGENT:  // The user agent name contains a custom user agent.
-                            nestedScrollWebView.getSettings().setUserAgentString(userAgentName);
-                            break;
-
-                        case SETTINGS_WEBVIEW_DEFAULT_USER_AGENT:
-                            // Set the user agent to `""`, which uses the default value.
-                            nestedScrollWebView.getSettings().setUserAgentString("");
-                            break;
-
-                        default:
-                            // Get the user agent string from the user agent data array.
-                            nestedScrollWebView.getSettings().setUserAgentString(userAgentDataArray[userAgentArrayPosition]);
-                    }
-                }
-
-                // Set swipe to refresh.
-                switch (swipeToRefreshInt) {
-                    case DomainsDatabaseHelper.SYSTEM_DEFAULT:
-                        // Store the swipe to refresh status in the nested scroll WebView.
-                        nestedScrollWebView.setSwipeToRefresh(defaultSwipeToRefresh);
-
-                        // Update the swipe refresh layout.
-                        if (defaultSwipeToRefresh) {  // Swipe to refresh is enabled.
-                            // Only enable the swipe refresh layout if the WebView is scrolled to the top.  It is updated every time the scroll changes.
-                            swipeRefreshLayout.setEnabled(currentWebView.getY() == 0);
-                        } else {  // Swipe to refresh is disabled.
-                            // Disable the swipe refresh layout.
-                            swipeRefreshLayout.setEnabled(false);
-                        }
-                        break;
-
-                    case DomainsDatabaseHelper.ENABLED:
-                        // Store the swipe to refresh status in the nested scroll WebView.
-                        nestedScrollWebView.setSwipeToRefresh(true);
-
-                        // Only enable the swipe refresh layout if the WebView is scrolled to the top.  It is updated every time the scroll changes.
-                        swipeRefreshLayout.setEnabled(currentWebView.getY() == 0);
-                        break;
-
-                    case DomainsDatabaseHelper.DISABLED:
-                        // Store the swipe to refresh status in the nested scroll WebView.
-                        nestedScrollWebView.setSwipeToRefresh(false);
-
-                        // Disable swipe to refresh.
-                        swipeRefreshLayout.setEnabled(false);
-                }
-
-                // Check to see if WebView themes are supported.
-                if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
-                    // Set the WebView theme.
-                    switch (webViewThemeInt) {
-                        case DomainsDatabaseHelper.SYSTEM_DEFAULT:
-                            // Set the WebView theme.  A switch statement cannot be used because the WebView theme entry values string array is not a compile time constant.
-                            if (webViewTheme.equals(webViewThemeEntryValuesStringArray[1])) {  // The light theme is selected.
-                                // Turn off the WebView dark mode.
-                                WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_OFF);
-                            } else if (webViewTheme.equals(webViewThemeEntryValuesStringArray[2])) {  // The dark theme is selected.
-                                // Turn on the WebView dark mode.
-                                WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_ON);
-                            } else {  // The system default theme is selected.
-                                // Get the current system theme status.
-                                int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
-                                // Set the WebView theme according to the current system theme status.
-                                if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {  // The system is in day mode.
-                                    // Turn off the WebView dark mode.
-                                    WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_OFF);
-                                } else {  // The system is in night mode.
-                                    // Turn on the WebView dark mode.
-                                    WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_ON);
-                                }
-                            }
-                            break;
-
-                        case DomainsDatabaseHelper.LIGHT_THEME:
-                            // Turn off the WebView dark mode.
-                            WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_OFF);
-                            break;
-
-                        case DomainsDatabaseHelper.DARK_THEME:
-                            // Turn on the WebView dark mode.
-                            WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_ON);
-                            break;
-                    }
-                }
-
-                // Set the viewport.
-                switch (wideViewportInt) {
-                    case DomainsDatabaseHelper.SYSTEM_DEFAULT:
-                        nestedScrollWebView.getSettings().setUseWideViewPort(wideViewport);
-                        break;
-
-                    case DomainsDatabaseHelper.ENABLED:
-                        nestedScrollWebView.getSettings().setUseWideViewPort(true);
-                        break;
-
-                    case DomainsDatabaseHelper.DISABLED:
-                        nestedScrollWebView.getSettings().setUseWideViewPort(false);
-                        break;
-                }
-
-                // Set the loading of webpage images.
-                switch (displayWebpageImagesInt) {
-                    case DomainsDatabaseHelper.SYSTEM_DEFAULT:
-                        nestedScrollWebView.getSettings().setLoadsImagesAutomatically(displayWebpageImages);
-                        break;
-
-                    case DomainsDatabaseHelper.ENABLED:
-                        nestedScrollWebView.getSettings().setLoadsImagesAutomatically(true);
-                        break;
-
-                    case DomainsDatabaseHelper.DISABLED:
-                        nestedScrollWebView.getSettings().setLoadsImagesAutomatically(false);
-                        break;
-                }
-
-                // Get the current theme status.
-                int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
-                // Set a background on the URL relative layout to indicate that custom domain settings are being used.
-                if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
-                    urlRelativeLayout.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.url_bar_background_light_green, null));
-                } else {
-                    urlRelativeLayout.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.url_bar_background_dark_blue, null));
-                }
-            } else {  // The new URL does not have custom domain settings.  Load the defaults.
-                // Store the values from the shared preferences.
-                nestedScrollWebView.getSettings().setJavaScriptEnabled(sharedPreferences.getBoolean("javascript", false));
-                nestedScrollWebView.setAcceptFirstPartyCookies(sharedPreferences.getBoolean("first_party_cookies", false));
-                boolean defaultThirdPartyCookiesEnabled = sharedPreferences.getBoolean("third_party_cookies", false);
-                nestedScrollWebView.getSettings().setDomStorageEnabled(sharedPreferences.getBoolean("dom_storage", false));
-                boolean saveFormData = sharedPreferences.getBoolean("save_form_data", false);  // Form data can be removed once the minimum API >= 26.
-                nestedScrollWebView.enableBlocklist(NestedScrollWebView.EASYLIST, sharedPreferences.getBoolean("easylist", true));
-                nestedScrollWebView.enableBlocklist(NestedScrollWebView.EASYPRIVACY, sharedPreferences.getBoolean("easyprivacy", true));
-                nestedScrollWebView.enableBlocklist(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST, sharedPreferences.getBoolean("fanboys_annoyance_list", true));
-                nestedScrollWebView.enableBlocklist(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST, sharedPreferences.getBoolean("fanboys_social_blocking_list", true));
-                nestedScrollWebView.enableBlocklist(NestedScrollWebView.ULTRALIST, sharedPreferences.getBoolean("ultralist", true));
-                nestedScrollWebView.enableBlocklist(NestedScrollWebView.ULTRAPRIVACY, sharedPreferences.getBoolean("ultraprivacy", true));
-                nestedScrollWebView.enableBlocklist(NestedScrollWebView.THIRD_PARTY_REQUESTS, sharedPreferences.getBoolean("block_all_third_party_requests", false));
-
-                // Apply the default first-party cookie setting.
-                cookieManager.setAcceptCookie(nestedScrollWebView.getAcceptFirstPartyCookies());
-
-                // Apply the default font size setting.
-                try {
-                    // Try to set the font size from the value in the app settings.
-                    nestedScrollWebView.getSettings().setTextZoom(Integer.parseInt(defaultFontSizeString));
-                } catch (Exception exception) {
-                    // If the app settings value is invalid, set the font size to 100%.
-                    nestedScrollWebView.getSettings().setTextZoom(100);
-                }
-
-                // Apply the form data setting if the API < 26.
-                if (Build.VERSION.SDK_INT < 26) {
-                    nestedScrollWebView.getSettings().setSaveFormData(saveFormData);
-                }
-
-                // Store the swipe to refresh status in the nested scroll WebView.
-                nestedScrollWebView.setSwipeToRefresh(defaultSwipeToRefresh);
-
-                // Update the swipe refresh layout.
-                if (defaultSwipeToRefresh) {  // Swipe to refresh is enabled.
-                    // Only enable the swipe refresh layout if the WebView is scrolled to the top.  It is updated every time the scroll changes.
-                    swipeRefreshLayout.setEnabled(currentWebView.getY() == 0);
-                } else {  // Swipe to refresh is disabled.
-                    // Disable the swipe refresh layout.
-                    swipeRefreshLayout.setEnabled(false);
-                }
-
-                // Reset the pinned variables.
-                nestedScrollWebView.setDomainSettingsDatabaseId(-1);
-
-                // Set third-party cookies status if API >= 21.
-                if (Build.VERSION.SDK_INT >= 21) {
-                    cookieManager.setAcceptThirdPartyCookies(nestedScrollWebView, defaultThirdPartyCookiesEnabled);
-                }
-
-                // Get the array position of the user agent name.
-                int userAgentArrayPosition = userAgentNamesArray.getPosition(defaultUserAgentName);
-
-                // Set the user agent.
-                switch (userAgentArrayPosition) {
-                    case UNRECOGNIZED_USER_AGENT:  // The default user agent name is not on the canonical list.
-                        // This is probably because it was set in an older version of Privacy Browser before the switch to persistent user agent names.
-                        nestedScrollWebView.getSettings().setUserAgentString(defaultUserAgentName);
-                        break;
-
-                    case SETTINGS_WEBVIEW_DEFAULT_USER_AGENT:
-                        // Set the user agent to `""`, which uses the default value.
-                        nestedScrollWebView.getSettings().setUserAgentString("");
-                        break;
-
-                    case SETTINGS_CUSTOM_USER_AGENT:
-                        // Set the default custom user agent.
-                        nestedScrollWebView.getSettings().setUserAgentString(sharedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
-                        break;
-
-                    default:
-                        // Get the user agent string from the user agent data array
-                        nestedScrollWebView.getSettings().setUserAgentString(userAgentDataArray[userAgentArrayPosition]);
-                }
-
-                // Apply the WebView theme if supported by the installed WebView.
-                if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
-                    // Set the WebView theme.  A switch statement cannot be used because the WebView theme entry values string array is not a compile time constant.
-                    if (webViewTheme.equals(webViewThemeEntryValuesStringArray[1])) {  // The light theme is selected.
-                        // Turn off the WebView dark mode.
-                        WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_OFF);
-                    } else if (webViewTheme.equals(webViewThemeEntryValuesStringArray[2])) {  // The dark theme is selected.
-                        // Turn on the WebView dark mode.
-                        WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_ON);
-                    } else {  // The system default theme is selected.
-                        // Get the current system theme status.
-                        int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
-                        // Set the WebView theme according to the current system theme status.
-                        if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {  // The system is in day mode.
-                            // Turn off the WebView dark mode.
-                            WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_OFF);
-                        } else {  // The system is in night mode.
-                            // Turn on the WebView dark mode.
-                            WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_ON);
-                        }
-                    }
-                }
-
-                // Set the viewport.
-                nestedScrollWebView.getSettings().setUseWideViewPort(wideViewport);
-
-                // Set the loading of webpage images.
-                nestedScrollWebView.getSettings().setLoadsImagesAutomatically(displayWebpageImages);
-
-                // Set a transparent background on URL edit text.
-                urlRelativeLayout.setBackground(ResourcesCompat.getDrawable(getResources(), R.color.transparent, null));
-            }
-
-            // Close the domains database helper.
-            domainsDatabaseHelper.close();
-
-            // Update the privacy icons.
-            updatePrivacyIcons(true);
-        }
-
-        // Reload the website if returning from the Domains activity.
-        if (reloadWebsite) {
-            nestedScrollWebView.reload();
-        }
-
-        // Load the URL if directed.  This makes sure that the domain settings are properly loaded before the URL.  By using `loadUrl()`, instead of `loadUrlFromBase()`, the Referer header will never be sent.
-        if (loadUrl) {
-            nestedScrollWebView.loadUrl(url, customHeaders);
-        }
-    }
-
-    private void applyProxy(boolean reloadWebViews) {
-        // Set the proxy according to the mode.  `this` refers to the current activity where an alert dialog might be displayed.
-        ProxyHelper.setProxy(getApplicationContext(), appBarLayout, proxyMode);
-
-        // Reset the waiting for proxy tracker.
-        waitingForProxy = false;
-
-        // Get the current theme status.
-        int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
-        // Update the user interface and reload the WebViews if requested.
-        switch (proxyMode) {
-            case ProxyHelper.NONE:
-                // Initialize a color background typed value.
-                TypedValue colorBackgroundTypedValue = new TypedValue();
-
-                // Get the color background from the theme.
-                getTheme().resolveAttribute(android.R.attr.colorBackground, colorBackgroundTypedValue, true);
-
-                // Get the color background int from the typed value.
-                int colorBackgroundInt = colorBackgroundTypedValue.data;
-
-                // Set the default app bar layout background.
-                appBarLayout.setBackgroundColor(colorBackgroundInt);
-                break;
-
-            case ProxyHelper.TOR:
-                // Set the app bar background to indicate proxying through Orbot is enabled.
-                if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
-                    appBarLayout.setBackgroundResource(R.color.blue_50);
-                } else {
-                    appBarLayout.setBackgroundResource(R.color.dark_blue_30);
-                }
-
-                // Check to see if Orbot is installed.
-                try {
-                    // Get the package manager.
-                    PackageManager packageManager = getPackageManager();
-
-                    // Check to see if Orbot is in the list.  This will throw an error and drop to the catch section if it isn't installed.
-                    packageManager.getPackageInfo("org.torproject.android", 0);
-
-                    // Check to see if the proxy is ready.
-                    if (!orbotStatus.equals("ON")) {  // Orbot is not ready.
-                        // Set the waiting for proxy status.
-                        waitingForProxy = true;
-
-                        // Show the waiting for proxy dialog if it isn't already displayed.
-                        if (getSupportFragmentManager().findFragmentByTag(getString(R.string.waiting_for_proxy_dialog)) == null) {
-                            // Get a handle for the waiting for proxy alert dialog.
-                            DialogFragment waitingForProxyDialogFragment = new WaitingForProxyDialog();
-
-                            // Display the waiting for proxy alert dialog.
-                            waitingForProxyDialogFragment.show(getSupportFragmentManager(), getString(R.string.waiting_for_proxy_dialog));
-                        }
-                    }
-                } catch (PackageManager.NameNotFoundException exception) {  // Orbot is not installed.
-                    // Show the Orbot not installed dialog if it is not already displayed.
-                    if (getSupportFragmentManager().findFragmentByTag(getString(R.string.proxy_not_installed_dialog)) == null) {
-                        // Get a handle for the Orbot not installed alert dialog.
-                        DialogFragment orbotNotInstalledDialogFragment = ProxyNotInstalledDialog.displayDialog(proxyMode);
-
-                        // Display the Orbot not installed alert dialog.
-                        orbotNotInstalledDialogFragment.show(getSupportFragmentManager(), getString(R.string.proxy_not_installed_dialog));
-                    }
-                }
-                break;
-
-            case ProxyHelper.I2P:
-                // Set the app bar background to indicate proxying through Orbot is enabled.
-                if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
-                    appBarLayout.setBackgroundResource(R.color.blue_50);
-                } else {
-                    appBarLayout.setBackgroundResource(R.color.dark_blue_30);
-                }
-
-                // Check to see if I2P is installed.
-                try {
-                    // Get the package manager.
-                    PackageManager packageManager = getPackageManager();
-
-                    // Check to see if I2P is in the list.  This will throw an error and drop to the catch section if it isn't installed.
-                    packageManager.getPackageInfo("org.torproject.android", 0);
-                } catch (PackageManager.NameNotFoundException exception) {  // I2P is not installed.
-                    // Sow the I2P not installed dialog if it is not already displayed.
-                    if (getSupportFragmentManager().findFragmentByTag(getString(R.string.proxy_not_installed_dialog)) == null) {
-                        // Get a handle for the waiting for proxy alert dialog.
-                        DialogFragment i2pNotInstalledDialogFragment = ProxyNotInstalledDialog.displayDialog(proxyMode);
-
-                        // Display the I2P not installed alert dialog.
-                        i2pNotInstalledDialogFragment.show(getSupportFragmentManager(), getString(R.string.proxy_not_installed_dialog));
-                    }
-                }
-                break;
-
-            case ProxyHelper.CUSTOM:
-                // Set the app bar background to indicate proxying through Orbot is enabled.
-                if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
-                    appBarLayout.setBackgroundResource(R.color.blue_50);
-                } else {
-                    appBarLayout.setBackgroundResource(R.color.dark_blue_30);
-                }
-                break;
-        }
-
-        // Reload the WebViews if requested and not waiting for the proxy.
-        if (reloadWebViews && !waitingForProxy) {
-            // Reload the WebViews.
-            for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
-                // Get the WebView tab fragment.
-                WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
-
-                // Get the fragment view.
-                View fragmentView = webViewTabFragment.getView();
-
-                // Only reload the WebViews if they exist.
-                if (fragmentView != null) {
-                    // Get the nested scroll WebView from the tab fragment.
-                    NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
-
-                    // Reload the WebView.
-                    nestedScrollWebView.reload();
-                }
-            }
-        }
-    }
-
-    private void updatePrivacyIcons(boolean runInvalidateOptionsMenu) {
-        // Only update the privacy icons if the options menu and the current WebView have already been populated.
-        if ((optionsMenu != null) && (currentWebView != null)) {
-            // Get handles for the menu items.
-            MenuItem privacyMenuItem = optionsMenu.findItem(R.id.toggle_javascript);
-            MenuItem firstPartyCookiesMenuItem = optionsMenu.findItem(R.id.toggle_first_party_cookies);
-            MenuItem refreshMenuItem = optionsMenu.findItem(R.id.refresh);
-
-            // Update the privacy icon.
-            if (currentWebView.getSettings().getJavaScriptEnabled()) {  // JavaScript is enabled.
-                privacyMenuItem.setIcon(R.drawable.javascript_enabled);
-            } else if (currentWebView.getAcceptFirstPartyCookies()) {  // JavaScript is disabled but cookies are enabled.
-                privacyMenuItem.setIcon(R.drawable.warning);
-            } else {  // All the dangerous features are disabled.
-                privacyMenuItem.setIcon(R.drawable.privacy_mode);
-            }
-
-            // Get the current theme status.
-            int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
-            // Update the first-party cookies icon.
-            if (currentWebView.getAcceptFirstPartyCookies()) {  // First-party cookies are enabled.
-                firstPartyCookiesMenuItem.setIcon(R.drawable.cookies_enabled);
-            } else {  // First-party cookies are disabled.
-                if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
-                    firstPartyCookiesMenuItem.setIcon(R.drawable.cookies_disabled_day);
-                } else {
-                    firstPartyCookiesMenuItem.setIcon(R.drawable.cookies_disabled_night);
-                }
-            }
-
-            // Update the refresh icon.
-            if (refreshMenuItem.getTitle() == getString(R.string.refresh)) {  // The refresh icon is displayed.
-                // Set the icon according to the theme.
-                if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
-                    refreshMenuItem.setIcon(R.drawable.refresh_enabled_day);
-                } else {
-                    refreshMenuItem.setIcon(R.drawable.refresh_enabled_night);
-                }
-            } else {  // The stop icon is displayed.
-                // Set the icon according to the theme.
-                if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
-                    refreshMenuItem.setIcon(R.drawable.close_blue_day);
-                } else {
-                    refreshMenuItem.setIcon(R.drawable.close_blue_night);
-                }
-            }
-
-            // `invalidateOptionsMenu()` calls `onPrepareOptionsMenu()` and redraws the icons in the app bar.
-            if (runInvalidateOptionsMenu) {
-                invalidateOptionsMenu();
-            }
-        }
-    }
-
-    private void highlightUrlText() {
-        // Get a handle for the URL edit text.
-        EditText urlEditText = findViewById(R.id.url_edittext);
-
-        // Only highlight the URL text if the box is not currently selected.
-        if (!urlEditText.hasFocus()) {
-            // Get the URL string.
-            String urlString = urlEditText.getText().toString();
-
-            // Highlight the URL according to the protocol.
-            if (urlString.startsWith("file://") || urlString.startsWith("content://")) {  // This is a file or content URL.
-                // De-emphasize everything before the file name.
-                urlEditText.getText().setSpan(initialGrayColorSpan, 0, urlString.lastIndexOf("/") + 1,Spanned.SPAN_INCLUSIVE_INCLUSIVE);
-            } else {  // This is a web URL.
-                // Get the index of the `/` immediately after the domain name.
-                int endOfDomainName = urlString.indexOf("/", (urlString.indexOf("//") + 2));
-
-                // Create a base URL string.
-                String baseUrl;
-
-                // Get the base URL.
-                if (endOfDomainName > 0) {  // There is at least one character after the base URL.
-                    // Get the base URL.
-                    baseUrl = urlString.substring(0, endOfDomainName);
-                } else {  // There are no characters after the base URL.
-                    // Set the base URL to be the entire URL string.
-                    baseUrl = urlString;
-                }
-
-                // Get the index of the last `.` in the domain.
-                int lastDotIndex = baseUrl.lastIndexOf(".");
-
-                // Get the index of the penultimate `.` in the domain.
-                int penultimateDotIndex = baseUrl.lastIndexOf(".", lastDotIndex - 1);
-
-                // Markup the beginning of the URL.
-                if (urlString.startsWith("http://")) {  // Highlight the protocol of connections that are not encrypted.
-                    urlEditText.getText().setSpan(redColorSpan, 0, 7, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
-
-                    // De-emphasize subdomains.
-                    if (penultimateDotIndex > 0) {  // There is more than one subdomain in the domain name.
-                        urlEditText.getText().setSpan(initialGrayColorSpan, 7, penultimateDotIndex + 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
-                    }
-                } else if (urlString.startsWith("https://")) {  // De-emphasize the protocol of connections that are encrypted.
-                    if (penultimateDotIndex > 0) {  // There is more than one subdomain in the domain name.
-                        // De-emphasize the protocol and the additional subdomains.
-                        urlEditText.getText().setSpan(initialGrayColorSpan, 0, penultimateDotIndex + 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
-                    } else {  // There is only one subdomain in the domain name.
-                        // De-emphasize only the protocol.
-                        urlEditText.getText().setSpan(initialGrayColorSpan, 0, 8, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
-                    }
-                }
-
-                // De-emphasize the text after the domain name.
-                if (endOfDomainName > 0) {
-                    urlEditText.getText().setSpan(finalGrayColorSpan, endOfDomainName, urlString.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
-                }
-            }
-        }
-    }
-
-    private void loadBookmarksFolder() {
-        // Update the bookmarks cursor with the contents of the bookmarks database for the current folder.
-        bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentBookmarksFolder);
-
-        // Populate the bookmarks cursor adapter.  `this` specifies the `Context`.  `false` disables `autoRequery`.
-        bookmarksCursorAdapter = new CursorAdapter(this, bookmarksCursor, false) {
-            @Override
-            public View newView(Context context, Cursor cursor, ViewGroup parent) {
-                // Inflate the individual item layout.  `false` does not attach it to the root.
-                return getLayoutInflater().inflate(R.layout.bookmarks_drawer_item_linearlayout, parent, false);
-            }
-
-            @Override
-            public void bindView(View view, Context context, Cursor cursor) {
-                // Get handles for the views.
-                ImageView bookmarkFavoriteIcon = view.findViewById(R.id.bookmark_favorite_icon);
-                TextView bookmarkNameTextView = view.findViewById(R.id.bookmark_name);
-
-                // Get the favorite icon byte array from the cursor.
-                byte[] favoriteIconByteArray = cursor.getBlob(cursor.getColumnIndex(BookmarksDatabaseHelper.FAVORITE_ICON));
-
-                // Convert the byte array to a `Bitmap` beginning at the first byte and ending at the last.
-                Bitmap favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length);
-
-                // Display the bitmap in `bookmarkFavoriteIcon`.
-                bookmarkFavoriteIcon.setImageBitmap(favoriteIconBitmap);
-
-                // Get the bookmark name from the cursor and display it in `bookmarkNameTextView`.
-                String bookmarkNameString = cursor.getString(cursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
-                bookmarkNameTextView.setText(bookmarkNameString);
-
-                // Make the font bold for folders.
-                if (cursor.getInt(cursor.getColumnIndex(BookmarksDatabaseHelper.IS_FOLDER)) == 1) {
-                    bookmarkNameTextView.setTypeface(Typeface.DEFAULT_BOLD);
-                } else {  // Reset the font to default for normal bookmarks.
-                    bookmarkNameTextView.setTypeface(Typeface.DEFAULT);
-                }
-            }
-        };
-
-        // Get a handle for the bookmarks list view.
-        ListView bookmarksListView = findViewById(R.id.bookmarks_drawer_listview);
-
-        // Populate the list view with the adapter.
-        bookmarksListView.setAdapter(bookmarksCursorAdapter);
-
-        // Get a handle for the bookmarks title text view.
-        TextView bookmarksTitleTextView = findViewById(R.id.bookmarks_title_textview);
-
-        // Set the bookmarks drawer title.
-        if (currentBookmarksFolder.isEmpty()) {
-            bookmarksTitleTextView.setText(R.string.bookmarks);
-        } else {
-            bookmarksTitleTextView.setText(currentBookmarksFolder);
-        }
-    }
-
-    private void openWithApp(String url) {
-        // Create an open with app intent with `ACTION_VIEW`.
-        Intent openWithAppIntent = new Intent(Intent.ACTION_VIEW);
-
-        // Set the URI but not the MIME type.  This should open all available apps.
-        openWithAppIntent.setData(Uri.parse(url));
-
-        // Flag the intent to open in a new task.
-        openWithAppIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        // Try the intent.
-        try {
-            // Show the chooser.
-            startActivity(openWithAppIntent);
-        } catch (ActivityNotFoundException exception) {  // There are no apps available to open the URL.
-            // Show a snackbar with the error.
-            Snackbar.make(currentWebView, getString(R.string.error) + "  " + exception, Snackbar.LENGTH_INDEFINITE).show();
-        }
-    }
-
-    private void openWithBrowser(String url) {
-        // Create an open with browser intent with `ACTION_VIEW`.
-        Intent openWithBrowserIntent = new Intent(Intent.ACTION_VIEW);
-
-        // Set the URI and the MIME type.  `"text/html"` should load browser options.
-        openWithBrowserIntent.setDataAndType(Uri.parse(url), "text/html");
-
-        // Flag the intent to open in a new task.
-        openWithBrowserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        // Try the intent.
-        try {
-            // Show the chooser.
-            startActivity(openWithBrowserIntent);
-        } catch (ActivityNotFoundException exception) {  // There are no browsers available to open the URL.
-            // Show a snackbar with the error.
-            Snackbar.make(currentWebView, getString(R.string.error) + "  " + exception, Snackbar.LENGTH_INDEFINITE).show();
-        }
-    }
-
-    private String sanitizeUrl(String url) {
-        // Sanitize Google Analytics.
-        if (sanitizeGoogleAnalytics) {
-            // Remove `?utm_`.
-            if (url.contains("?utm_")) {
-                url = url.substring(0, url.indexOf("?utm_"));
-            }
-
-            // Remove `&utm_`.
-            if (url.contains("&utm_")) {
-                url = url.substring(0, url.indexOf("&utm_"));
-            }
-        }
-
-        // Sanitize Facebook Click IDs.
-        if (sanitizeFacebookClickIds) {
-            // Remove `?fbclid=`.
-            if (url.contains("?fbclid=")) {
-                url = url.substring(0, url.indexOf("?fbclid="));
-            }
-
-            // Remove `&fbclid=`.
-            if (url.contains("&fbclid=")) {
-                url = url.substring(0, url.indexOf("&fbclid="));
-            }
-
-            // Remove `?fbadid=`.
-            if (url.contains("?fbadid=")) {
-                url = url.substring(0, url.indexOf("?fbadid="));
-            }
-
-            // Remove `&fbadid=`.
-            if (url.contains("&fbadid=")) {
-                url = url.substring(0, url.indexOf("&fbadid="));
-            }
-        }
-
-        // Sanitize Twitter AMP redirects.
-        if (sanitizeTwitterAmpRedirects) {
-            // Remove `?amp=1`.
-            if (url.contains("?amp=1")) {
-                url = url.substring(0, url.indexOf("?amp=1"));
-            }
-        }
-
-        // Return the sanitized URL.
-        return url;
-    }
-
-    public void finishedPopulatingBlocklists(ArrayList<ArrayList<List<String[]>>> combinedBlocklists) {
-        // Store the blocklists.
-        easyList = combinedBlocklists.get(0);
-        easyPrivacy = combinedBlocklists.get(1);
-        fanboysAnnoyanceList = combinedBlocklists.get(2);
-        fanboysSocialList = combinedBlocklists.get(3);
-        ultraList = combinedBlocklists.get(4);
-        ultraPrivacy = combinedBlocklists.get(5);
-
-        // Check to see if the activity has been restarted with a saved state.
-        if ((savedStateArrayList == null) || (savedStateArrayList.size() == 0)) {  // The activity has not been restarted or it was restarted on start to force the night theme.
-            // Add the first tab.
-            addNewTab("", true);
-        } else {  // The activity has been restarted.
-            // Restore each tab.  Once the minimum API >= 24, a `forEach()` command can be used.
-            for (int i = 0; i < savedStateArrayList.size(); i++) {
-                // Add a new tab.
-                tabLayout.addTab(tabLayout.newTab());
-
-                // Get the new tab.
-                TabLayout.Tab newTab = tabLayout.getTabAt(i);
-
-                // Remove the lint warning below that the current tab might be null.
-                assert newTab != null;
-
-                // Set a custom view on the new tab.
-                newTab.setCustomView(R.layout.tab_custom_view);
-
-                // Add the new page.
-                webViewPagerAdapter.restorePage(savedStateArrayList.get(i), savedNestedScrollWebViewStateArrayList.get(i));
-            }
-
-            // Reset the saved state variables.
-            savedStateArrayList = null;
-            savedNestedScrollWebViewStateArrayList = null;
-
-            // Restore the selected tab position.
-            if (savedTabPosition == 0) {  // The first tab is selected.
-                // Set the first page as the current WebView.
-                setCurrentWebView(0);
-            } else {  // the first tab is not selected.
-                // Move to the selected tab.
-                webViewPager.setCurrentItem(savedTabPosition);
-            }
-
-            // Get the intent that started the app.
-            Intent intent = getIntent();
-
-            // Reset the intent.  This prevents a duplicate tab from being created on restart.
-            setIntent(new Intent());
-
-            // Get the information from the intent.
-            String intentAction = intent.getAction();
-            Uri intentUriData = intent.getData();
-            String intentStringExtra = intent.getStringExtra(Intent.EXTRA_TEXT);
-
-            // Determine if this is a web search.
-            boolean isWebSearch = ((intentAction != null) && intentAction.equals(Intent.ACTION_WEB_SEARCH));
-
-            // Only process the URI if it contains data or it is a web search.  If the user pressed the desktop icon after the app was already running the URI will be null.
-            if (intentUriData != null || intentStringExtra != null || isWebSearch) {
-                // Get the shared preferences.
-                SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
-
-                // Create a URL string.
-                String url;
-
-                // If the intent action is a web search, perform the search.
-                if (isWebSearch) {  // The intent is a web search.
-                    // Create an encoded URL string.
-                    String encodedUrlString;
-
-                    // Sanitize the search input and convert it to a search.
-                    try {
-                        encodedUrlString = URLEncoder.encode(intent.getStringExtra(SearchManager.QUERY), "UTF-8");
-                    } catch (UnsupportedEncodingException exception) {
-                        encodedUrlString = "";
-                    }
-
-                    // Add the base search URL.
-                    url = searchURL + encodedUrlString;
-                } else if (intentUriData != null) {  // The intent contains a URL formatted as a URI.
-                    // Set the intent data as the URL.
-                    url = intentUriData.toString();
-                } else {  // The intent contains a string, which might be a URL.
-                    // Set the intent string as the URL.
-                    url = intentStringExtra;
-                }
-
-                // Add a new tab if specified in the preferences.
-                if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) {  // Load the URL in a new tab.
-                    // Set the loading new intent flag.
-                    loadingNewIntent = true;
-
-                    // Add a new tab.
-                    addNewTab(url, true);
-                } else {  // Load the URL in the current tab.
-                    // Make it so.
-                    loadUrl(currentWebView, url);
-                }
-            }
-        }
-    }
-
-    public void addTab(View view) {
-        // Add a new tab with a blank URL.
-        addNewTab("", true);
-    }
-
-    private void addNewTab(String url, boolean moveToTab) {
-        // Get the new page number.  The page numbers are 0 indexed, so the new page number will match the current count.
-        int newTabNumber = tabLayout.getTabCount();
-
-        // Add a new tab.
-        tabLayout.addTab(tabLayout.newTab());
-
-        // Get the new tab.
-        TabLayout.Tab newTab = tabLayout.getTabAt(newTabNumber);
-
-        // Remove the lint warning below that the current tab might be null.
-        assert newTab != null;
-
-        // Set a custom view on the new tab.
-        newTab.setCustomView(R.layout.tab_custom_view);
-
-        // Add the new WebView page.
-        webViewPagerAdapter.addPage(newTabNumber, webViewPager, url, moveToTab);
-    }
-
-    public void closeTab(View view) {
-        // Run the command according to the number of tabs.
-        if (tabLayout.getTabCount() > 1) {  // There is more than one tab open.
-            // Close the current tab.
-            closeCurrentTab();
-        } else {  // There is only one tab open.
-            clearAndExit();
-        }
-    }
-
-    private void closeCurrentTab() {
-        // Pause the current WebView.  This prevents buffered audio from playing after the tab is closed.
-        currentWebView.onPause();
-
-        // Get the current tab number.
-        int currentTabNumber = tabLayout.getSelectedTabPosition();
-
-        // Delete the current tab.
-        tabLayout.removeTabAt(currentTabNumber);
-
-        // Delete the current page.  If the selected page number did not change during the delete, it will return true, meaning that the current WebView must be reset.
-        if (webViewPagerAdapter.deletePage(currentTabNumber, webViewPager)) {
-            setCurrentWebView(currentTabNumber);
-        }
-
-        // Expand the app bar if it is currently collapsed.
-        appBarLayout.setExpanded(true);
-    }
-
-    private void saveWebpageArchive(String filePath) {
-        // Save the webpage archive.
-        currentWebView.saveWebArchive(filePath);
-
-        // Display a snackbar.
-        Snackbar saveWebpageArchiveSnackbar = Snackbar.make(currentWebView, getString(R.string.file_saved) + "  " + filePath, Snackbar.LENGTH_SHORT);
-
-        // Add an open option to the snackbar.
-        saveWebpageArchiveSnackbar.setAction(R.string.open, (View view) -> {
-            // Get a file for the file name string.
-            File file = new File(filePath);
-
-            // Declare a file URI variable.
-            Uri fileUri;
-
-            // Get the URI for the file according to the Android version.
-            if (Build.VERSION.SDK_INT >= 24) {  // Use a file provider.
-                fileUri = FileProvider.getUriForFile(this, getString(R.string.file_provider), file);
-            } else {  // Get the raw file path URI.
-                fileUri = Uri.fromFile(file);
-            }
-
-            // Get a handle for the content resolver.
-            ContentResolver contentResolver = getContentResolver();
-
-            // Create an open intent with `ACTION_VIEW`.
-            Intent openIntent = new Intent(Intent.ACTION_VIEW);
-
-            // Set the URI and the MIME type.
-            openIntent.setDataAndType(fileUri, contentResolver.getType(fileUri));
-
-            // Allow the app to read the file URI.
-            openIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-
-            // Show the chooser.
-            startActivity(Intent.createChooser(openIntent, getString(R.string.open)));
-        });
-
-        // Show the snackbar.
-        saveWebpageArchiveSnackbar.show();
-    }
-
-    private void clearAndExit() {
-        // Get a handle for the shared preferences.
-        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
-
-        // Close the bookmarks cursor and database.
-        bookmarksCursor.close();
-        bookmarksDatabaseHelper.close();
-
-        // Get the status of the clear everything preference.
-        boolean clearEverything = sharedPreferences.getBoolean("clear_everything", true);
-
-        // Get a handle for the runtime.
-        Runtime runtime = Runtime.getRuntime();
-
-        // Get the application's private data directory, which will be something like `/data/user/0/com.stoutner.privacybrowser.standard`,
-        // which links to `/data/data/com.stoutner.privacybrowser.standard`.
-        String privateDataDirectoryString = getApplicationInfo().dataDir;
-
-        // Clear cookies.
-        if (clearEverything || sharedPreferences.getBoolean("clear_cookies", true)) {
-            // The command to remove cookies changed slightly in API 21.
-            if (Build.VERSION.SDK_INT >= 21) {
-                CookieManager.getInstance().removeAllCookies(null);
-            } else {
-                CookieManager.getInstance().removeAllCookie();
-            }
-
-            // Manually delete the cookies database, as `CookieManager` sometimes will not flush its changes to disk before `System.exit(0)` is run.
-            try {
-                // Two commands must be used because `Runtime.exec()` does not like `*`.
-                Process deleteCookiesProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/Cookies");
-                Process deleteCookiesJournalProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/Cookies-journal");
-
-                // Wait until the processes have finished.
-                deleteCookiesProcess.waitFor();
-                deleteCookiesJournalProcess.waitFor();
-            } catch (Exception exception) {
-                // Do nothing if an error is thrown.
-            }
-        }
-
-        // Clear DOM storage.
-        if (clearEverything || sharedPreferences.getBoolean("clear_dom_storage", true)) {
-            // Ask `WebStorage` to clear the DOM storage.
-            WebStorage webStorage = WebStorage.getInstance();
-            webStorage.deleteAllData();
-
-            // Manually delete the DOM storage files and directories, as `WebStorage` sometimes will not flush its changes to disk before `System.exit(0)` is run.
-            try {
-                // A `String[]` must be used because the directory contains a space and `Runtime.exec` will otherwise not escape the string correctly.
-                Process deleteLocalStorageProcess = runtime.exec(new String[] {"rm", "-rf", privateDataDirectoryString + "/app_webview/Local Storage/"});
-
-                // Multiple commands must be used because `Runtime.exec()` does not like `*`.
-                Process deleteIndexProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/IndexedDB");
-                Process deleteQuotaManagerProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager");
-                Process deleteQuotaManagerJournalProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager-journal");
-                Process deleteDatabaseProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/databases");
-
-                // Wait until the processes have finished.
-                deleteLocalStorageProcess.waitFor();
-                deleteIndexProcess.waitFor();
-                deleteQuotaManagerProcess.waitFor();
-                deleteQuotaManagerJournalProcess.waitFor();
-                deleteDatabaseProcess.waitFor();
-            } catch (Exception exception) {
-                // Do nothing if an error is thrown.
-            }
-        }
-
-        // Clear form data if the API < 26.
-        if ((Build.VERSION.SDK_INT < 26) && (clearEverything || sharedPreferences.getBoolean("clear_form_data", true))) {
-            WebViewDatabase webViewDatabase = WebViewDatabase.getInstance(this);
-            webViewDatabase.clearFormData();
-
-            // Manually delete the form data database, as `WebViewDatabase` sometimes will not flush its changes to disk before `System.exit(0)` is run.
-            try {
-                // A string array must be used because the database contains a space and `Runtime.exec` will not otherwise escape the string correctly.
-                Process deleteWebDataProcess = runtime.exec(new String[] {"rm", "-f", privateDataDirectoryString + "/app_webview/Web Data"});
-                Process deleteWebDataJournalProcess = runtime.exec(new String[] {"rm", "-f", privateDataDirectoryString + "/app_webview/Web Data-journal"});
-
-                // Wait until the processes have finished.
-                deleteWebDataProcess.waitFor();
-                deleteWebDataJournalProcess.waitFor();
-            } catch (Exception exception) {
-                // Do nothing if an error is thrown.
-            }
-        }
-
-        // Clear the logcat.
-        if (clearEverything || sharedPreferences.getBoolean(getString(R.string.clear_logcat_key), true)) {
-            try {
-                // Clear the logcat.  `-c` clears the logcat.  `-b all` clears all the buffers (instead of just crash, main, and system).
-                Process process = Runtime.getRuntime().exec("logcat -b all -c");
-
-                // Wait for the process to finish.
-                process.waitFor();
-            } catch (IOException|InterruptedException exception) {
-                // Do nothing.
-            }
-        }
-
-        // Clear the cache.
-        if (clearEverything || sharedPreferences.getBoolean("clear_cache", true)) {
-            // Clear the cache from each WebView.
-            for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
-                // Get the WebView tab fragment.
-                WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
-
-                // Get the fragment view.
-                View fragmentView = webViewTabFragment.getView();
-
-                // Only clear the cache if the WebView exists.
-                if (fragmentView != null) {
-                    // Get the nested scroll WebView from the tab fragment.
-                    NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
-
-                    // Clear the cache for this WebView.
-                    nestedScrollWebView.clearCache(true);
-                }
-            }
-
-            // Manually delete the cache directories.
-            try {
-                // Delete the main cache directory.
-                Process deleteCacheProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/cache");
-
-                // Delete the secondary `Service Worker` cache directory.
-                // A string array must be used because the directory contains a space and `Runtime.exec` will otherwise not escape the string correctly.
-                Process deleteServiceWorkerProcess = runtime.exec(new String[] {"rm", "-rf", privateDataDirectoryString + "/app_webview/Service Worker/"});
-
-                // Wait until the processes have finished.
-                deleteCacheProcess.waitFor();
-                deleteServiceWorkerProcess.waitFor();
-            } catch (Exception exception) {
-                // Do nothing if an error is thrown.
-            }
-        }
-
-        // Wipe out each WebView.
-        for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
-            // Get the WebView tab fragment.
-            WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
-
-            // Get the fragment view.
-            View fragmentView = webViewTabFragment.getView();
-
-            // Only wipe out the WebView if it exists.
-            if (fragmentView != null) {
-                // Get the nested scroll WebView from the tab fragment.
-                NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
-
-                // Clear SSL certificate preferences for this WebView.
-                nestedScrollWebView.clearSslPreferences();
-
-                // Clear the back/forward history for this WebView.
-                nestedScrollWebView.clearHistory();
-
-                // Destroy the internal state of the WebView.
-                nestedScrollWebView.destroy();
-            }
-        }
-
-        // Clear the custom headers.
-        customHeaders.clear();
-
-        // Manually delete the `app_webview` folder, which contains the cookies, DOM storage, form data, and `Service Worker` cache.
-        // See `https://code.google.com/p/android/issues/detail?id=233826&thanks=233826&ts=1486670530`.
-        if (clearEverything) {
-            try {
-                // Delete the folder.
-                Process deleteAppWebviewProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/app_webview");
-
-                // Wait until the process has finished.
-                deleteAppWebviewProcess.waitFor();
-            } catch (Exception exception) {
-                // Do nothing if an error is thrown.
-            }
-        }
-
-        // Close Privacy Browser.  `finishAndRemoveTask` also removes Privacy Browser from the recent app list.
-        if (Build.VERSION.SDK_INT >= 21) {
-            finishAndRemoveTask();
-        } else {
-            finish();
-        }
-
-        // Remove the terminated program from RAM.  The status code is `0`.
-        System.exit(0);
-    }
-
-    public void bookmarksBack(View view) {
-        if (currentBookmarksFolder.isEmpty()) {  // The home folder is displayed.
-            // close the bookmarks drawer.
-            drawerLayout.closeDrawer(GravityCompat.END);
-        } else {  // A subfolder is displayed.
-            // Place the former parent folder in `currentFolder`.
-            currentBookmarksFolder = bookmarksDatabaseHelper.getParentFolderName(currentBookmarksFolder);
-
-            // Load the new folder.
-            loadBookmarksFolder();
-        }
-    }
-
-    private void setCurrentWebView(int pageNumber) {
-        // Get handles for the URL views.
-        RelativeLayout urlRelativeLayout = findViewById(R.id.url_relativelayout);
-        EditText urlEditText = findViewById(R.id.url_edittext);
-        SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
-
-        // Stop the swipe to refresh indicator if it is running
-        swipeRefreshLayout.setRefreshing(false);
-
-        // Get the WebView tab fragment.
-        WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(pageNumber);
-
-        // Get the fragment view.
-        View fragmentView = webViewTabFragment.getView();
-
-        // Set the current WebView if the fragment view is not null.
-        if (fragmentView != null) {  // The fragment has been populated.
-            // Store the current WebView.
-            currentWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
-
-            // Update the status of swipe to refresh.
-            if (currentWebView.getSwipeToRefresh()) {  // Swipe to refresh is enabled.
-                // Enable the swipe refresh layout if the WebView is scrolled all the way to the top.  It is updated every time the scroll changes.
-                swipeRefreshLayout.setEnabled(currentWebView.getY() == 0);
-            } else {  // Swipe to refresh is disabled.
-                // Disable the swipe refresh layout.
-                swipeRefreshLayout.setEnabled(false);
-            }
-
-            // Get a handle for the cookie manager.
-            CookieManager cookieManager = CookieManager.getInstance();
-
-            // Set the first-party cookie status.
-            cookieManager.setAcceptCookie(currentWebView.getAcceptFirstPartyCookies());
-
-            // Update the privacy icons.  `true` redraws the icons in the app bar.
-            updatePrivacyIcons(true);
-
-            // Get a handle for the input method manager.
-            InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
-
-            // Remove the lint warning below that the input method manager might be null.
-            assert inputMethodManager != null;
-
-            // Get the current URL.
-            String url = currentWebView.getUrl();
-
-            // Update the URL edit text if not loading a new intent.  Otherwise, this will be handled by `onPageStarted()` (if called) and `onPageFinished()`.
-            if (!loadingNewIntent) {  // A new intent is not being loaded.
-                if ((url == null) || url.equals("about:blank")) {  // The WebView is blank.
-                    // Display the hint in the URL edit text.
-                    urlEditText.setText("");
-
-                    // Request focus for the URL text box.
-                    urlEditText.requestFocus();
-
-                    // Display the keyboard.
-                    inputMethodManager.showSoftInput(urlEditText, 0);
-                } else {  // The WebView has a loaded URL.
-                    // Clear the focus from the URL text box.
-                    urlEditText.clearFocus();
-
-                    // Hide the soft keyboard.
-                    inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0);
-
-                    // Display the current URL in the URL text box.
-                    urlEditText.setText(url);
-
-                    // Highlight the URL text.
-                    highlightUrlText();
-                }
-            } else {  // A new intent is being loaded.
-                // Reset the loading new intent tracker.
-                loadingNewIntent = false;
-            }
-
-            // Set the background to indicate the domain settings status.
-            if (currentWebView.getDomainSettingsApplied()) {
-                // Get the current theme status.
-                int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
-                // Set a green background on the URL relative layout to indicate that custom domain settings are being used.
-                if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
-                    urlRelativeLayout.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.url_bar_background_light_green, null));
-                } else {
-                    urlRelativeLayout.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.url_bar_background_dark_blue, null));
-                }
-            } else {
-                urlRelativeLayout.setBackground(ResourcesCompat.getDrawable(getResources(), R.color.transparent, null));
-            }
-        } else {  // The fragment has not been populated.  Try again in 100 milliseconds.
-            // Create a handler to set the current WebView.
-            Handler setCurrentWebViewHandler = new Handler();
-
-            // Create a runnable to set the current WebView.
-            Runnable setCurrentWebWebRunnable = () -> {
-                // Set the current WebView.
-                setCurrentWebView(pageNumber);
-            };
-
-            // Try setting the current WebView again after 100 milliseconds.
-            setCurrentWebViewHandler.postDelayed(setCurrentWebWebRunnable, 100);
-        }
-    }
-
-    @Override
-    public void initializeWebView(NestedScrollWebView nestedScrollWebView, int pageNumber, ProgressBar progressBar, String url, Boolean restoringState) {
-        // Get a handle for the shared preferences.
-        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
-
-        // Get the WebView theme.
-        String webViewTheme = sharedPreferences.getString("webview_theme", getString(R.string.webview_theme_default_value));
-
-        // Get the WebView theme entry values string array.
-        String[] webViewThemeEntryValuesStringArray = getResources().getStringArray(R.array.webview_theme_entry_values);
-
-        // Apply the WebView theme if supported by the installed WebView.
-        if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
-            // Set the WebView theme.  A switch statement cannot be used because the WebView theme entry values string array is not a compile time constant.
-            if (webViewTheme.equals(webViewThemeEntryValuesStringArray[1])) {  // The light theme is selected.
-                // Turn off the WebView dark mode.
-                WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_OFF);
-
-                // Make the WebView visible. The WebView was created invisible in `webview_framelayout` to prevent a white background splash in night mode.
-                // If the system is currently in night mode, showing the WebView will be handled in `onProgressChanged()`.
-                nestedScrollWebView.setVisibility(View.VISIBLE);
-            } else if (webViewTheme.equals(webViewThemeEntryValuesStringArray[2])) {  // The dark theme is selected.
-                // Turn on the WebView dark mode.
-                WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_ON);
-            } else {  // The system default theme is selected.
-                // Get the current system theme status.
-                int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
-                // Set the WebView theme according to the current system theme status.
-                if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {  // The system is in day mode.
-                    // Turn off the WebView dark mode.
-                    WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_OFF);
-
-                    // Make the WebView visible. The WebView was created invisible in `webview_framelayout` to prevent a white background splash in night mode.
-                    // If the system is currently in night mode, showing the WebView will be handled in `onProgressChanged()`.
-                    nestedScrollWebView.setVisibility(View.VISIBLE);
-                } else {  // The system is in night mode.
-                    // Turn on the WebView dark mode.
-                    WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_ON);
-                }
-            }
-        }
-
-        // Get a handle for the app compat delegate.
-        AppCompatDelegate appCompatDelegate = getDelegate();
-
-        // Get handles for the activity views.
-        FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout);
-        RelativeLayout mainContentRelativeLayout = findViewById(R.id.main_content_relativelayout);
-        ActionBar actionBar = appCompatDelegate.getSupportActionBar();
-        LinearLayout tabsLinearLayout = findViewById(R.id.tabs_linearlayout);
-        EditText urlEditText = findViewById(R.id.url_edittext);
-        SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
-
-        // Remove the incorrect lint warning below that the action bar might be null.
-        assert actionBar != null;
-
-        // Get a handle for the activity
-        Activity activity = this;
-
-        // Get a handle for the input method manager.
-        InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
-
-        // Instantiate the blocklist helper.
-        BlocklistHelper blocklistHelper = new BlocklistHelper();
-
-        // Remove the lint warning below that the input method manager might be null.
-        assert inputMethodManager != null;
-
-        // Initialize the favorite icon.
-        nestedScrollWebView.initializeFavoriteIcon();
-
-        // Set the app bar scrolling.
-        nestedScrollWebView.setNestedScrollingEnabled(sharedPreferences.getBoolean("scroll_app_bar", true));
-
-        // Allow pinch to zoom.
-        nestedScrollWebView.getSettings().setBuiltInZoomControls(true);
-
-        // Hide zoom controls.
-        nestedScrollWebView.getSettings().setDisplayZoomControls(false);
-
-        // Don't allow mixed content (HTTP and HTTPS) on the same website.
-        if (Build.VERSION.SDK_INT >= 21) {
-            nestedScrollWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_NEVER_ALLOW);
-        }
-
-        // Set the WebView to load in overview mode (zoomed out to the maximum width).
-        nestedScrollWebView.getSettings().setLoadWithOverviewMode(true);
-
-        // Explicitly disable geolocation.
-        nestedScrollWebView.getSettings().setGeolocationEnabled(false);
-
-        // Create a double-tap gesture detector to toggle full-screen mode.
-        GestureDetector doubleTapGestureDetector = new GestureDetector(getApplicationContext(), new GestureDetector.SimpleOnGestureListener() {
-            // Override `onDoubleTap()`.  All other events are handled using the default settings.
-            @Override
-            public boolean onDoubleTap(MotionEvent event) {
-                if (fullScreenBrowsingModeEnabled) {  // Only process the double-tap if full screen browsing mode is enabled.
-                    // Toggle the full screen browsing mode tracker.
-                    inFullScreenBrowsingMode = !inFullScreenBrowsingMode;
-
-                    // Toggle the full screen browsing mode.
-                    if (inFullScreenBrowsingMode) {  // Switch to full screen mode.
-                        // Hide the app bar if specified.
-                        if (hideAppBar) {
-                            // Close the find on page bar if it is visible.
-                            closeFindOnPage(null);
-
-                            // Hide the tab linear layout.
-                            tabsLinearLayout.setVisibility(View.GONE);
-
-                            // Hide the action bar.
-                            actionBar.hide();
-
-                            // Check to see if the app bar is normally scrolled.
-                            if (scrollAppBar) {  // The app bar is scrolled when it is displayed.
-                                // Get the swipe refresh layout parameters.
-                                CoordinatorLayout.LayoutParams swipeRefreshLayoutParams = (CoordinatorLayout.LayoutParams) swipeRefreshLayout.getLayoutParams();
-
-                                // Remove the off-screen scrolling layout.
-                                swipeRefreshLayoutParams.setBehavior(null);
-                            } else {  // The app bar is not scrolled when it is displayed.
-                                // Remove the padding from the top of the swipe refresh layout.
-                                swipeRefreshLayout.setPadding(0, 0, 0, 0);
-
-                                // The swipe refresh circle must be moved above the now removed status bar location.
-                                swipeRefreshLayout.setProgressViewOffset(false, -200, defaultProgressViewEndOffset);
-                            }
-                        }
-
-                        // Hide the banner ad in the free flavor.
-                        if (BuildConfig.FLAVOR.contentEquals("free")) {
-                            AdHelper.hideAd(findViewById(R.id.adview));
-                        }
-
-                        /* Hide the system bars.
-                         * SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen.
-                         * SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN makes the root frame layout fill the area that is normally reserved for the status bar.
-                         * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen.
-                         * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically re-hides them after they are shown.
-                         */
-                        rootFrameLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
-                                View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
-                    } else {  // Switch to normal viewing mode.
-                        // Show the app bar if it was hidden.
-                        if (hideAppBar) {
-                            // Show the tab linear layout.
-                            tabsLinearLayout.setVisibility(View.VISIBLE);
-
-                            // Show the action bar.
-                            actionBar.show();
-
-                            // Check to see if the app bar is normally scrolled.
-                            if (scrollAppBar) {  // The app bar is scrolled when it is displayed.
-                                // Get the swipe refresh layout parameters.
-                                CoordinatorLayout.LayoutParams swipeRefreshLayoutParams = (CoordinatorLayout.LayoutParams) swipeRefreshLayout.getLayoutParams();
-
-                                // Add the off-screen scrolling layout.
-                                swipeRefreshLayoutParams.setBehavior(new AppBarLayout.ScrollingViewBehavior());
-                            } else {  // The app bar is not scrolled when it is displayed.
-                                // The swipe refresh layout must be manually moved below the app bar layout.
-                                swipeRefreshLayout.setPadding(0, appBarHeight, 0, 0);
-
-                                // The swipe to refresh circle doesn't always hide itself completely unless it is moved up 10 pixels.
-                                swipeRefreshLayout.setProgressViewOffset(false, defaultProgressViewStartOffset - 10 + appBarHeight, defaultProgressViewEndOffset + appBarHeight);
-                            }
-                        }
-
-                        // Show the banner ad in the free flavor.
-                        if (BuildConfig.FLAVOR.contentEquals("free")) {
-                            // Reload the ad.
-                            AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_unit_id));
-                        }
-
-                        // Remove the `SYSTEM_UI` flags from the root frame layout.
-                        rootFrameLayout.setSystemUiVisibility(0);
-                    }
-
-                    // Consume the double-tap.
-                    return true;
-                } else { // Do not consume the double-tap because full screen browsing mode is disabled.
-                    return false;
-                }
-            }
-        });
-
-        // Pass all touch events on the WebView through the double-tap gesture detector.
-        nestedScrollWebView.setOnTouchListener((View view, MotionEvent event) -> {
-            // Call `performClick()` on the view, which is required for accessibility.
-            view.performClick();
-
-            // Send the event to the gesture detector.
-            return doubleTapGestureDetector.onTouchEvent(event);
-        });
-
-        // Register the WebView for a context menu.  This is used to see link targets and download images.
-        registerForContextMenu(nestedScrollWebView);
-
-        // Allow the downloading of files.
-        nestedScrollWebView.setDownloadListener((String downloadUrl, String userAgent, String contentDisposition, String mimetype, long contentLength) -> {
-            // Define a formatted file size string.
-            String formattedFileSizeString;
-
-            // Process the content length if it contains data.
-            if (contentLength > 0) {  // The content length is greater than 0.
-                // Format the content length as a string.
-                formattedFileSizeString = NumberFormat.getInstance().format(contentLength) + " " + getString(R.string.bytes);
-            } else {  // The content length is not greater than 0.
-                // Set the formatted file size string to be `unknown size`.
-                formattedFileSizeString = getString(R.string.unknown_size);
-            }
-
-            // Get the file name from the content disposition.
-            String fileNameString = PrepareSaveDialog.getFileNameFromHeaders(this, contentDisposition, mimetype, downloadUrl);
-
-            // Instantiate the save dialog.
-            DialogFragment saveDialogFragment = SaveWebpageDialog.saveWebpage(StoragePermissionDialog.SAVE_URL, downloadUrl, formattedFileSizeString, fileNameString, userAgent,
-                    nestedScrollWebView.getAcceptFirstPartyCookies());
-
-            // Show the save dialog.  It must be named `save_dialog` so that the file picker can update the file name.
-            saveDialogFragment.show(getSupportFragmentManager(), getString(R.string.save_dialog));
-        });
-
-        // Update the find on page count.
-        nestedScrollWebView.setFindListener(new WebView.FindListener() {
-            // Get a handle for `findOnPageCountTextView`.
-            final TextView findOnPageCountTextView = findViewById(R.id.find_on_page_count_textview);
-
-            @Override
-            public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches, boolean isDoneCounting) {
-                if ((isDoneCounting) && (numberOfMatches == 0)) {  // There are no matches.
-                    // Set `findOnPageCountTextView` to `0/0`.
-                    findOnPageCountTextView.setText(R.string.zero_of_zero);
-                } else if (isDoneCounting) {  // There are matches.
-                    // `activeMatchOrdinal` is zero-based.
-                    int activeMatch = activeMatchOrdinal + 1;
-
-                    // Build the match string.
-                    String matchString = activeMatch + "/" + numberOfMatches;
-
-                    // Set `findOnPageCountTextView`.
-                    findOnPageCountTextView.setText(matchString);
-                }
-            }
-        });
-
-        // Update the status of swipe to refresh based on the scroll position of the nested scroll WebView.  Also reinforce full screen browsing mode.
-        // On API < 23, `getViewTreeObserver().addOnScrollChangedListener()` must be used, but it is a little bit buggy and appears to get garbage collected from time to time.
-        if (Build.VERSION.SDK_INT >= 23) {
-            nestedScrollWebView.setOnScrollChangeListener((view, i, i1, i2, i3) -> {
-                if (nestedScrollWebView.getSwipeToRefresh()) {
-                    // Only enable swipe to refresh if the WebView is scrolled to the top.
-                    swipeRefreshLayout.setEnabled(nestedScrollWebView.getScrollY() == 0);
-                } else {
-                    // Disable swipe to refresh.
-                    swipeRefreshLayout.setEnabled(false);
-                }
-
-                // Reinforce the system UI visibility flags if in full screen browsing mode.
-                // This hides the status and navigation bars, which are displayed if other elements are shown, like dialog boxes, the options menu, or the keyboard.
-                if (inFullScreenBrowsingMode) {
-                    /* Hide the system bars.
-                     * SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen.
-                     * SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN makes the root frame layout fill the area that is normally reserved for the status bar.
-                     * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen.
-                     * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically re-hides them after they are shown.
-                     */
-                    rootFrameLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
-                            View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
-                }
-            });
-        } else {
-            nestedScrollWebView.getViewTreeObserver().addOnScrollChangedListener(() -> {
-                if (nestedScrollWebView.getSwipeToRefresh()) {
-                    // Only enable swipe to refresh if the WebView is scrolled to the top.
-                    swipeRefreshLayout.setEnabled(nestedScrollWebView.getScrollY() == 0);
-                } else {
-                    // Disable swipe to refresh.
-                    swipeRefreshLayout.setEnabled(false);
-                }
-
-
-                // Reinforce the system UI visibility flags if in full screen browsing mode.
-                // This hides the status and navigation bars, which are displayed if other elements are shown, like dialog boxes, the options menu, or the keyboard.
-                if (inFullScreenBrowsingMode) {
-                    /* Hide the system bars.
-                     * SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen.
-                     * SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN makes the root frame layout fill the area that is normally reserved for the status bar.
-                     * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen.
-                     * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically re-hides them after they are shown.
-                     */
-                    rootFrameLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
-                            View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
-                }
-            });
-        }
-
-        // Set the web chrome client.
-        nestedScrollWebView.setWebChromeClient(new WebChromeClient() {
-            // Update the progress bar when a page is loading.
-            @Override
-            public void onProgressChanged(WebView view, int progress) {
-                // Update the progress bar.
-                progressBar.setProgress(progress);
-
-                // Set the visibility of the progress bar.
-                if (progress < 100) {
-                    // Show the progress bar.
-                    progressBar.setVisibility(View.VISIBLE);
-                } else {
-                    // Hide the progress bar.
-                    progressBar.setVisibility(View.GONE);
-
-                    //Stop the swipe to refresh indicator if it is running
-                    swipeRefreshLayout.setRefreshing(false);
-
-                    // Make the current WebView visible.  If this is a new tab, the current WebView would have been created invisible in `webview_framelayout` to prevent a white background splash in night mode.
-                    nestedScrollWebView.setVisibility(View.VISIBLE);
-                }
-            }
-
-            // Set the favorite icon when it changes.
-            @Override
-            public void onReceivedIcon(WebView view, Bitmap icon) {
-                // Only update the favorite icon if the website has finished loading.
-                if (progressBar.getVisibility() == View.GONE) {
-                    // Store the new favorite icon.
-                    nestedScrollWebView.setFavoriteOrDefaultIcon(icon);
-
-                    // Get the current page position.
-                    int currentPosition = webViewPagerAdapter.getPositionForId(nestedScrollWebView.getWebViewFragmentId());
-
-                    // Get the current tab.
-                    TabLayout.Tab tab = tabLayout.getTabAt(currentPosition);
-
-                    // Check to see if the tab has been populated.
-                    if (tab != null) {
-                        // Get the custom view from the tab.
-                        View tabView = tab.getCustomView();
-
-                        // Check to see if the custom tab view has been populated.
-                        if (tabView != null) {
-                            // Get the favorite icon image view from the tab.
-                            ImageView tabFavoriteIconImageView = tabView.findViewById(R.id.favorite_icon_imageview);
-
-                            // Display the favorite icon in the tab.
-                            tabFavoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(icon, 64, 64, true));
-                        }
-                    }
-                }
-            }
-
-            // Save a copy of the title when it changes.
-            @Override
-            public void onReceivedTitle(WebView view, String title) {
-                // Get the current page position.
-                int currentPosition = webViewPagerAdapter.getPositionForId(nestedScrollWebView.getWebViewFragmentId());
-
-                // Get the current tab.
-                TabLayout.Tab tab = tabLayout.getTabAt(currentPosition);
-
-                // Only populate the title text view if the tab has been fully created.
-                if (tab != null) {
-                    // Get the custom view from the tab.
-                    View tabView = tab.getCustomView();
-
-                    // Only populate the title text view if the tab view has been fully populated.
-                    if (tabView != null) {
-                        // Get the title text view from the tab.
-                        TextView tabTitleTextView = tabView.findViewById(R.id.title_textview);
-
-                        // Set the title according to the URL.
-                        if (title.equals("about:blank")) {
-                            // Set the title to indicate a new tab.
-                            tabTitleTextView.setText(R.string.new_tab);
-                        } else {
-                            // Set the title as the tab text.
-                            tabTitleTextView.setText(title);
-                        }
-                    }
-                }
-            }
-
-            // Enter full screen video.
-            @Override
-            public void onShowCustomView(View video, CustomViewCallback callback) {
-                // Get a handle for the full screen video frame layout.
-                FrameLayout fullScreenVideoFrameLayout = findViewById(R.id.full_screen_video_framelayout);
-
-                // Set the full screen video flag.
-                displayingFullScreenVideo = true;
-
-                // Pause the ad if this is the free flavor.
-                if (BuildConfig.FLAVOR.contentEquals("free")) {
-                    // The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
-                    AdHelper.pauseAd(findViewById(R.id.adview));
-                }
-
-                // Hide the keyboard.
-                inputMethodManager.hideSoftInputFromWindow(nestedScrollWebView.getWindowToken(), 0);
-
-                // Hide the main content relative layout.
-                mainContentRelativeLayout.setVisibility(View.GONE);
-
-                /* Hide the system bars.
-                 * SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen.
-                 * SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN makes the root frame layout fill the area that is normally reserved for the status bar.
-                 * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen.
-                 * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically re-hides them after they are shown.
-                 */
-                rootFrameLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
-                        View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
-
-                // Disable the sliding drawers.
-                drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
-
-                // Add the video view to the full screen video frame layout.
-                fullScreenVideoFrameLayout.addView(video);
-
-                // Show the full screen video frame layout.
-                fullScreenVideoFrameLayout.setVisibility(View.VISIBLE);
-
-                // Disable the screen timeout while the video is playing.  YouTube does this automatically, but not all other videos do.
-                fullScreenVideoFrameLayout.setKeepScreenOn(true);
-            }
-
-            // Exit full screen video.
-            @Override
-            public void onHideCustomView() {
-                // Get a handle for the full screen video frame layout.
-                FrameLayout fullScreenVideoFrameLayout = findViewById(R.id.full_screen_video_framelayout);
-
-                // Re-enable the screen timeout.
-                fullScreenVideoFrameLayout.setKeepScreenOn(false);
-
-                // Unset the full screen video flag.
-                displayingFullScreenVideo = false;
-
-                // Remove all the views from the full screen video frame layout.
-                fullScreenVideoFrameLayout.removeAllViews();
-
-                // Hide the full screen video frame layout.
-                fullScreenVideoFrameLayout.setVisibility(View.GONE);
-
-                // Enable the sliding drawers.
-                drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
-
-                // Show the main content relative layout.
-                mainContentRelativeLayout.setVisibility(View.VISIBLE);
-
-                // Apply the appropriate full screen mode flags.
-                if (fullScreenBrowsingModeEnabled && inFullScreenBrowsingMode) {  // Privacy Browser is currently in full screen browsing mode.
-                    // Hide the app bar if specified.
-                    if (hideAppBar) {
-                        // Hide the tab linear layout.
-                        tabsLinearLayout.setVisibility(View.GONE);
-
-                        // Hide the action bar.
-                        actionBar.hide();
-                    }
-
-                    // Hide the banner ad in the free flavor.
-                    if (BuildConfig.FLAVOR.contentEquals("free")) {
-                        AdHelper.hideAd(findViewById(R.id.adview));
-                    }
-
-                    /* Hide the system bars.
-                     * SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen.
-                     * SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN makes the root frame layout fill the area that is normally reserved for the status bar.
-                     * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen.
-                     * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically re-hides them after they are shown.
-                     */
-                    rootFrameLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
-                            View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
-                } else {  // Switch to normal viewing mode.
-                    // Remove the `SYSTEM_UI` flags from the root frame layout.
-                    rootFrameLayout.setSystemUiVisibility(0);
-                }
-
-                // Reload the ad for the free flavor if not in full screen mode.
-                if (BuildConfig.FLAVOR.contentEquals("free") && !inFullScreenBrowsingMode) {
-                    // Reload the ad.
-                    AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_unit_id));
-                }
-            }
-
-            // Upload files.
-            @Override
-            public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
-                // Show the file chooser if the device is running API >= 21.
-                if (Build.VERSION.SDK_INT >= 21) {
-                    // Store the file path callback.
-                    fileChooserCallback = filePathCallback;
-
-                    // Create an intent to open a chooser based on the file chooser parameters.
-                    Intent fileChooserIntent = fileChooserParams.createIntent();
-
-                    // Get a handle for the package manager.
-                    PackageManager packageManager = getPackageManager();
-
-                    // Check to see if the file chooser intent resolves to an installed package.
-                    if (fileChooserIntent.resolveActivity(packageManager) != null) {  // The file chooser intent is fine.
-                        // Start the file chooser intent.
-                        startActivityForResult(fileChooserIntent, BROWSE_FILE_UPLOAD_REQUEST_CODE);
-                    } else {  // The file chooser intent will cause a crash.
-                        // Create a generic intent to open a chooser.
-                        Intent genericFileChooserIntent = new Intent(Intent.ACTION_GET_CONTENT);
-
-                        // Request an openable file.
-                        genericFileChooserIntent.addCategory(Intent.CATEGORY_OPENABLE);
-
-                        // Set the file type to everything.
-                        genericFileChooserIntent.setType("*/*");
-
-                        // Start the generic file chooser intent.
-                        startActivityForResult(genericFileChooserIntent, BROWSE_FILE_UPLOAD_REQUEST_CODE);
-                    }
-                }
-                return true;
-            }
-        });
-
-        nestedScrollWebView.setWebViewClient(new WebViewClient() {
-            // `shouldOverrideUrlLoading` makes this WebView the default handler for URLs inside the app, so that links are not kicked out to other apps.
-            // The deprecated `shouldOverrideUrlLoading` must be used until API >= 24.
-            @Override
-            public boolean shouldOverrideUrlLoading(WebView view, String url) {
-                // Sanitize the url.
-                url = sanitizeUrl(url);
-
-                // Handle the URL according to the type.
-                if (url.startsWith("http")) {  // Load the URL in Privacy Browser.
-                    // Load the URL.  By using `loadUrl()`, instead of `loadUrlFromBase()`, the Referer header will never be sent.
-                    loadUrl(nestedScrollWebView, url);
-
-                    // Returning true indicates that Privacy Browser is manually handling the loading of the URL.
-                    // Custom headers cannot be added if false is returned and the WebView handles the loading of the URL.
-                    return true;
-                } else if (url.startsWith("mailto:")) {  // Load the email address in an external email program.
-                    // Use `ACTION_SENDTO` instead of `ACTION_SEND` so that only email programs are launched.
-                    Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
-
-                    // Parse the url and set it as the data for the intent.
-                    emailIntent.setData(Uri.parse(url));
-
-                    // Open the email program in a new task instead of as part of Privacy Browser.
-                    emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-                    try {
-                        // Make it so.
-                        startActivity(emailIntent);
-                    } catch (ActivityNotFoundException exception) {
-                        // Display a snackbar.
-                        Snackbar.make(currentWebView, getString(R.string.error) + "  " + exception, Snackbar.LENGTH_INDEFINITE).show();
-                    }
-
-
-                    // Returning true indicates Privacy Browser is handling the URL by creating an intent.
-                    return true;
-                } else if (url.startsWith("tel:")) {  // Load the phone number in the dialer.
-                    // Open the dialer and load the phone number, but wait for the user to place the call.
-                    Intent dialIntent = new Intent(Intent.ACTION_DIAL);
-
-                    // Add the phone number to the intent.
-                    dialIntent.setData(Uri.parse(url));
-
-                    // Open the dialer in a new task instead of as part of Privacy Browser.
-                    dialIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-                    try {
-                        // Make it so.
-                        startActivity(dialIntent);
-                    } catch (ActivityNotFoundException exception) {
-                        // Display a snackbar.
-                        Snackbar.make(currentWebView, getString(R.string.error) + "  " + exception, Snackbar.LENGTH_INDEFINITE).show();
-                    }
-
-                    // Returning true indicates Privacy Browser is handling the URL by creating an intent.
-                    return true;
-                } else {  // Load a system chooser to select an app that can handle the URL.
-                    // Open an app that can handle the URL.
-                    Intent genericIntent = new Intent(Intent.ACTION_VIEW);
-
-                    // Add the URL to the intent.
-                    genericIntent.setData(Uri.parse(url));
-
-                    // List all apps that can handle the URL instead of just opening the first one.
-                    genericIntent.addCategory(Intent.CATEGORY_BROWSABLE);
-
-                    // Open the app in a new task instead of as part of Privacy Browser.
-                    genericIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-                    // Start the app or display a snackbar if no app is available to handle the URL.
-                    try {
-                        startActivity(genericIntent);
-                    } catch (ActivityNotFoundException exception) {
-                        Snackbar.make(nestedScrollWebView, getString(R.string.unrecognized_url) + "  " + url, Snackbar.LENGTH_SHORT).show();
-                    }
-
-                    // Returning true indicates Privacy Browser is handling the URL by creating an intent.
-                    return true;
-                }
-            }
-
-            // Check requests against the block lists.  The deprecated `shouldInterceptRequest()` must be used until minimum API >= 21.
-            @Override
-            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
-                // Check to see if the resource request is for the main URL.
-                if (url.equals(nestedScrollWebView.getCurrentUrl())) {
-                    // `return null` loads the resource request, which should never be blocked if it is the main URL.
-                    return null;
-                }
-
-                // Wait until the blocklists have been populated.  When Privacy Browser is being resumed after having the process killed in the background it will try to load the URLs immediately.
-                while (ultraPrivacy == null) {
-                    // The wait must be synchronized, which only lets one thread run on it at a time, or `java.lang.IllegalMonitorStateException` is thrown.
-                    synchronized (this) {
-                        try {
-                            // Check to see if the blocklists have been populated after 100 ms.
-                            wait(100);
-                        } catch (InterruptedException exception) {
-                            // Do nothing.
-                        }
-                    }
-                }
-
-                // Sanitize the URL.
-                url = sanitizeUrl(url);
-
-                // Get a handle for the navigation view.
-                NavigationView navigationView = findViewById(R.id.navigationview);
-
-                // Get a handle for the navigation menu.
-                Menu navigationMenu = navigationView.getMenu();
-
-                // Get a handle for the navigation requests menu item.
-                MenuItem navigationRequestsMenuItem = navigationMenu.findItem(R.id.requests);
-
-                // Create an empty web resource response to be used if the resource request is blocked.
-                WebResourceResponse emptyWebResourceResponse = new WebResourceResponse("text/plain", "utf8", new ByteArrayInputStream("".getBytes()));
-
-                // Reset the whitelist results tracker.
-                String[] whitelistResultStringArray = null;
-
-                // Initialize the third party request tracker.
-                boolean isThirdPartyRequest = false;
-
-                // Get the current URL.  `.getUrl()` throws an error because operations on the WebView cannot be made from this thread.
-                String currentBaseDomain = nestedScrollWebView.getCurrentDomainName();
-
-                // Store a copy of the current domain for use in later requests.
-                String currentDomain = currentBaseDomain;
-
-                // Nobody is happy when comparing null strings.
-                if ((currentBaseDomain != null) && (url != null)) {
-                    // Convert the request URL to a URI.
-                    Uri requestUri = Uri.parse(url);
-
-                    // Get the request host name.
-                    String requestBaseDomain = requestUri.getHost();
-
-                    // Only check for third-party requests if the current base domain is not empty and the request domain is not null.
-                    if (!currentBaseDomain.isEmpty() && (requestBaseDomain != null)) {
-                        // Determine the current base domain.
-                        while (currentBaseDomain.indexOf(".", currentBaseDomain.indexOf(".") + 1) > 0) {  // There is at least one subdomain.
-                            // Remove the first subdomain.
-                            currentBaseDomain = currentBaseDomain.substring(currentBaseDomain.indexOf(".") + 1);
-                        }
-
-                        // Determine the request base domain.
-                        while (requestBaseDomain.indexOf(".", requestBaseDomain.indexOf(".") + 1) > 0) {  // There is at least one subdomain.
-                            // Remove the first subdomain.
-                            requestBaseDomain = requestBaseDomain.substring(requestBaseDomain.indexOf(".") + 1);
-                        }
-
-                        // Update the third party request tracker.
-                        isThirdPartyRequest = !currentBaseDomain.equals(requestBaseDomain);
-                    }
-                }
-
-                // Get the current WebView page position.
-                int webViewPagePosition = webViewPagerAdapter.getPositionForId(nestedScrollWebView.getWebViewFragmentId());
-
-                // Determine if the WebView is currently displayed.
-                boolean webViewDisplayed = (webViewPagePosition == tabLayout.getSelectedTabPosition());
-
-                // Block third-party requests if enabled.
-                if (isThirdPartyRequest && nestedScrollWebView.isBlocklistEnabled(NestedScrollWebView.THIRD_PARTY_REQUESTS)) {
-                    // Add the result to the resource requests.
-                    nestedScrollWebView.addResourceRequest(new String[]{BlocklistHelper.REQUEST_THIRD_PARTY, url});
-
-                    // Increment the blocked requests counters.
-                    nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS);
-                    nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.THIRD_PARTY_REQUESTS);
-
-                    // Update the titles of the blocklist menu items if the WebView is currently displayed.
-                    if (webViewDisplayed) {
-                        // Updating the UI must be run from the UI thread.
-                        activity.runOnUiThread(() -> {
-                            // Update the menu item titles.
-                            navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
-
-                            // Update the options menu if it has been populated.
-                            if (optionsMenu != null) {
-                                optionsMenu.findItem(R.id.blocklists).setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
-                                optionsMenu.findItem(R.id.block_all_third_party_requests).setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.THIRD_PARTY_REQUESTS) + " - " +
-                                        getString(R.string.block_all_third_party_requests));
-                            }
-                        });
-                    }
-
-                    // Return an empty web resource response.
-                    return emptyWebResourceResponse;
-                }
-
-                // Check UltraList if it is enabled.
-                if (nestedScrollWebView.isBlocklistEnabled(NestedScrollWebView.ULTRALIST)) {
-                    // Check the URL against UltraList.
-                    String[] ultraListResults = blocklistHelper.checkBlocklist(currentDomain, url, isThirdPartyRequest, ultraList);
-
-                    // Process the UltraList results.
-                    if (ultraListResults[0].equals(BlocklistHelper.REQUEST_BLOCKED)) {  // The resource request matched UltraLists's blacklist.
-                        // Add the result to the resource requests.
-                        nestedScrollWebView.addResourceRequest(new String[] {ultraListResults[0], ultraListResults[1], ultraListResults[2], ultraListResults[3], ultraListResults[4], ultraListResults[5]});
-
-                        // Increment the blocked requests counters.
-                        nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS);
-                        nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.ULTRALIST);
-
-                        // Update the titles of the blocklist menu items if the WebView is currently displayed.
-                        if (webViewDisplayed) {
-                            // Updating the UI must be run from the UI thread.
-                            activity.runOnUiThread(() -> {
-                                // Update the menu item titles.
-                                navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
-
-                                // Update the options menu if it has been populated.
-                                if (optionsMenu != null) {
-                                    optionsMenu.findItem(R.id.blocklists).setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
-                                    optionsMenu.findItem(R.id.ultralist).setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.ULTRALIST) + " - " + getString(R.string.ultralist));
-                                }
-                            });
-                        }
-
-                        // The resource request was blocked.  Return an empty web resource response.
-                        return emptyWebResourceResponse;
-                    } else if (ultraListResults[0].equals(BlocklistHelper.REQUEST_ALLOWED)) {  // The resource request matched UltraList's whitelist.
-                        // Add a whitelist entry to the resource requests array.
-                        nestedScrollWebView.addResourceRequest(new String[] {ultraListResults[0], ultraListResults[1], ultraListResults[2], ultraListResults[3], ultraListResults[4], ultraListResults[5]});
-
-                        // The resource request has been allowed by UltraPrivacy.  `return null` loads the requested resource.
-                        return null;
-                    }
-                }
-
-                // Check UltraPrivacy if it is enabled.
-                if (nestedScrollWebView.isBlocklistEnabled(NestedScrollWebView.ULTRAPRIVACY)) {
-                    // Check the URL against UltraPrivacy.
-                    String[] ultraPrivacyResults = blocklistHelper.checkBlocklist(currentDomain, url, isThirdPartyRequest, ultraPrivacy);
-
-                    // Process the UltraPrivacy results.
-                    if (ultraPrivacyResults[0].equals(BlocklistHelper.REQUEST_BLOCKED)) {  // The resource request matched UltraPrivacy's blacklist.
-                        // Add the result to the resource requests.
-                        nestedScrollWebView.addResourceRequest(new String[] {ultraPrivacyResults[0], ultraPrivacyResults[1], ultraPrivacyResults[2], ultraPrivacyResults[3], ultraPrivacyResults[4],
-                                ultraPrivacyResults[5]});
-
-                        // Increment the blocked requests counters.
-                        nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS);
-                        nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.ULTRAPRIVACY);
-
-                        // Update the titles of the blocklist menu items if the WebView is currently displayed.
-                        if (webViewDisplayed) {
-                            // Updating the UI must be run from the UI thread.
-                            activity.runOnUiThread(() -> {
-                                // Update the menu item titles.
-                                navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
-
-                                // Update the options menu if it has been populated.
-                                if (optionsMenu != null) {
-                                    optionsMenu.findItem(R.id.blocklists).setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
-                                    optionsMenu.findItem(R.id.ultraprivacy).setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.ULTRAPRIVACY) + " - " + getString(R.string.ultraprivacy));
-                                }
-                            });
-                        }
-
-                        // The resource request was blocked.  Return an empty web resource response.
-                        return emptyWebResourceResponse;
-                    } else if (ultraPrivacyResults[0].equals(BlocklistHelper.REQUEST_ALLOWED)) {  // The resource request matched UltraPrivacy's whitelist.
-                        // Add a whitelist entry to the resource requests array.
-                        nestedScrollWebView.addResourceRequest(new String[] {ultraPrivacyResults[0], ultraPrivacyResults[1], ultraPrivacyResults[2], ultraPrivacyResults[3], ultraPrivacyResults[4],
-                                ultraPrivacyResults[5]});
-
-                        // The resource request has been allowed by UltraPrivacy.  `return null` loads the requested resource.
-                        return null;
-                    }
-                }
-
-                // Check EasyList if it is enabled.
-                if (nestedScrollWebView.isBlocklistEnabled(NestedScrollWebView.EASYLIST)) {
-                    // Check the URL against EasyList.
-                    String[] easyListResults = blocklistHelper.checkBlocklist(currentDomain, url, isThirdPartyRequest, easyList);
-
-                    // Process the EasyList results.
-                    if (easyListResults[0].equals(BlocklistHelper.REQUEST_BLOCKED)) {  // The resource request matched EasyList's blacklist.
-                        // Add the result to the resource requests.
-                        nestedScrollWebView.addResourceRequest(new String[] {easyListResults[0], easyListResults[1], easyListResults[2], easyListResults[3], easyListResults[4], easyListResults[5]});
-
-                        // Increment the blocked requests counters.
-                        nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS);
-                        nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.EASYLIST);
-
-                        // Update the titles of the blocklist menu items if the WebView is currently displayed.
-                        if (webViewDisplayed) {
-                            // Updating the UI must be run from the UI thread.
-                            activity.runOnUiThread(() -> {
-                                // Update the menu item titles.
-                                navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
-
-                                // Update the options menu if it has been populated.
-                                if (optionsMenu != null) {
-                                    optionsMenu.findItem(R.id.blocklists).setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
-                                    optionsMenu.findItem(R.id.easylist).setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.EASYLIST) + " - " + getString(R.string.easylist));
-                                }
-                            });
-                        }
-
-                        // The resource request was blocked.  Return an empty web resource response.
-                        return emptyWebResourceResponse;
-                    } else if (easyListResults[0].equals(BlocklistHelper.REQUEST_ALLOWED)) {  // The resource request matched EasyList's whitelist.
-                        // Update the whitelist result string array tracker.
-                        whitelistResultStringArray = new String[] {easyListResults[0], easyListResults[1], easyListResults[2], easyListResults[3], easyListResults[4], easyListResults[5]};
-                    }
-                }
-
-                // Check EasyPrivacy if it is enabled.
-                if (nestedScrollWebView.isBlocklistEnabled(NestedScrollWebView.EASYPRIVACY)) {
-                    // Check the URL against EasyPrivacy.
-                    String[] easyPrivacyResults = blocklistHelper.checkBlocklist(currentDomain, url, isThirdPartyRequest, easyPrivacy);
-
-                    // Process the EasyPrivacy results.
-                    if (easyPrivacyResults[0].equals(BlocklistHelper.REQUEST_BLOCKED)) {  // The resource request matched EasyPrivacy's blacklist.
-                        // Add the result to the resource requests.
-                        nestedScrollWebView.addResourceRequest(new String[] {easyPrivacyResults[0], easyPrivacyResults[1], easyPrivacyResults[2], easyPrivacyResults[3], easyPrivacyResults[4],
-                                easyPrivacyResults[5]});
-
-                        // Increment the blocked requests counters.
-                        nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS);
-                        nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.EASYPRIVACY);
-
-                        // Update the titles of the blocklist menu items if the WebView is currently displayed.
-                        if (webViewDisplayed) {
-                            // Updating the UI must be run from the UI thread.
-                            activity.runOnUiThread(() -> {
-                                // Update the menu item titles.
-                                navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
-
-                                // Update the options menu if it has been populated.
-                                if (optionsMenu != null) {
-                                    optionsMenu.findItem(R.id.blocklists).setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
-                                    optionsMenu.findItem(R.id.easyprivacy).setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.EASYPRIVACY) + " - " + getString(R.string.easyprivacy));
-                                }
-                            });
-                        }
-
-                        // The resource request was blocked.  Return an empty web resource response.
-                        return emptyWebResourceResponse;
-                    } else if (easyPrivacyResults[0].equals(BlocklistHelper.REQUEST_ALLOWED)) {  // The resource request matched EasyPrivacy's whitelist.
-                        // Update the whitelist result string array tracker.
-                        whitelistResultStringArray = new String[] {easyPrivacyResults[0], easyPrivacyResults[1], easyPrivacyResults[2], easyPrivacyResults[3], easyPrivacyResults[4], easyPrivacyResults[5]};
-                    }
-                }
-
-                // Check Fanboy’s Annoyance List if it is enabled.
-                if (nestedScrollWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST)) {
-                    // Check the URL against Fanboy's Annoyance List.
-                    String[] fanboysAnnoyanceListResults = blocklistHelper.checkBlocklist(currentDomain, url, isThirdPartyRequest, fanboysAnnoyanceList);
-
-                    // Process the Fanboy's Annoyance List results.
-                    if (fanboysAnnoyanceListResults[0].equals(BlocklistHelper.REQUEST_BLOCKED)) {  // The resource request matched Fanboy's Annoyance List's blacklist.
-                        // Add the result to the resource requests.
-                        nestedScrollWebView.addResourceRequest(new String[] {fanboysAnnoyanceListResults[0], fanboysAnnoyanceListResults[1], fanboysAnnoyanceListResults[2], fanboysAnnoyanceListResults[3],
-                                fanboysAnnoyanceListResults[4], fanboysAnnoyanceListResults[5]});
-
-                        // Increment the blocked requests counters.
-                        nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS);
-                        nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST);
-
-                        // Update the titles of the blocklist menu items if the WebView is currently displayed.
-                        if (webViewDisplayed) {
-                            // Updating the UI must be run from the UI thread.
-                            activity.runOnUiThread(() -> {
-                                // Update the menu item titles.
-                                navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
-
-                                // Update the options menu if it has been populated.
-                                if (optionsMenu != null) {
-                                    optionsMenu.findItem(R.id.blocklists).setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
-                                    optionsMenu.findItem(R.id.fanboys_annoyance_list).setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST) + " - " +
-                                            getString(R.string.fanboys_annoyance_list));
-                                }
-                            });
-                        }
-
-                        // The resource request was blocked.  Return an empty web resource response.
-                        return emptyWebResourceResponse;
-                    } else if (fanboysAnnoyanceListResults[0].equals(BlocklistHelper.REQUEST_ALLOWED)){  // The resource request matched Fanboy's Annoyance List's whitelist.
-                        // Update the whitelist result string array tracker.
-                        whitelistResultStringArray = new String[] {fanboysAnnoyanceListResults[0], fanboysAnnoyanceListResults[1], fanboysAnnoyanceListResults[2], fanboysAnnoyanceListResults[3],
-                                fanboysAnnoyanceListResults[4], fanboysAnnoyanceListResults[5]};
-                    }
-                } else if (nestedScrollWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST)) {  // Only check Fanboy’s Social Blocking List if Fanboy’s Annoyance List is disabled.
-                    // Check the URL against Fanboy's Annoyance List.
-                    String[] fanboysSocialListResults = blocklistHelper.checkBlocklist(currentDomain, url, isThirdPartyRequest, fanboysSocialList);
-
-                    // Process the Fanboy's Social Blocking List results.
-                    if (fanboysSocialListResults[0].equals(BlocklistHelper.REQUEST_BLOCKED)) {  // The resource request matched Fanboy's Social Blocking List's blacklist.
-                        // Add the result to the resource requests.
-                        nestedScrollWebView.addResourceRequest(new String[] {fanboysSocialListResults[0], fanboysSocialListResults[1], fanboysSocialListResults[2], fanboysSocialListResults[3],
-                                fanboysSocialListResults[4], fanboysSocialListResults[5]});
-
-                        // Increment the blocked requests counters.
-                        nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS);
-                        nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST);
-
-                        // Update the titles of the blocklist menu items if the WebView is currently displayed.
-                        if (webViewDisplayed) {
-                            // Updating the UI must be run from the UI thread.
-                            activity.runOnUiThread(() -> {
-                                // Update the menu item titles.
-                                navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
-
-                                // Update the options menu if it has been populated.
-                                if (optionsMenu != null) {
-                                    optionsMenu.findItem(R.id.blocklists).setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
-                                    optionsMenu.findItem(R.id.fanboys_social_blocking_list).setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST) + " - " +
-                                            getString(R.string.fanboys_social_blocking_list));
-                                }
-                            });
-                        }
-
-                        // The resource request was blocked.  Return an empty web resource response.
-                        return emptyWebResourceResponse;
-                    } else if (fanboysSocialListResults[0].equals(BlocklistHelper.REQUEST_ALLOWED)) {  // The resource request matched Fanboy's Social Blocking List's whitelist.
-                        // Update the whitelist result string array tracker.
-                        whitelistResultStringArray = new String[] {fanboysSocialListResults[0], fanboysSocialListResults[1], fanboysSocialListResults[2], fanboysSocialListResults[3],
-                                fanboysSocialListResults[4], fanboysSocialListResults[5]};
-                    }
-                }
-
-                // Add the request to the log because it hasn't been processed by any of the previous checks.
-                if (whitelistResultStringArray != null) {  // The request was processed by a whitelist.
-                    nestedScrollWebView.addResourceRequest(whitelistResultStringArray);
-                } else {  // The request didn't match any blocklist entry.  Log it as a default request.
-                    nestedScrollWebView.addResourceRequest(new String[]{BlocklistHelper.REQUEST_DEFAULT, url});
-                }
-
-                // The resource request has not been blocked.  `return null` loads the requested resource.
-                return null;
-            }
-
-            // Handle HTTP authentication requests.
-            @Override
-            public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
-                // Store the handler.
-                nestedScrollWebView.setHttpAuthHandler(handler);
-
-                // Instantiate an HTTP authentication dialog.
-                DialogFragment httpAuthenticationDialogFragment = HttpAuthenticationDialog.displayDialog(host, realm, nestedScrollWebView.getWebViewFragmentId());
-
-                // Show the HTTP authentication dialog.
-                httpAuthenticationDialogFragment.show(getSupportFragmentManager(), getString(R.string.http_authentication));
-            }
-
-            @Override
-            public void onPageStarted(WebView view, String url, Bitmap favicon) {
-                // Get the preferences.
-                boolean scrollAppBar = sharedPreferences.getBoolean("scroll_app_bar", true);
-
-                // Set the top padding of the swipe refresh layout according to the app bar scrolling preference.  This can't be done in `appAppSettings()` because the app bar is not yet populated there.
-                if (scrollAppBar || (inFullScreenBrowsingMode && hideAppBar)) {
-                    // No padding is needed because it will automatically be placed below the app bar layout due to the scrolling layout behavior.
-                    swipeRefreshLayout.setPadding(0, 0, 0, 0);
-
-                    // The swipe to refresh circle doesn't always hide itself completely unless it is moved up 10 pixels.
-                    swipeRefreshLayout.setProgressViewOffset(false, defaultProgressViewStartOffset - 10, defaultProgressViewEndOffset);
-                } else {
-                    // Get the app bar layout height.  This can't be done in `applyAppSettings()` because the app bar is not yet populated there.
-                    appBarHeight = appBarLayout.getHeight();
-
-                    // The swipe refresh layout must be manually moved below the app bar layout.
-                    swipeRefreshLayout.setPadding(0, appBarHeight, 0, 0);
-
-                    // The swipe to refresh circle doesn't always hide itself completely unless it is moved up 10 pixels.
-                    swipeRefreshLayout.setProgressViewOffset(false, defaultProgressViewStartOffset - 10 + appBarHeight, defaultProgressViewEndOffset + appBarHeight);
-                }
-
-                // Reset the list of resource requests.
-                nestedScrollWebView.clearResourceRequests();
-
-                // Reset the requests counters.
-                nestedScrollWebView.resetRequestsCounters();
-
-                // Get the current page position.
-                int currentPagePosition = webViewPagerAdapter.getPositionForId(nestedScrollWebView.getWebViewFragmentId());
-
-                // Update the URL text bar if the page is currently selected and the URL edit text is not currently being edited.
-                if ((tabLayout.getSelectedTabPosition() == currentPagePosition) && !urlEditText.hasFocus()) {
-                    // Display the formatted URL text.
-                    urlEditText.setText(url);
-
-                    // Apply text highlighting to `urlTextBox`.
-                    highlightUrlText();
-
-                    // Hide the keyboard.
-                    inputMethodManager.hideSoftInputFromWindow(nestedScrollWebView.getWindowToken(), 0);
-                }
-
-                // Reset the list of host IP addresses.
-                nestedScrollWebView.clearCurrentIpAddresses();
-
-                // Get a URI for the current URL.
-                Uri currentUri = Uri.parse(url);
-
-                // Get the IP addresses for the host.
-                new GetHostIpAddresses(activity, getSupportFragmentManager(), nestedScrollWebView).execute(currentUri.getHost());
-
-                // Replace Refresh with Stop if the options menu has been created.  (The first WebView typically begins loading before the menu items are instantiated.)
-                if (optionsMenu != null) {
-                    // Get a handle for the refresh menu item.
-                    MenuItem refreshMenuItem = optionsMenu.findItem(R.id.refresh);
-
-                    // Set the title.
-                    refreshMenuItem.setTitle(R.string.stop);
-
-                    // Get the app bar and theme preferences.
-                    boolean displayAdditionalAppBarIcons = sharedPreferences.getBoolean(getString(R.string.display_additional_app_bar_icons_key), false);
-
-                    // If the icon is displayed in the AppBar, set it according to the theme.
-                    if (displayAdditionalAppBarIcons) {
-                        // Get the current theme status.
-                        int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
-                        // Set the stop icon according to the theme.
-                        if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
-                            refreshMenuItem.setIcon(R.drawable.close_blue_day);
-                        } else {
-                            refreshMenuItem.setIcon(R.drawable.close_blue_night);
-                        }
-                    }
-                }
-            }
-
-            @Override
-            public void onPageFinished(WebView view, String url) {
-                // Flush any cookies to persistent storage.  The cookie manager has become very lazy about flushing cookies in recent versions.
-                if (nestedScrollWebView.getAcceptFirstPartyCookies() && Build.VERSION.SDK_INT >= 21) {
-                    CookieManager.getInstance().flush();
-                }
-
-                // Update the Refresh menu item if the options menu has been created.
-                if (optionsMenu != null) {
-                    // Get a handle for the refresh menu item.
-                    MenuItem refreshMenuItem = optionsMenu.findItem(R.id.refresh);
-
-                    // Reset the Refresh title.
-                    refreshMenuItem.setTitle(R.string.refresh);
-
-                    // Get the app bar and theme preferences.
-                    boolean displayAdditionalAppBarIcons = sharedPreferences.getBoolean(getString(R.string.display_additional_app_bar_icons_key), false);
-
-                    // If the icon is displayed in the app bar, reset it according to the theme.
-                    if (displayAdditionalAppBarIcons) {
-                        // Get the current theme status.
-                        int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
-                        // Set the icon according to the theme.
-                        if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
-                            refreshMenuItem.setIcon(R.drawable.refresh_enabled_day);
-                        } else {
-                            refreshMenuItem.setIcon(R.drawable.refresh_enabled_night);
-                        }
-                    }
-                }
-
-                // Clear the cache, history, and logcat if Incognito Mode is enabled.
-                if (incognitoModeEnabled) {
-                    // Clear the cache.  `true` includes disk files.
-                    nestedScrollWebView.clearCache(true);
-
-                    // Clear the back/forward history.
-                    nestedScrollWebView.clearHistory();
-
-                    // Manually delete cache folders.
-                    try {
-                        // Get the application's private data directory, which will be something like `/data/user/0/com.stoutner.privacybrowser.standard`,
-                        // which links to `/data/data/com.stoutner.privacybrowser.standard`.
-                        String privateDataDirectoryString = getApplicationInfo().dataDir;
-
-                        // Delete the main cache directory.
-                        Runtime.getRuntime().exec("rm -rf " + privateDataDirectoryString + "/cache");
-
-                        // Delete the secondary `Service Worker` cache directory.
-                        // A `String[]` must be used because the directory contains a space and `Runtime.exec` will not escape the string correctly otherwise.
-                        Runtime.getRuntime().exec(new String[]{"rm", "-rf", privateDataDirectoryString + "/app_webview/Service Worker/"});
-                    } catch (IOException exception) {
-                        // Do nothing if an error is thrown.
-                    }
-
-                    // Clear the logcat.
-                    try {
-                        // Clear the logcat.  `-c` clears the logcat.  `-b all` clears all the buffers (instead of just crash, main, and system).
-                        Runtime.getRuntime().exec("logcat -b all -c");
-                    } catch (IOException exception) {
-                        // Do nothing.
-                    }
-                }
-
-                // Get the current page position.
-                int currentPagePosition = webViewPagerAdapter.getPositionForId(nestedScrollWebView.getWebViewFragmentId());
-
-                // Get the current URL from the nested scroll WebView.  This is more accurate than using the URL passed into the method, which is sometimes not the final one.
-                String currentUrl = nestedScrollWebView.getUrl();
-
-                // Get the current tab.
-                TabLayout.Tab tab = tabLayout.getTabAt(currentPagePosition);
-
-                // Update the URL text bar if the page is currently selected and the user is not currently typing in the URL edit text.
-                // Crash records show that, in some crazy way, it is possible for the current URL to be blank at this point.
-                // Probably some sort of race condition when Privacy Browser is being resumed.
-                if ((tabLayout.getSelectedTabPosition() == currentPagePosition) && !urlEditText.hasFocus() && (currentUrl != null)) {
-                    // Check to see if the URL is `about:blank`.
-                    if (currentUrl.equals("about:blank")) {  // The WebView is blank.
-                        // Display the hint in the URL edit text.
-                        urlEditText.setText("");
-
-                        // Request focus for the URL text box.
-                        urlEditText.requestFocus();
-
-                        // Display the keyboard.
-                        inputMethodManager.showSoftInput(urlEditText, 0);
-
-                        // Apply the domain settings.  This clears any settings from the previous domain.
-                        applyDomainSettings(nestedScrollWebView, "", true, false, false);
-
-                        // Only populate the title text view if the tab has been fully created.
-                        if (tab != null) {
-                            // Get the custom view from the tab.
-                            View tabView = tab.getCustomView();
-
-                            // Remove the incorrect warning below that the current tab view might be null.
-                            assert tabView != null;
-
-                            // Get the title text view from the tab.
-                            TextView tabTitleTextView = tabView.findViewById(R.id.title_textview);
-
-                            // Set the title as the tab text.
-                            tabTitleTextView.setText(R.string.new_tab);
-                        }
-                    } else {  // The WebView has loaded a webpage.
-                        // Update the URL edit text if it is not currently being edited.
-                        if (!urlEditText.hasFocus()) {
-                            // Sanitize the current URL.  This removes unwanted URL elements that were added by redirects, so that they won't be included if the URL is shared.
-                            String sanitizedUrl = sanitizeUrl(currentUrl);
-
-                            // Display the final URL.  Getting the URL from the WebView instead of using the one provided by `onPageFinished()` makes websites like YouTube function correctly.
-                            urlEditText.setText(sanitizedUrl);
-
-                            // Apply text highlighting to the URL.
-                            highlightUrlText();
-                        }
-
-                        // Only populate the title text view if the tab has been fully created.
-                        if (tab != null) {
-                            // Get the custom view from the tab.
-                            View tabView = tab.getCustomView();
-
-                            // Remove the incorrect warning below that the current tab view might be null.
-                            assert tabView != null;
-
-                            // Get the title text view from the tab.
-                            TextView tabTitleTextView = tabView.findViewById(R.id.title_textview);
-
-                            // Set the title as the tab text.  Sometimes `onReceivedTitle()` is not called, especially when navigating history.
-                            tabTitleTextView.setText(nestedScrollWebView.getTitle());
-                        }
-                    }
-                }
-            }
-
-            // Handle SSL Certificate errors.
-            @Override
-            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
-                // Get the current website SSL certificate.
-                SslCertificate currentWebsiteSslCertificate = error.getCertificate();
-
-                // Extract the individual pieces of information from the current website SSL certificate.
-                String currentWebsiteIssuedToCName = currentWebsiteSslCertificate.getIssuedTo().getCName();
-                String currentWebsiteIssuedToOName = currentWebsiteSslCertificate.getIssuedTo().getOName();
-                String currentWebsiteIssuedToUName = currentWebsiteSslCertificate.getIssuedTo().getUName();
-                String currentWebsiteIssuedByCName = currentWebsiteSslCertificate.getIssuedBy().getCName();
-                String currentWebsiteIssuedByOName = currentWebsiteSslCertificate.getIssuedBy().getOName();
-                String currentWebsiteIssuedByUName = currentWebsiteSslCertificate.getIssuedBy().getUName();
-                Date currentWebsiteSslStartDate = currentWebsiteSslCertificate.getValidNotBeforeDate();
-                Date currentWebsiteSslEndDate = currentWebsiteSslCertificate.getValidNotAfterDate();
-
-                // Proceed to the website if the current SSL website certificate matches the pinned domain certificate.
-                if (nestedScrollWebView.hasPinnedSslCertificate()) {
-                    // Get the pinned SSL certificate.
-                    ArrayList<Object> pinnedSslCertificateArrayList = nestedScrollWebView.getPinnedSslCertificate();
-
-                    // Extract the arrays from the array list.
-                    String[] pinnedSslCertificateStringArray = (String[]) pinnedSslCertificateArrayList.get(0);
-                    Date[] pinnedSslCertificateDateArray = (Date[]) pinnedSslCertificateArrayList.get(1);
-
-                    // Check if the current SSL certificate matches the pinned certificate.
-                    if (currentWebsiteIssuedToCName.equals(pinnedSslCertificateStringArray[0]) && currentWebsiteIssuedToOName.equals(pinnedSslCertificateStringArray[1]) &&
-                        currentWebsiteIssuedToUName.equals(pinnedSslCertificateStringArray[2]) && currentWebsiteIssuedByCName.equals(pinnedSslCertificateStringArray[3]) &&
-                        currentWebsiteIssuedByOName.equals(pinnedSslCertificateStringArray[4]) && currentWebsiteIssuedByUName.equals(pinnedSslCertificateStringArray[5]) &&
-                        currentWebsiteSslStartDate.equals(pinnedSslCertificateDateArray[0]) && currentWebsiteSslEndDate.equals(pinnedSslCertificateDateArray[1])) {
-
-                        // An SSL certificate is pinned and matches the current domain certificate.  Proceed to the website without displaying an error.
-                        handler.proceed();
-                    }
-                } else {  // Either there isn't a pinned SSL certificate or it doesn't match the current website certificate.
-                    // Store the SSL error handler.
-                    nestedScrollWebView.setSslErrorHandler(handler);
-
-                    // Instantiate an SSL certificate error alert dialog.
-                    DialogFragment sslCertificateErrorDialogFragment = SslCertificateErrorDialog.displayDialog(error, nestedScrollWebView.getWebViewFragmentId());
-
-                    // Show the SSL certificate error dialog.
-                    sslCertificateErrorDialogFragment.show(getSupportFragmentManager(), getString(R.string.ssl_certificate_error));
-                }
-            }
-        });
-
-        // Check to see if the state is being restored.
-        if (restoringState) {  // The state is being restored.
-            // Resume the nested scroll WebView JavaScript timers.
-            nestedScrollWebView.resumeTimers();
-        } else if (pageNumber == 0) {  // The first page is being loaded.
-            // Set this nested scroll WebView as the current WebView.
-            currentWebView = nestedScrollWebView;
-
-            // Initialize the URL to load string.
-            String urlToLoadString;
-
-            // Get the intent that started the app.
-            Intent launchingIntent = getIntent();
-
-            // Reset the intent.  This prevents a duplicate tab from being created on restart.
-            setIntent(new Intent());
-
-            // Get the information from the intent.
-            String launchingIntentAction = launchingIntent.getAction();
-            Uri launchingIntentUriData = launchingIntent.getData();
-            String launchingIntentStringExtra = launchingIntent.getStringExtra(Intent.EXTRA_TEXT);
-
-            // Parse the launching intent URL.
-            if ((launchingIntentAction != null) && launchingIntentAction.equals(Intent.ACTION_WEB_SEARCH)) {  // The intent contains a search string.
-                // Create an encoded URL string.
-                String encodedUrlString;
-
-                // Sanitize the search input and convert it to a search.
-                try {
-                    encodedUrlString = URLEncoder.encode(launchingIntent.getStringExtra(SearchManager.QUERY), "UTF-8");
-                } catch (UnsupportedEncodingException exception) {
-                    encodedUrlString = "";
-                }
-
-                // Store the web search as the URL to load.
-                urlToLoadString = searchURL + encodedUrlString;
-            } else if (launchingIntentUriData != null) {  // The launching intent contains a URL formatted as a URI.
-                // Store the URI as a URL.
-                urlToLoadString = launchingIntentUriData.toString();
-            } else if (launchingIntentStringExtra != null) {  // The launching intent contains text that might be a URL.
-                // Store the URL.
-                urlToLoadString = launchingIntentStringExtra;
-            } else if (!url.equals("")) {  // The activity has been restarted.
-                // Load the saved URL.
-                urlToLoadString = url;
-            } else {  // The is no URL in the intent.
-                // Store the homepage to be loaded.
-                urlToLoadString = sharedPreferences.getString("homepage", getString(R.string.homepage_default_value));
-            }
-
-            // Load the website if not waiting for the proxy.
-            if (waitingForProxy) {  // Store the URL to be loaded in the Nested Scroll WebView.
-                nestedScrollWebView.setWaitingForProxyUrlString(urlToLoadString);
-            } else {  // Load the URL.
-                loadUrl(nestedScrollWebView, urlToLoadString);
-            }
-
-            // Reset the intent.  This prevents a duplicate tab from being created on a subsequent restart if loading an link from a new intent on restart.
-            // For example, this prevents a duplicate tab if a link is loaded from the Guide after changing the theme in the guide and then changing the theme again in the main activity.
-            setIntent(new Intent());
-        } else {  // This is not the first tab.
-            // Load the URL.
-            loadUrl(nestedScrollWebView, url);
-
-            // Set the focus and display the keyboard if the URL is blank.
-            if (url.equals("")) {
-                // Request focus for the URL text box.
-                urlEditText.requestFocus();
-
-                // Create a display keyboard handler.
-                Handler displayKeyboardHandler = new Handler();
-
-                // Create a display keyboard runnable.
-                Runnable displayKeyboardRunnable = () -> {
-                    // Display the keyboard.
-                    inputMethodManager.showSoftInput(urlEditText, 0);
-                };
-
-                // Display the keyboard after 100 milliseconds, which leaves enough time for the tab to transition.
-                displayKeyboardHandler.postDelayed(displayKeyboardRunnable, 100);
-            }
-        }
-    }
-}
\ No newline at end of file