diff --git a/Android.mk b/Android.mk
deleted file mode 100644
index c96d479..0000000
--- a/Android.mk
+++ /dev/null
@@ -1,6 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-# leaving the makefile emtpy to prevent the build
-# system from traversing the project
-
-# Built as part of the Settings package
diff --git a/res/values-ar/custom_strings.xml b/res/values-ar/custom_strings.xml
index dc32479..1edfefa 100644
--- a/res/values-ar/custom_strings.xml
+++ b/res/values-ar/custom_strings.xml
@@ -130,7 +130,6 @@
   <string name="battery_light_full_color_title">شحن (90%)</string>
   <string name="battery_light_really_full_color_title">شحن (100%)</string>
   <string name="edit_battery_settings">تغيير اعدادات البطارية</string>
-  <string name="notification_light_general_title">عام</string>
   <string name="led_color_green">أخضر</string>
   <string name="led_color_red">أحمر</string>
   <string name="led_color_blue">أزرق</string>
diff --git a/res/values-az-rAZ/custom_strings.xml b/res/values-az-rAZ/custom_strings.xml
index 4b7238f..a2deb23 100644
--- a/res/values-az-rAZ/custom_strings.xml
+++ b/res/values-az-rAZ/custom_strings.xml
@@ -109,7 +109,6 @@
   <string name="battery_light_full_color_title">Şarj edildi (90%)</string>
   <string name="battery_light_really_full_color_title">Şarj edildi (100%)</string>
   <string name="edit_battery_settings">Batareya parametrlərini redaktə et</string>
-  <string name="notification_light_general_title">Ümumi</string>
   <string name="led_color_green">Yaşıl</string>
   <string name="led_color_red">Qırmızı</string>
   <string name="led_color_blue">Mavi</string>
diff --git a/res/values-ca/custom_strings.xml b/res/values-ca/custom_strings.xml
index d181a44..066b464 100644
--- a/res/values-ca/custom_strings.xml
+++ b/res/values-ca/custom_strings.xml
@@ -135,7 +135,6 @@
   <string name="battery_light_full_color_title">Carregat (90%)</string>
   <string name="battery_light_really_full_color_title">Carregat (100%)</string>
   <string name="edit_battery_settings">Edita la configuració de la bateria</string>
-  <string name="notification_light_general_title">General</string>
   <string name="led_color_green">Verd</string>
   <string name="led_color_red">Vermell</string>
   <string name="led_color_blue">Blau</string>
diff --git a/res/values-cs/custom_strings.xml b/res/values-cs/custom_strings.xml
index bba3dfb..76af091 100644
--- a/res/values-cs/custom_strings.xml
+++ b/res/values-cs/custom_strings.xml
@@ -147,7 +147,6 @@
   <string name="battery_light_full_color_title">Nabito (90%)</string>
   <string name="battery_light_really_full_color_title">Nabito (100%)</string>
   <string name="edit_battery_settings">Upravit nastavení baterie</string>
-  <string name="notification_light_general_title">Obecné</string>
   <string name="led_color_green">Zelená</string>
   <string name="led_color_red">Červená</string>
   <string name="led_color_blue">Modrá</string>
diff --git a/res/values-de/custom_strings.xml b/res/values-de/custom_strings.xml
index a60cfdc..4fa2586 100644
--- a/res/values-de/custom_strings.xml
+++ b/res/values-de/custom_strings.xml
@@ -147,7 +147,6 @@
   <string name="battery_light_full_color_title">Geladen (90%)</string>
   <string name="battery_light_really_full_color_title">Voll geladen (100%)</string>
   <string name="edit_battery_settings">Akku-Einstellungen bearbeiten</string>
-  <string name="notification_light_general_title">Allgemein</string>
   <string name="led_color_green">Grün</string>
   <string name="led_color_red">Rot</string>
   <string name="led_color_blue">Blau</string>
diff --git a/res/values-el/custom_strings.xml b/res/values-el/custom_strings.xml
index 2d5aa38..c89f5f5 100644
--- a/res/values-el/custom_strings.xml
+++ b/res/values-el/custom_strings.xml
@@ -83,7 +83,6 @@
   <string name="battery_light_full_color_title">Φορτισμένο (90%)</string>
   <string name="battery_light_really_full_color_title">Φορτισμένο (100%)</string>
   <string name="edit_battery_settings">Επεξεργασία ρυθμίσεων μπαταρίας</string>
-  <string name="notification_light_general_title">Γενικά</string>
   <string name="led_color_green">Πράσινο</string>
   <string name="led_color_red">Κόκκινο</string>
   <string name="led_color_blue">Μπλε</string>
diff --git a/res/values-es/custom_strings.xml b/res/values-es/custom_strings.xml
index c5cacb8..87c24e0 100644
--- a/res/values-es/custom_strings.xml
+++ b/res/values-es/custom_strings.xml
@@ -146,7 +146,6 @@
   <string name="battery_light_full_color_title">Cargado (90%)</string>
   <string name="battery_light_really_full_color_title">Cargado (100%)</string>
   <string name="edit_battery_settings">Editar la configuración de la batería</string>
-  <string name="notification_light_general_title">General</string>
   <string name="led_color_green">Verde</string>
   <string name="led_color_red">Rojo</string>
   <string name="led_color_blue">Azul</string>
diff --git a/res/values-fr/custom_strings.xml b/res/values-fr/custom_strings.xml
index 3e5ef9a..ed11796 100644
--- a/res/values-fr/custom_strings.xml
+++ b/res/values-fr/custom_strings.xml
@@ -146,7 +146,6 @@
   <string name="battery_light_full_color_title">Chargée (90%)</string>
   <string name="battery_light_really_full_color_title">Chargée (100%)</string>
   <string name="edit_battery_settings">Éditer les paramètres de la batterie</string>
-  <string name="notification_light_general_title">Général</string>
   <string name="led_color_green">Vert</string>
   <string name="led_color_red">Rouge</string>
   <string name="led_color_blue">Bleu</string>
diff --git a/res/values-hu/custom_strings.xml b/res/values-hu/custom_strings.xml
index bf16a41..4a7b321 100644
--- a/res/values-hu/custom_strings.xml
+++ b/res/values-hu/custom_strings.xml
@@ -147,7 +147,6 @@
   <string name="battery_light_full_color_title">Feltöltve (90%)</string>
   <string name="battery_light_really_full_color_title">Feltöltve (100%)</string>
   <string name="edit_battery_settings">Akkumulátor-beállítások szerkesztése</string>
-  <string name="notification_light_general_title">Általános</string>
   <string name="led_color_green">Zöld</string>
   <string name="led_color_red">Vörös</string>
   <string name="led_color_blue">Kék</string>
diff --git a/res/values-it/custom_strings.xml b/res/values-it/custom_strings.xml
index 5cca0a1..efafdcb 100644
--- a/res/values-it/custom_strings.xml
+++ b/res/values-it/custom_strings.xml
@@ -147,7 +147,6 @@
   <string name="battery_light_full_color_title">Carica (90%)</string>
   <string name="battery_light_really_full_color_title">Carica (100%)</string>
   <string name="edit_battery_settings">Modifica impostazioni batteria</string>
-  <string name="notification_light_general_title">Generale</string>
   <string name="led_color_green">Verde</string>
   <string name="led_color_red">Rosso</string>
   <string name="led_color_blue">Blu</string>
diff --git a/res/values-ko/custom_strings.xml b/res/values-ko/custom_strings.xml
index 16671f9..861f290 100644
--- a/res/values-ko/custom_strings.xml
+++ b/res/values-ko/custom_strings.xml
@@ -142,7 +142,6 @@
   <string name="battery_light_full_color_title">충전됨 (90%)</string>
   <string name="battery_light_really_full_color_title">충전됨 (100%)</string>
   <string name="edit_battery_settings">배터리 설정 편집</string>
-  <string name="notification_light_general_title">일반</string>
   <string name="led_color_green">녹색</string>
   <string name="led_color_red">적색</string>
   <string name="led_color_blue">청색</string>
diff --git a/res/values-nl/custom_strings.xml b/res/values-nl/custom_strings.xml
index ab4ff59..c763ba9 100644
--- a/res/values-nl/custom_strings.xml
+++ b/res/values-nl/custom_strings.xml
@@ -147,7 +147,6 @@
   <string name="battery_light_full_color_title">Opgeladen (90%)</string>
   <string name="battery_light_really_full_color_title">Volledig opgeladen (100%)</string>
   <string name="edit_battery_settings">Batterij-instellingen aanpassen</string>
-  <string name="notification_light_general_title">Algemeen</string>
   <string name="led_color_green">Groen</string>
   <string name="led_color_red">Rood</string>
   <string name="led_color_blue">Blauw</string>
diff --git a/res/values-pl/custom_strings.xml b/res/values-pl/custom_strings.xml
index 9305dc5..db3026e 100644
--- a/res/values-pl/custom_strings.xml
+++ b/res/values-pl/custom_strings.xml
@@ -146,7 +146,6 @@
   <string name="battery_light_full_color_title">Naładowane (90%)</string>
   <string name="battery_light_really_full_color_title">Naładowane (100%)</string>
   <string name="edit_battery_settings">Edytuj ustawienia baterii</string>
-  <string name="notification_light_general_title">Ogólne</string>
   <string name="led_color_green">ZIelony</string>
   <string name="led_color_red">Czerwony</string>
   <string name="led_color_blue">Niebieski</string>
diff --git a/res/values-pt-rBR/custom_strings.xml b/res/values-pt-rBR/custom_strings.xml
index 08951be..418e854 100644
--- a/res/values-pt-rBR/custom_strings.xml
+++ b/res/values-pt-rBR/custom_strings.xml
@@ -147,7 +147,6 @@
   <string name="battery_light_full_color_title">Carregando (90%)</string>
   <string name="battery_light_really_full_color_title">Carregada (100%)</string>
   <string name="edit_battery_settings">Editar configurações de bateria</string>
-  <string name="notification_light_general_title">Geral</string>
   <string name="led_color_green">Verde</string>
   <string name="led_color_red">Vermelho</string>
   <string name="led_color_blue">Azul</string>
diff --git a/res/values-pt-rPT/custom_strings.xml b/res/values-pt-rPT/custom_strings.xml
index a102598..d1f5795 100644
--- a/res/values-pt-rPT/custom_strings.xml
+++ b/res/values-pt-rPT/custom_strings.xml
@@ -147,7 +147,6 @@
   <string name="battery_light_full_color_title">Carregado (90%)</string>
   <string name="battery_light_really_full_color_title">Carregado (100%)</string>
   <string name="edit_battery_settings">Editar as definições de bateria</string>
-  <string name="notification_light_general_title">Geral</string>
   <string name="led_color_green">Verde</string>
   <string name="led_color_red">Vermelho</string>
   <string name="led_color_blue">Azul</string>
diff --git a/res/values-ru/custom_strings.xml b/res/values-ru/custom_strings.xml
index a1b3964..cabd7a0 100644
--- a/res/values-ru/custom_strings.xml
+++ b/res/values-ru/custom_strings.xml
@@ -146,7 +146,6 @@
   <string name="battery_light_full_color_title">Заряжена на 90%</string>
   <string name="battery_light_really_full_color_title">Полностью заряжена</string>
   <string name="edit_battery_settings">Изменить настройки батареи</string>
-  <string name="notification_light_general_title">Основные</string>
   <string name="led_color_green">Зелёный</string>
   <string name="led_color_red">Красный</string>
   <string name="led_color_blue">Синий</string>
diff --git a/res/values-sk/custom_strings.xml b/res/values-sk/custom_strings.xml
index f20ae99..88ec557 100644
--- a/res/values-sk/custom_strings.xml
+++ b/res/values-sk/custom_strings.xml
@@ -147,7 +147,6 @@
   <string name="battery_light_full_color_title">Nabitá (90%)</string>
   <string name="battery_light_really_full_color_title">Nabitá (100%)</string>
   <string name="edit_battery_settings">Upraviť nastavenia batérie</string>
-  <string name="notification_light_general_title">Všeobecné</string>
   <string name="led_color_green">Zelená</string>
   <string name="led_color_red">Červená</string>
   <string name="led_color_blue">Modrá</string>
diff --git a/res/values-sl/custom_strings.xml b/res/values-sl/custom_strings.xml
index 94dbf5f..a4945a3 100644
--- a/res/values-sl/custom_strings.xml
+++ b/res/values-sl/custom_strings.xml
@@ -146,7 +146,6 @@
   <string name="battery_light_full_color_title">Napolnjena</string>
   <string name="battery_light_really_full_color_title">Napolnjena (100 %)</string>
   <string name="edit_battery_settings">Uredi nastavitve baterije</string>
-  <string name="notification_light_general_title">Splošno</string>
   <string name="led_color_green">Zelena</string>
   <string name="led_color_red">Rdeča</string>
   <string name="led_color_blue">Modra</string>
diff --git a/res/values-sv/custom_strings.xml b/res/values-sv/custom_strings.xml
index fe33cd9..e4a8eeb 100644
--- a/res/values-sv/custom_strings.xml
+++ b/res/values-sv/custom_strings.xml
@@ -116,7 +116,6 @@
   <string name="battery_light_full_color_title">Laddad (90%)</string>
   <string name="battery_light_really_full_color_title">Fulladdad (100%)</string>
   <string name="edit_battery_settings">Ändra batteriinställningar</string>
-  <string name="notification_light_general_title">Allmänt</string>
   <string name="led_color_green">Grön</string>
   <string name="led_color_red">Röd</string>
   <string name="led_color_blue">Blå</string>
diff --git a/res/values-tr/custom_strings.xml b/res/values-tr/custom_strings.xml
index b5bc543..7e44471 100644
--- a/res/values-tr/custom_strings.xml
+++ b/res/values-tr/custom_strings.xml
@@ -147,7 +147,6 @@
   <string name="battery_light_full_color_title">(%90) şarj edildi</string>
   <string name="battery_light_really_full_color_title">(%100) şarj edildi</string>
   <string name="edit_battery_settings">Pil ayarlarını düzenle</string>
-  <string name="notification_light_general_title">Genel</string>
   <string name="led_color_green">Yeşil</string>
   <string name="led_color_red">Kırmızı</string>
   <string name="led_color_blue">Mavi</string>
diff --git a/res/values-uk/custom_strings.xml b/res/values-uk/custom_strings.xml
index b79b5f4..3109139 100644
--- a/res/values-uk/custom_strings.xml
+++ b/res/values-uk/custom_strings.xml
@@ -129,7 +129,6 @@
   <string name="battery_light_full_color_title">Заряджено (90%)</string>
   <string name="battery_light_really_full_color_title">Заряджено (100%)</string>
   <string name="edit_battery_settings">Редагувати параметри батареї</string>
-  <string name="notification_light_general_title">Загальні</string>
   <string name="led_color_green">Зелений</string>
   <string name="led_color_red">Червоний</string>
   <string name="led_color_blue">Синій</string>
diff --git a/res/values-zh-rCN/custom_strings.xml b/res/values-zh-rCN/custom_strings.xml
index b95d2e5..0f69930 100644
--- a/res/values-zh-rCN/custom_strings.xml
+++ b/res/values-zh-rCN/custom_strings.xml
@@ -147,7 +147,6 @@
   <string name="battery_light_full_color_title">已充电 (90%)</string>
   <string name="battery_light_really_full_color_title">充电完成 (100%)</string>
   <string name="edit_battery_settings">编辑电池设置</string>
-  <string name="notification_light_general_title">常规</string>
   <string name="led_color_green">绿色</string>
   <string name="led_color_red">红色</string>
   <string name="led_color_blue">蓝色</string>
diff --git a/res/values-zh-rTW/custom_strings.xml b/res/values-zh-rTW/custom_strings.xml
index d4f7119..c81df7a 100644
--- a/res/values-zh-rTW/custom_strings.xml
+++ b/res/values-zh-rTW/custom_strings.xml
@@ -85,7 +85,6 @@
   <string name="battery_light_full_color_title">已充電 (90%)</string>
   <string name="battery_light_really_full_color_title">已充電 (100%)</string>
   <string name="edit_battery_settings">編輯電池設定</string>
-  <string name="notification_light_general_title">一般</string>
   <string name="led_color_green">綠色</string>
   <string name="led_color_red">紅色</string>
   <string name="led_color_blue">藍色</string>
diff --git a/res/values/custom_strings.xml b/res/values/custom_strings.xml
index e3e7a05..f8ac1a1 100644
--- a/res/values/custom_strings.xml
+++ b/res/values/custom_strings.xml
@@ -172,7 +172,6 @@
     <string name="fast_charging_light_color_title">Color</string>
     <string name="fast_charging_light_color_summary"></string>
     <string name="edit_battery_settings">Edit battery settings</string>
-    <string name="notification_light_general_title">General</string>
     <string name="led_color_green">Green</string>
     <string name="led_color_red">Red</string>
     <string name="led_color_blue">Blue</string>
@@ -415,7 +414,6 @@
     <string name="notification_light_applist_title">Apps</string>
     <string name="notification_light_use_custom">Use custom values</string>
     <string name="notification_light_default_value">Default</string>
-    <string name="notification_light_brightness" translatable="false">@string/brightness</string>
     <string name="notification_light_screen_on">Lights with screen on</string>
     <string name="notification_light_zen_mode">Lights in Do Not Disturb mode</string>
     <string name="notification_light_use_multiple_leds">Multiple LEDs</string>
diff --git a/res/xml/ambient_settings.xml b/res/xml/ambient_settings.xml
deleted file mode 100644
index 5b3759c..0000000
--- a/res/xml/ambient_settings.xml
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?> 
-<!--  Copyright (C) 2015 The OmniROM Project
-
-  This program 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 2 of the License, or
-  (at your option) any later version.
-
-  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-                  xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
-        android:title="@string/doze_title"
-        settings:keywords="@string/doze_title">
-<!--
-            <SwitchPreference
-                    android:key="doze"
-                    android:title="@string/doze_title"
-                    android:summary="@string/doze_summary"
-                    android:persistent="false" />
-
-            <ListPreference
-                    android:entries="@array/doze_list_mode_entries"
-                    android:entryValues="@array/doze_list_mode_values"
-                    android:key="doze_list_mode"
-                    android:title="@string/doze_list_mode_title"
-                    android:summary="@string/doze_list_mode_summary"
-                    android:persistent="false"
-                    android:dependency="doze" />
-
-            <com.android.settings.preference.SystemCheckBoxPreference
-                    android:key="doze_time_mode"
-                    android:title="@string/doze_time_mode_title"
-                    android:summary="@string/doze_time_mode_summary"
-                    android:dependency="doze" />
-
-            <com.android.settings.preference.SystemCheckBoxPreference
-                    android:key="doze_overwrite_value"
-                    android:title="@string/doze_overwrite_value_title"
-                    android:summary="@string/doze_overwrite_value_summary"
-                    android:dependency="doze" />
-
-            <com.android.settings.preference.SystemCheckBoxPreference
-                    android:key="doze_pulse_on_notifications"
-                    android:title="@string/doze_pulse_on_notifications_title"
-                    android:summary="@string/doze_pulse_on_notifications_summary"
-                    android:defaultValue="true"
-                    android:dependency="doze_overwrite_value" />
-
-            <com.android.settings.preference.SeekBarPreference
-                    android:key="doze_brightness_level"
-                    android:title="@string/doze_brightness_level_title"
-                    android:max="255"
-                    settings:min="0"
-                    android:persistent="false"
-                    android:dependency="doze_overwrite_value" />
-
-            <PreferenceCategory
-                    android:key="doze_pulse_category"
-                    android:title="@string/doze_pulse_title" >
-                    <ListPreference
-                          android:entries="@array/doze_pulse_duration_in_entries"
-                          android:entryValues="@array/doze_pulse_duration_in_values"
-                          android:key="doze_pulse_in"
-                          android:title="@string/doze_pulse_duration_in_title"
-                          android:summary="@string/doze_pulse_duration_in_summary"
-                          android:persistent="false"
-                          android:dependency="doze_overwrite_value" />
-
-                    <ListPreference
-                          android:entries="@array/doze_pulse_duration_visible_entries"
-                          android:entryValues="@array/doze_pulse_duration_visible_values"
-                          android:key="doze_pulse_visible"
-                          android:title="@string/doze_pulse_duration_visible_title"
-                          android:summary="@string/doze_pulse_duration_visible_summary"
-                          android:persistent="false"
-                          android:dependency="doze_overwrite_value" />
-
-                    <ListPreference
-                          android:entries="@array/doze_pulse_duration_in_entries"
-                          android:entryValues="@array/doze_pulse_duration_in_values"
-                          android:key="doze_pulse_out"
-                          android:title="@string/doze_pulse_duration_out_title"
-                          android:summary="@string/doze_pulse_duration_out_summary"
-                          android:persistent="false"
-                          android:dependency="doze_overwrite_value" />
-
-            </PreferenceCategory>
-
-            <PreferenceCategory
-                    android:key="doze_shake_category"
-                    android:title="@string/doze_shake_title" >
-
-                <ListPreference
-                        android:entries="@array/doze_shake_acc_threshold_entries"
-                        android:entryValues="@array/doze_shake_acc_threshold_values"
-                        android:key="doze_shake_threshold"
-                        android:title="@string/doze_shake_acc_threshold_title"
-                        android:summary="@string/doze_shake_acc_threshold_summary"
-                        android:persistent="false"
-                        android:dependency="doze" />
-            </PreferenceCategory>
--->
-</PreferenceScreen>
diff --git a/res/xml/bars_settings.xml b/res/xml/bars_settings.xml
deleted file mode 100644
index 4be60b3..0000000
--- a/res/xml/bars_settings.xml
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--  Copyright (C) 2015 The OmniROM Project
-
-  This program 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 2 of the License, or
-  (at your option) any later version.
-
-  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
--->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
-
-        <PreferenceCategory
-            android:key="category_statusbar"
-            android:title="@string/statusbar_title">
-
-            <org.omnirom.omnigears.preference.SystemCheckBoxPreference
-                android:key="status_bar_brightness_control"
-                android:title="@string/status_bar_brightness_control_title"
-                android:summary="@string/status_bar_brightness_control_summary"
-                android:defaultValue="false"/>
-
-            <org.omnirom.omnigears.preference.SystemCheckBoxPreference
-                android:key="double_tap_sleep_gesture"
-                android:title="@string/double_tap_to_sleep_title"
-                android:summary="@string/double_tap_to_sleep_summary"
-                android:defaultValue="false" />
-
-            <org.omnirom.omnigears.preference.SystemCheckBoxPreference
-                android:key="status_bar_ime_notification"
-                android:title="@string/status_bar_ime_notification_title"
-                android:summary="@string/status_bar_ime_notification_summary"
-                android:defaultValue="true"/>
-
-<!--
-            <PreferenceScreen
-                    android:title="@string/status_bar_icon_blacklist_title"
-                    android:summary="@string/status_bar_icon_blacklist_summary" >
-                <intent android:action="android.intent.action.MAIN"
-                        android:targetPackage="com.android.systemui"
-                        android:targetClass="com.android.systemui.tuner.StatusBarActivity" />
-            </PreferenceScreen>
--->
-            <!-- Network traffic meter -->
-            <PreferenceScreen
-                android:key="category_network_traffic"
-                android:title="@string/network_traffic_title"
-                android:fragment="org.omnirom.omnigears.interfacesettings.NetworkTraffic" />
-<!--
-            <ListPreference
-                android:key="status_bar_quick_qs_pulldown"
-                android:title="@string/status_bar_quick_qs_pulldown_title"
-                android:entries="@array/status_bar_quick_qs_pulldown_entries"
-                android:entryValues="@array/status_bar_quick_qs_pulldown_values"
-                android:persistent="false" />
--->
-        </PreferenceCategory>
-
-        <PreferenceCategory
-            android:key="category_navigationbar"
-            android:title="@string/navigationbar_title">
-
-            <org.omnirom.omnigears.preference.SystemCheckBoxPreference
-                android:key="navigation_bar_ime_button"
-                android:title="@string/navigation_bar_ime_button_title"
-                android:summary="@string/navigation_bar_ime_button_summary"
-                android:defaultValue="true"/>
-
-            <!--<com.android.settings.preference.SystemCheckBoxPreference
-                android:key="enable_tablet_navigation"
-                android:title="@string/enable_tablet_navigation_title"
-                android:summary="@string/enable_tablet_navigation_summary"
-                android:defaultValue="false" />-->
-        </PreferenceCategory>
-
-</PreferenceScreen>
diff --git a/res/xml/battery_light_settings.xml b/res/xml/battery_light_settings.xml
deleted file mode 100644
index ad8d26c..0000000
--- a/res/xml/battery_light_settings.xml
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The CyanogenMod Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
-
-    <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
-        android:key="battery_light_enabled"
-        android:title="@string/battery_light_enable"
-        android:persistent="false"/>
-
-    <PreferenceCategory
-        android:key="general_section"
-        android:title="@string/notification_light_general_title">
-
-        <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
-            android:key="battery_light_pulse"
-            android:title="@string/battery_low_pulse_title"
-            android:dependency="battery_light_enabled"
-            android:persistent="false" />
-
-        <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
-            android:key="battery_light_only_fully_charged"
-            android:title="@string/battery_light_only_full_charge_title"
-            android:dependency="battery_light_enabled" />
-
-    </PreferenceCategory>
-
-    <PreferenceCategory
-        android:key="colors_list"
-        android:title="@string/battery_light_list_title"
-        android:dependency="battery_light_enabled" >
-
-        <org.omnirom.omnigears.batterylight.BatteryLightPreference
-            android:key="low_color"
-            android:title="@string/battery_light_low_color_title"
-            android:persistent="false" />
-
-        <org.omnirom.omnigears.batterylight.BatteryLightPreference
-            android:key="medium_color"
-            android:title="@string/battery_light_medium_color_title"
-            android:persistent="false" />
-
-        <org.omnirom.omnigears.batterylight.BatteryLightPreference
-            android:key="full_color"
-            android:title="@string/battery_light_full_color_title"
-            android:persistent="false" />
-
-        <org.omnirom.omnigears.batterylight.BatteryLightPreference
-            android:key="really_full_color"
-            android:title="@string/battery_light_really_full_color_title"
-            android:persistent="false" />
-
-    </PreferenceCategory>
-
-    <PreferenceCategory
-        android:key="fast_color_cat"
-        android:title="@string/fast_color_cat_title"
-        android:dependency="battery_light_enabled" >
-
-        <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
-            android:key="fast_charging_led_enabled"
-            android:title="@string/fast_charging_led_enabled_title"
-            android:summary="@string/fast_charging_led_enabled_summary" />
-
-        <org.omnirom.omnigears.batterylight.BatteryLightPreference
-            android:key="fast_color"
-            android:title="@string/fast_charging_light_color_title"
-            android:summary="@string/fast_charging_light_color_summary"
-            android:persistent="false"
-            android:dependency="fast_charging_led_enabled" />
-
-    </PreferenceCategory>
-
-</PreferenceScreen>
diff --git a/res/xml/button_brightness_settings.xml b/res/xml/button_brightness_settings.xml
deleted file mode 100644
index 4ece1cc..0000000
--- a/res/xml/button_brightness_settings.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--  Copyright (C) 2014 The OmniROM Project
-
-  This program 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 2 of the License, or
-  (at your option) any later version.
-
-  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
--->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
-
-        <SwitchPreference
-                android:key="button_backlight_enable"
-                android:title="@string/button_backlight_enable_title"
-                android:persistent="false"/>
-        <CheckBoxPreference
-                android:key="button_link_brightness"
-                android:title="@string/button_link_brightness"
-                android:summary="@string/button_link_brightness_summary"
-                android:persistent="false"
-                android:dependency="button_backlight_enable"
-                android:disableDependentsState="true" />
-        <org.omnirom.omnigears.preference.SeekBarPreference
-                android:key="button_manual_brightness_new"
-                android:title="@string/button_manual_brightness"
-                android:max="255"
-                settings:min="1"
-                android:persistent="false"
-                android:dependency="button_link_brightness" />
-        <org.omnirom.omnigears.preference.SeekBarPreference
-                android:key="button_timeout"
-                android:title="@string/button_timeout_title"
-                android:summary="@string/button_timeout_summary"
-                android:max="30"
-                settings:min="0"
-                settings:unitsLeft=""
-                settings:unitsRight="@string/unit_sec"
-                android:persistent="false"
-                android:dependency="button_backlight_enable" />
-        <org.omnirom.omnigears.preference.SystemCheckBoxPreference
-                android:key="button_backlight_on_touch_only"
-                android:title="@string/button_backlight_on_touch_only_title"
-                android:summary="@string/button_backlight_on_touch_only_summary"
-                android:defaultValue="false"
-                android:dependency="button_backlight_enable" />
-</PreferenceScreen>
diff --git a/res/xml/button_settings.xml b/res/xml/button_settings.xml
deleted file mode 100644
index 027fe9d..0000000
--- a/res/xml/button_settings.xml
+++ /dev/null
@@ -1,315 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--  Copyright (C) 2013 The OmniROM Project
-
-  This program 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 2 of the License, or
-  (at your option) any later version.
-
-  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- -->
-<!-- Copyright (C) 2012 The CyanogenMod Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
-
-    <PreferenceCategory
-        android:key="button_volume_keys"
-        android:title="@string/button_volume_keys_title" >
-
-        <CheckBoxPreference
-            android:key="button_volume_wake_screen"
-            android:title="@string/button_volume_wake_title"
-            android:summary="@string/button_volume_wake_summary"
-            android:persistent="false"
-            android:disableDependentsState="true" />
-
-        <!--<ListPreference
-            android:key="button_volume_default_screen"
-            android:title="@string/button_volume_default_title"
-            android:summary="@string/button_volume_default_summary"
-            android:entries="@array/button_volume_default_entries"
-            android:entryValues="@array/button_volume_default_values"
-            android:persistent="false"/>-->
-
-        <org.omnirom.omnigears.preference.SystemCheckBoxPreference
-            android:key="volume_button_music_control"
-            android:title="@string/volume_button_music_control_title"
-            android:summary="@string/volume_button_music_control_summary"
-            android:dependency="button_volume_wake_screen"/>
-
-        <!-- <ListPreference
-            android:key="volume_key_cursor_control"
-            android:persistent="false"
-            android:dialogTitle="@string/volume_key_cursor_control_title"
-            android:title="@string/volume_key_cursor_control_title"
-            android:entries="@array/volume_key_cursor_control_entries"
-            android:entryValues="@array/volume_key_cursor_control_values" /> -->
-
-        <org.omnirom.omnigears.preference.SystemCheckBoxPreference
-            android:key="swap_volume_buttons"
-            android:title="@string/swap_volume_buttons_title"
-            android:summary="@string/swap_volume_buttons_summary" />
-
-        <org.omnirom.omnigears.preference.SystemCheckBoxPreference
-            android:key="volume_button_force_media"
-            android:title="@string/volume_button_force_media_title"
-            android:summary="@string/volume_button_force_media_summary" />
-
-    </PreferenceCategory>
-
-    <PreferenceCategory
-        android:key="button_keys"
-        android:title="@string/button_keys_title" >
-
-        <SwitchPreference
-            android:key="navigation_bar_show"
-            android:title="@string/navigation_bar_show_title"
-            android:summary="@string/navigation_bar_show_summary"
-            android:persistent="false" />
-        <SwitchPreference
-            android:key="hardware_keys_disable"
-            android:title="@string/hardware_keys_disable_title"
-            android:summary="@string/hardware_keys_disable_summary"
-            android:persistent="false"
-            android:dependency="navigation_bar_show"/>
-<!--
-        <CheckBoxPreference
-            android:key="virtual_key_haptic_feedback"
-            android:title="@string/virtual_key_haptic_feedback_title"
-            android:summary="@string/virtual_key_haptic_feedback_summary"
-            android:persistent="false"/>
-
-        <CheckBoxPreference
-            android:key="force_show_overflow_menu"
-            android:title="@string/force_show_overflow_menu_title"
-            android:summary="@string/force_show_overflow_menu_summary"
-            android:persistent="false"/>-->
-
-        <PreferenceScreen
-            android:key="button_brightness"
-            android:title="@string/button_backlight_title"
-            android:fragment="org.omnirom.omnigears.ButtonBrightnessSettings" />
-
-        <!--<SwitchPreference
-            android:key="keys_enable_custom"
-            android:title="@string/keys_enable_custom_title"
-            android:persistent="false" />-->
-
-    </PreferenceCategory>
-<!--
-    <PreferenceCategory
-       android:key="button_keys_back"
-        android:title="@string/button_keys_back_title" >
-
-        <ListPreference
-            android:key="keys_back_press"
-            android:dialogTitle="@string/keys_back_press_title"
-            android:title="@string/keys_action_normal"
-            android:entries="@array/keys_action_entries"
-            android:entryValues="@array/keys_action_values"
-            android:persistent="false"
-            android:dependency="keys_enable_custom" />
-
-        <ListPreference
-            android:key="keys_back_long_press"
-            android:dialogTitle="@string/keys_back_long_press_title"
-            android:title="@string/keys_action_long"
-            android:entries="@array/keys_action_entries"
-            android:entryValues="@array/keys_action_values"
-            android:persistent="false"
-            android:dependency="keys_enable_custom" />
-    </PreferenceCategory>
-
-    <PreferenceCategory
-        android:key="button_keys_home"
-        android:title="@string/button_keys_home_title">
-
-        <ListPreference
-            android:key="keys_home_press"
-            android:dialogTitle="@string/keys_home_press_title"
-            android:title="@string/keys_action_normal"
-            android:entries="@array/keys_action_entries"
-            android:entryValues="@array/keys_action_values"
-            android:persistent="false"
-            android:dependency="keys_enable_custom" />
-
-        <ListPreference
-            android:key="keys_home_long_press"
-            android:dialogTitle="@string/keys_home_long_press_title"
-            android:title="@string/keys_action_long"
-            android:entries="@array/keys_action_entries"
-            android:entryValues="@array/keys_action_values"
-            android:persistent="false"
-            android:dependency="keys_enable_custom" />
-
-        <ListPreference
-            android:key="keys_home_double_tap"
-            android:dialogTitle="@string/keys_home_double_tap_title"
-            android:title="@string/keys_action_double"
-            android:entries="@array/keys_action_entries"
-            android:entryValues="@array/keys_action_values"
-            android:persistent="false"
-            android:dependency="keys_enable_custom" />
-
-        <CheckBoxPreference
-            android:key="button_home_wake_screen"
-            android:title="@string/button_home_wake_title"
-            android:summary="@string/button_home_wake_summary"
-            android:persistent="false"/>
-
-        <CheckBoxPreference
-            android:key="button_home_answers_call"
-            android:title="@string/button_home_answers_call_title"
-            android:summary="@string/button_home_answers_call_summary"
-            android:persistent="false" />
-
-    </PreferenceCategory>
-
-    <PreferenceCategory
-        android:key="button_keys_menu"
-        android:title="@string/button_keys_menu_title">
-
-        <ListPreference
-            android:key="keys_menu_press"
-            android:dialogTitle="@string/keys_menu_press_title"
-            android:title="@string/keys_action_normal"
-            android:entries="@array/keys_action_entries"
-            android:entryValues="@array/keys_action_values"
-            android:persistent="false"
-            android:dependency="keys_enable_custom" />
-
-        <ListPreference
-            android:key="keys_menu_long_press"
-            android:dialogTitle="@string/keys_menu_long_press_title"
-            android:title="@string/keys_action_long"
-            android:entries="@array/keys_action_entries"
-            android:entryValues="@array/keys_action_values"
-            android:persistent="false"
-            android:dependency="keys_enable_custom" />
-    </PreferenceCategory>
-
-    <PreferenceCategory
-        android:key="button_keys_assist"
-        android:title="@string/button_keys_assist_title">
-
-        <ListPreference
-            android:key="keys_assist_press"
-            android:dialogTitle="@string/keys_assist_press_title"
-            android:title="@string/keys_action_normal"
-            android:entries="@array/keys_action_entries"
-            android:entryValues="@array/keys_action_values"
-            android:persistent="false"
-            android:dependency="keys_enable_custom" />
-
-        <ListPreference
-            android:key="keys_assist_long_press"
-            android:dialogTitle="@string/keys_assist_long_press_title"
-            android:title="@string/keys_action_long"
-            android:entries="@array/keys_action_entries"
-            android:entryValues="@array/keys_action_values"
-            android:persistent="false"
-            android:dependency="keys_enable_custom" />
-    </PreferenceCategory>
-
-    <PreferenceCategory
-        android:key="button_keys_appSwitch"
-        android:title="@string/button_keys_appSwitch_title">
-
-        <ListPreference
-            android:key="keys_app_switch_press"
-            android:dialogTitle="@string/keys_app_switch_press_title"
-            android:title="@string/keys_action_normal"
-            android:entries="@array/keys_action_entries"
-            android:entryValues="@array/keys_action_values"
-            android:persistent="false"
-            android:dependency="keys_enable_custom" />
-
-        <ListPreference
-            android:key="keys_app_switch_long_press"
-            android:dialogTitle="@string/keys_app_switch_long_press_title"
-            android:title="@string/keys_action_long"
-            android:entries="@array/keys_action_entries"
-            android:entryValues="@array/keys_action_values"
-            android:persistent="false"
-            android:dependency="keys_enable_custom" />
-    </PreferenceCategory>
--->
-    <PreferenceCategory
-        android:key="button_other"
-        android:title="@string/button_other_title" >
-        <ListPreference
-            android:key="navbar_recents_style"
-            android:title="@string/navbar_recents_style_title"
-            android:entries="@array/navbar_recents_style_entries"
-            android:entryValues="@array/navbar_recents_style_values"
-            android:persistent="false"/>
-
-        <ListPreference
-            android:key="long_press_recents_action"
-            android:title="@string/long_press_recents_action_title"
-            android:entries="@array/long_press_recents_action_entries"
-            android:entryValues="@array/long_press_recents_action_values"
-            android:persistent="false"/>
-
-        <ListPreference
-            android:key="long_press_home_action"
-            android:title="@string/long_press_home_action_title"
-            android:entries="@array/long_press_home_action_entries"
-            android:entryValues="@array/long_press_home_action_values"
-            android:persistent="false"/>
-
-        <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
-            android:key="button_back_kill_enable"
-            android:title="@string/button_back_kill_enable_title"
-            android:summary="@string/button_back_kill_enable_summary"
-            android:defaultValue="false"/>
-
-        <ListPreference
-            android:key="button_back_kill_timeout"
-            android:title="@string/button_back_kill_timeout_title"
-            android:entries="@array/button_back_kill_timeout_entries"
-            android:entryValues="@array/button_back_kill_timeout_values"
-            android:persistent="false"
-            android:dependency="button_back_kill_enable"/>
-
-        <PreferenceScreen
-            android:key="global_actions"
-            android:title="@string/global_actions_title"
-            android:summary="@string/global_actions_summary"
-            android:fragment="org.omnirom.omnigears.interfacesettings.GlobalActionsSettings" />
-
-    </PreferenceCategory>
-
-<!--    <PreferenceCategory
-        android:key="button_headsethook"
-        android:title="@string/button_headsethook_title" >
-
-        <CheckBoxPreference
-            android:key="button_headsethook_launch_voice"
-            android:title="@string/button_headsethook_launch_voice_title"
-            android:summary="@string/button_headsethook_launch_voice_summary"
-            android:persistent="false" />
-
-    </PreferenceCategory>
--->
-</PreferenceScreen>
diff --git a/res/xml/display_rotation.xml b/res/xml/display_rotation.xml
deleted file mode 100644
index 4fee35b..0000000
--- a/res/xml/display_rotation.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-        android:title="@string/display_rotation_title"
-        xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
-
-    <SwitchPreference
-        android:key="accelerometer"
-        android:title="@string/accelerometer_title"
-        android:persistent="false" />
-
-    <CheckBoxPreference
-        android:key="lockscreen_rotation"
-        android:title="@string/display_lockscreen_rotation_title"
-        android:dependency="accelerometer"
-        android:persistent="false" />
-
-    <PreferenceCategory
-        android:key="display_rotation_category"
-        android:title="@string/display_rotation_category_title" />
-
-    <CheckBoxPreference
-        android:key="display_rotation_0"
-        android:title="@string/display_rotation_0_title"
-        android:layout="?android:attr/preferenceLayoutChild"
-        android:dependency="accelerometer"
-        android:persistent="false" />
-
-    <CheckBoxPreference
-        android:key="display_rotation_90"
-        android:title="@string/display_rotation_90_title"
-        android:layout="?android:attr/preferenceLayoutChild"
-        android:dependency="accelerometer"
-        android:persistent="false" />
-
-    <CheckBoxPreference
-        android:key="display_rotation_180"
-        android:title="@string/display_rotation_180_title"
-        android:layout="?android:attr/preferenceLayoutChild"
-        android:dependency="accelerometer"
-        android:persistent="false" />
-
-    <CheckBoxPreference
-        android:key="display_rotation_270"
-        android:title="@string/display_rotation_270_title"
-        android:layout="?android:attr/preferenceLayoutChild"
-        android:dependency="accelerometer"
-        android:persistent="false" />
-
-</PreferenceScreen>
diff --git a/res/xml/global_actions.xml b/res/xml/global_actions.xml
deleted file mode 100644
index 1222505..0000000
--- a/res/xml/global_actions.xml
+++ /dev/null
@@ -1,93 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--  Copyright (C) 2016 The OmniROM Project
-
-  This program 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 2 of the License, or
-  (at your option) any later version.
-
-  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- -->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-    android:key="global_actions"
-    android:title="@string/global_actions_title">
-
-    <PreferenceCategory
-        android:key="global_actions_anim"
-        android:title="@string/global_actions_anim" >
-
-       <org.omnirom.omnigears.preference.SecureSettingSwitchPreference
-            android:key="advanced_reboot"
-            android:title="@string/global_actions_advanced_reboot_title"
-            android:summary="@string/global_actions_advanced_reboot_summary" />
-       <ListPreference
-            android:key="power_menu_animations"
-            android:title="@string/power_menu_animation_title"
-            android:dialogTitle="@string/power_menu_animation_dialog_title"
-            android:entries="@array/power_menu_animations_entries"
-            android:entryValues="@array/power_menu_animations_values"
-            android:summary="@string/power_menu_animation_summary"
-            android:persistent="false" />
-    </PreferenceCategory>
-
-    <PreferenceCategory
-        android:key="global_actions_list"
-        android:title="@string/global_actions_header" >
-
-        <SwitchPreference
-            android:key="power"
-            android:title="@string/global_actions_power_title"
-            android:persistent="false" />
-        <SwitchPreference
-            android:key="reboot"
-            android:title="@string/global_actions_reboot_title"
-            android:persistent="false" />
-        <SwitchPreference
-            android:key="lockdown"
-            android:title="@string/global_actions_lockdown_title"
-            android:persistent="false" />
-        <SwitchPreference
-            android:key="settings"
-            android:title="@string/global_actions_settings_title"
-            android:persistent="false" />
-        <SwitchPreference
-            android:key="airplane"
-            android:title="@string/global_actions_airplane_title"
-            android:persistent="false" />
-        <SwitchPreference
-            android:key="screenshot"
-            android:title="@string/global_actions_screenshot_title"
-            android:persistent="false" />
-        <SwitchPreference
-            android:key="screenrecord"
-            android:title="@string/global_actions_screenrecord_title"
-            android:persistent="false" />
-        <SwitchPreference
-            android:key="torch"
-            android:title="@string/global_actions_torch_title"
-            android:persistent="false" />
-        <SwitchPreference
-            android:key="users"
-            android:title="@string/global_actions_users_title"
-            android:persistent="false" />
-        <SwitchPreference
-            android:key="voiceassist"
-            android:title="@string/global_actions_voiceassist_title"
-            android:persistent="false" />
-        <SwitchPreference
-            android:key="silent"
-            android:title="@string/global_actions_silent_title"
-            android:persistent="false" />
-        <SwitchPreference
-            android:key="dnd"
-            android:title="@string/global_actions_dnd_title"
-            android:persistent="false" />
-    </PreferenceCategory>
-</PreferenceScreen>
diff --git a/res/xml/lights_settings.xml b/res/xml/lights_settings.xml
deleted file mode 100644
index b302404..0000000
--- a/res/xml/lights_settings.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--  Copyright (C) 2017 The OmniROM Project
-  This program 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 2 of the License, or
-  (at your option) any later version.
-  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- -->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-    android:key="ligths_settings"
-    android:title="@string/omni_lights_title">
-
-       <PreferenceCategory
-        android:key="leds"
-        android:title="@string/omni_leds" >
-
-        <PreferenceScreen
-                android:key="notification_light"
-                android:title="@string/omni_notification_light_settings"
-                android:summary="@string/omni_notification_light_settings_summary"
-                android:fragment="org.omnirom.omnigears.batterylight.NotificationLightSettings" />
-
-        <PreferenceScreen
-                android:key="charging_light"
-                android:title="@string/omni_battery_light_settings"
-                android:summary="@string/omni_battery_light_settings_summary"
-                android:fragment="org.omnirom.omnigears.batterylight.BatteryLightSettings" />
-       </PreferenceCategory>
-</PreferenceScreen>
diff --git a/res/xml/lockscreen_settings.xml b/res/xml/lockscreen_settings.xml
deleted file mode 100644
index 2d3db9a..0000000
--- a/res/xml/lockscreen_settings.xml
+++ /dev/null
@@ -1,148 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--  Copyright (C) 2015 The OmniROM Project
-
-  This program 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 2 of the License, or
-  (at your option) any later version.
-
-  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- -->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
-    <PreferenceCategory
-        android:key="lockscreen_shortcut"
-        android:title="@string/lockscreen_shortcut_title" >
-
-        <org.omnirom.omnigears.preference.SecureSettingSwitchPreference
-            android:key="lockscreen_shortcuts_enable"
-            android:title="@string/lockscreen_shortcuts_enable_title"
-            android:defaultValue="true"/>
-
-        <org.omnirom.omnigears.preference.SecureCheckBoxPreference
-            android:key="lockscreen_camera_shortcut_enable"
-            android:title="@string/lockscreen_camera_shortcut_enable_title"
-            android:summary="@string/lockscreen_camera_shortcut_enable_summary"
-            android:defaultValue="true"
-            android:dependency="lockscreen_shortcuts_enable" />
-
-        <org.omnirom.omnigears.preference.SecureCheckBoxPreference
-            android:key="lockscreen_left_shortcut_enable"
-            android:title="@string/lockscreen_left_shortcut_enable_title"
-            android:summary="@string/lockscreen_left_shortcut_enable_summary"
-            android:defaultValue="true"
-            android:dependency="lockscreen_shortcuts_enable" />
-
-        <org.omnirom.omnigears.preference.SecureCheckBoxPreference
-            android:key="lockscreen_voice_shortcut"
-            android:title="@string/lockscreen_voice_shortcut_title"
-            android:summary="@string/lockscreen_voice_shortcut_summary"
-            android:defaultValue="true"
-            android:dependency="lockscreen_left_shortcut_enable" />
-
-        <!--
-
-        <Preference
-            android:key="lockscreen_shortcuts"
-            android:title="@string/lockscreen_shortcuts_title"
-            android:summary="@string/lockscreen_shortcuts_summary"
-            android:persistent="false"
-            android:dependency="lockscreen_shortcuts_enable" />
-        -->
-
-    </PreferenceCategory>
-    <PreferenceCategory
-        android:key="lockscreen_other"
-        android:title="@string/other_category" >
-
-        <org.omnirom.omnigears.preference.SecureSettingSwitchPreference
-            android:key="lockscreen_hide_indicator_display"
-            android:title="@string/lockscreen_hide_indicator_display_title"
-            android:summary="@string/lockscreen_hide_indicator_display_summary" />
-
-        <org.omnirom.omnigears.preference.SecureSettingSwitchPreference
-            android:key="lockscreen_qs_disabled"
-            android:title="@string/lockscreen_qs_disabled_title"
-            android:summary="@string/lockscreen_qs_summary"/>
-
-        <org.omnirom.omnigears.preference.SecureSettingSwitchPreference
-            android:key="lockscreen_power_menu_disabled"
-            android:title="@string/lockscreen_power_menu_disabled_title"
-            android:summary="@string/lockscreen_power_menu_disabled_summary" />
-
-        <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
-            android:key="lockscreen_hide_media"
-            android:title="@string/lockscreen_hide_media_title"
-            android:summary="@string/lockscreen_hide_media_summary" />
-
-        <org.omnirom.omnigears.preference.SecureSettingSwitchPreference
-            android:key="lockscreen_hide_status_bar"
-            android:title="@string/lockscreen_hide_status_bar_title"
-            android:summary="@string/lockscreen_hide_status_bar_summary"/>
-
-    </PreferenceCategory>
-
-    <PreferenceCategory
-        android:key="lockscreen_clock"
-        android:title="@string/lockscreen_clock" >
-
-        <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
-            android:key="lockscreen_clock_enable"
-            android:title="@string/lockscreen_clock_enable_title"
-            android:summary="@string/lockscreen_clock_enable_summary"
-            android:defaultValue="true" />
-
-        <CheckBoxPreference
-            android:key="lockscreen_clock_display_time"
-            android:title="@string/lockscreen_clock_display_time_title"
-            android:persistent="false"
-            android:defaultValue="true"
-            android:dependency="lockscreen_clock_enable" />
-
-        <CheckBoxPreference
-            android:key="lockscreen_clock_display_date"
-            android:title="@string/lockscreen_clock_display_date_title"
-            android:persistent="false"
-            android:defaultValue="true"
-            android:dependency="lockscreen_clock_enable" />
-
-        <CheckBoxPreference
-            android:key="lockscreen_clock_display_alarm"
-            android:title="@string/lockscreen_clock_display_alarm_title"
-            android:persistent="false"
-            android:defaultValue="true"
-            android:dependency="lockscreen_clock_enable" />
-
-        <org.omnirom.omnigears.preference.FontPreference
-            android:key="lockscreen_clock_font"
-            android:title="@string/lockscreen_clock_font_title"
-            android:persistent="false"
-            android:dependency="lockscreen_clock_enable" />
-
-        <org.omnirom.omnigears.preference.ColorPickerPreference
-            android:key="lockscreen_clock_color"
-            android:title="@string/lockscreen_clock_color_title"
-            android:persistent="false"
-            android:dependency="lockscreen_clock_enable" />
-
-        <org.omnirom.omnigears.preference.NumberPickerPreference
-            android:key="lockscreen_clock_size"
-            android:title="@string/lockscreen_clock_size_title"
-            android:persistent="false"
-            android:dependency="lockscreen_clock_enable" />
-
-        <CheckBoxPreference
-            android:key="lockscreen_clock_shadow"
-            android:title="@string/lockscreen_clock_shadow_title"
-            android:persistent="false"
-            android:defaultValue="false"
-            android:dependency="lockscreen_clock_enable" />
-
-    </PreferenceCategory>
-</PreferenceScreen>
diff --git a/res/xml/more_settings.xml b/res/xml/more_settings.xml
deleted file mode 100644
index 8bcd8d8..0000000
--- a/res/xml/more_settings.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--  Copyright (C) 2017 The OmniROM Project
-
-  This program 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 2 of the License, or
-  (at your option) any later version.
-
-  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- -->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-    android:key="more_settings"
-    android:title="@string/more_settings_title">
-
-        <PreferenceCategory
-            android:key="category_other"
-            android:title="@string/other_category">
-
-            <org.omnirom.omnigears.preference.HostnamePreference
-                android:key="device_hostname"
-                android:title="@string/device_hostname"
-                android:dialogTitle="@string/device_hostname"
-                android:persistent="false" />
-
-            <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
-                android:key="screenshot_crop_and_share"
-                android:title="@string/screenshot_crop_and_share_title"
-                android:summary="@string/screenshot_crop_and_share_summary"
-                android:defaultValue="false" />
-
-            <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
-                android:key="volume_dialog_headers"
-                android:title="@string/volume_dialog_headers_title"
-                android:summary="@string/volume_dialog_headers_summary"
-                android:defaultValue="true" />
-
-            <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
-                android:key="headset_plugged_notification"
-                android:title="@string/headset_plugged_notification_title"
-                android:summary="@string/headset_plugged_notification_summary"
-                android:defaultValue="true" />
-        </PreferenceCategory>
-
-        <PreferenceCategory
-            android:key="category_display"
-            android:title="@string/category_display">
-
-            <PreferenceScreen
-                android:key="display_rotation"
-                android:title="@string/display_rotation_title"
-                android:fragment="org.omnirom.omnigears.DisplayRotation" />
-        </PreferenceCategory>
-
-        <PreferenceCategory
-            android:key="category_system"
-            android:title="@string/system_category">
-
-            <PreferenceScreen
-                android:key="time_in_state"
-                android:title="@string/time_in_state_title"
-                android:summary="@string/time_in_state_summary"
-                android:fragment="org.omnirom.omnigears.system.TimeInState" />
-
-            <PreferenceScreen
-                android:key="wakelocks"
-                android:title="@string/wakelocks_title"
-                android:summary="@string/wakelocks_summary"
-                android:fragment="org.omnirom.omnigears.system.Wakelocks" />
-
-            <PreferenceScreen
-                android:key="doze_settings"
-                android:title="@string/doze_settings_title"
-                android:summary="@string/doze_settings_summary"
-                android:fragment="org.omnirom.omnigears.system.DozeSettings" />
-
-            <org.omnirom.omnigears.preference.GlobalSettingSwitchPreference
-                android:key="show_cpu"
-                android:title="@string/show_cpu_title"
-                android:summary="@string/show_cpu_summary" />
-
-            <PreferenceScreen
-                android:key="logcat_app"
-                android:title="@string/logcat_app_title"
-                android:summary="@string/logcat_app_summary"
-                android:persistent="false" >
-                <intent android:action="android.intent.action.MAIN"
-                        android:targetPackage="org.omnirom.logcat"
-                        android:targetClass="com.pluscubed.logcat.ui.LogcatActivity" />
-            </PreferenceScreen>
-        </PreferenceCategory>
-</PreferenceScreen>
diff --git a/res/xml/network_traffic.xml b/res/xml/network_traffic.xml
deleted file mode 100644
index 6877985..0000000
--- a/res/xml/network_traffic.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--  Copyright (C) 2015 The OmniROM Project
-
-  This program 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 2 of the License, or
-  (at your option) any later version.
-
-  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
--->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
-        android:key="category_network_traffic"
-        android:title="@string/network_traffic_title">
-
-            <ListPreference
-                android:key="network_traffic_state"
-                android:title="@string/show_network_traffic_state"
-                android:entries="@array/show_network_traffic_state_entries"
-                android:entryValues="@array/show_network_traffic_state_values"
-                android:persistent="false" />
-
-            <ListPreference
-                android:key="network_traffic_unit"
-                android:title="@string/show_network_traffic_unit"
-                android:entries="@array/show_network_traffic_unit_entries"
-                android:entryValues="@array/show_network_traffic_unit_values"
-                android:persistent="false" />
-
-            <ListPreference
-                android:key="network_traffic_period"
-                android:title="@string/show_network_traffic_frequency"
-                android:entries="@array/show_network_traffic_frequency_entries"
-                android:entryValues="@array/show_network_traffic_frequency_values"
-                android:persistent="false" />
-
-            <org.omnirom.omnigears.preference.SystemCheckBoxPreference
-                android:key="network_traffic_autohide"
-                android:title="@string/network_traffic_autohide_title"
-                android:summary="@string/network_traffic_autohide_summary"
-                android:defaultValue="false"/>
-
-            <org.omnirom.omnigears.preference.SeekBarPreference
-                android:key="network_traffic_autohide_threshold"
-                android:title="@string/network_traffic_autohide_threshold"
-                android:max="100"
-                settings:min="0"
-                settings:unitsLeft=""
-                settings:unitsRight="kB/s"
-                android:dependency="network_traffic_autohide"
-                android:persistent="false" />
-
-</PreferenceScreen>
diff --git a/res/xml/notification_light_settings.xml b/res/xml/notification_light_settings.xml
deleted file mode 100644
index 538a1ee..0000000
--- a/res/xml/notification_light_settings.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The CyanogenMod Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
-
-    <PreferenceCategory
-        android:key="general_section"
-        android:title="@string/notification_light_general_title">
-
-        <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
-            android:key="notification_light_pulse"
-            android:title="@string/notification_light_title" />
-
-        <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
-            android:key="notification_light_color_auto"
-            android:title="@string/notification_light_automagic"
-            android:summary="@string/notification_light_automagic_summary"
-            android:dependency="notification_light_pulse"
-            android:defaultValue="true" />
-
-        <org.omnirom.omnigears.batterylight.NotificationLightPreference
-            android:key="default"
-            android:title="@string/notification_light_default_value"
-            android:persistent="false"
-            android:dependency="notification_light_pulse" />
-
-    </PreferenceCategory>
-
-    <PreferenceCategory
-        android:key="advanced_section"
-        android:title="@string/advanced">
-
-        <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
-            android:key="notification_light_screen_on_enable"
-            android:title="@string/notification_light_screen_on"
-            android:dependency="notification_light_pulse" />
-
-        <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
-            android:key="allow_lights"
-            android:title="@string/notification_light_zen_mode"
-            android:dependency="notification_light_pulse"
-            android:defaultValue="true" />
-
-        <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
-            android:key="notification_light_pulse_custom_enable"
-            android:title="@string/notification_light_use_custom"
-            android:dependency="notification_light_pulse" />
-
-    </PreferenceCategory>
-
-    <PreferenceCategory
-        android:key="applications_list"
-        android:title="@string/notification_light_applist_title"
-        android:dependency="notification_light_pulse_custom_enable" >
-    </PreferenceCategory>
-
-</PreferenceScreen>
diff --git a/res/xml/omni_dashboard_fragment.xml b/res/xml/omni_dashboard_fragment.xml
new file mode 100644
index 0000000..78cd6c7
--- /dev/null
+++ b/res/xml/omni_dashboard_fragment.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:title="@string/header_category_omni">
+</PreferenceScreen>
diff --git a/res/xml/omnijaws_settings.xml b/res/xml/omnijaws_settings.xml
deleted file mode 100644
index 3540830..0000000
--- a/res/xml/omnijaws_settings.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--  Copyright (C) 2017 The OmniROM Project
-
-  This program 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 2 of the License, or
-  (at your option) any later version.
-
-  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- -->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-    android:key="omnijaws_settings"
-    android:title="@string/weather_title">
-
-        <PreferenceScreen
-            android:title="@string/weather_config_title"
-            android:summary="@string/weather_config_summary" >
-            <intent android:action="android.intent.action.MAIN"
-                    android:targetPackage="org.omnirom.omnijaws"
-                    android:targetClass="org.omnirom.omnijaws.SettingsActivityService" />
-        </PreferenceScreen>
-
-        <ListPreference
-            android:key="weather_icon_pack"
-            android:title="@string/weather_icon_pack_title"
-            android:persistent="false" />
-</PreferenceScreen>
diff --git a/res/xml/statusbar_battery_settings.xml b/res/xml/statusbar_battery_settings.xml
deleted file mode 100644
index 95b10eb..0000000
--- a/res/xml/statusbar_battery_settings.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--  Copyright (C) 2015 The OmniROM Project
-
-  This program 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 2 of the License, or
-  (at your option) any later version.
-
-  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
--->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
-
-        <SwitchPreference
-            android:key="statusbar_battery_enable"
-            android:title="@string/battery_enable_title"
-            android:persistent="false"
-            android:defaultValue="true"/>
-        <ListPreference
-            android:key="statusbar_battery_style"
-            android:title="@string/battery_style_title"
-            android:entries="@*android:array/entries_battery_styles"
-            android:entryValues="@*android:array/values_battery_styles"
-            android:persistent="false"
-            android:defaultValue="0"/>
-        <CheckBoxPreference
-            android:key="statusbar_battery_percent"
-            android:title="@string/battery_percent_title"
-            android:persistent="false"
-            android:defaultValue="false"/>
-        <org.omnirom.omnigears.preference.SystemCheckBoxPreference
-            android:key="statusbar_battery_percent_inside"
-            android:title="@string/statusbar_percent_inside_title"
-            android:summary="@string/statusbar_percent_inside_summary"
-            android:defaultValue="false"/>
-
-        <PreferenceCategory
-            android:key="statusbar_category_charging"
-            android:title="@string/statusbar_category_charging_title">
-
-            <org.omnirom.omnigears.preference.SystemCheckBoxPreference
-                android:key="statusbar_battery_charging_image"
-                android:title="@string/statusbar_charging_image_title"
-                android:summary="@string/statusbar_charging_image_summary"
-                android:defaultValue="true"/>
-            <org.omnirom.omnigears.preference.SystemCheckBoxPreference
-                android:key="statusbar_battery_charging_color_enable"
-                android:title="@string/statusbar_battery_charging_color_enable_title"
-                android:summary="@string/statusbar_battery_charging_color_enable_summary"
-                android:defaultValue="true"/>
-            <org.omnirom.omnigears.preference.ColorPickerPreference
-                android:key="statusbar_battery_charging_color"
-                android:title="@string/statusbar_battery_charging_color_title"
-                android:persistent="false"
-                android:dependency ="statusbar_battery_charging_color_enable"/>
-
-        </PreferenceCategory>
-</PreferenceScreen>
diff --git a/res/xml/style_settings.xml b/res/xml/style_settings.xml
index 63723e9..93303db 100644
--- a/res/xml/style_settings.xml
+++ b/res/xml/style_settings.xml
@@ -22,29 +22,6 @@
             android:title="@string/theming_title">
 
             <Preference
-                android:key="oms_app"
-                android:title="@string/oms_app_title"
-                android:summary="@string/oms_app_summary"/>
-
-            <PreferenceScreen
-                android:key="omni_theme"
-                android:title="@string/omni_theme_title"
-                android:summary="@string/omni_theme_summary"
-                android:persistent="false" >
-                <intent android:action="android.intent.action.MAIN"
-                        android:targetPackage="org.omnirom.daynight"
-                        android:targetClass="org.omnirom.daynight.OmniSubstratumLauncher" />
-            </PreferenceScreen>
-
-            <ListPreference
-                android:key="night_mode"
-                android:title="@string/night_mode_title"
-                settings:keywords="@string/keywords_display_night_mode"
-                android:summary="@string/night_mode_summary"
-                android:entries="@array/night_mode_entries"
-                android:entryValues="@array/night_mode_values" />
-
-            <PreferenceScreen
                 android:key="custom_wall_browse"
                 android:title="@string/custom_wall_browse_title"
                 android:summary="@string/custom_wall_browse_summary"
@@ -52,65 +29,6 @@
                 <intent android:action="android.intent.action.MAIN"
                         android:targetPackage="org.omnirom.omnistyle"
                         android:targetClass="org.omnirom.omnistyle.BrowseWallsActivity" />
-            </PreferenceScreen>
-        </PreferenceCategory>
-
-        <PreferenceCategory
-            android:key="category_statusbar"
-            android:title="@string/statusbar_title">
-
-            <PreferenceScreen
-                android:key="statusbar_battery"
-                android:title="@string/battery_title"
-                android:summary="@string/statusbar_battery_summary"
-                android:fragment="org.omnirom.omnigears.interfacesettings.StatusbarBatterySettings" />
-
-            <org.omnirom.omnigears.preference.SystemCheckBoxPreference
-                android:key="status_bar_logo"
-                android:title="@string/status_bar_logo_title"
-                android:summary="@string/status_bar_logo_summary"/>
-
-        </PreferenceCategory>
-
-        <PreferenceCategory
-            android:key="status_bar_custom_header_category"
-            android:title="@string/notification_title" >
-
-            <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
-                android:key="status_bar_custom_header"
-                android:title="@string/status_bar_custom_header_title"
-                android:summary="@string/status_bar_custom_header_summary"
-                android:defaultValue="false" />
-
-            <ListPreference
-                android:key="custom_header_provider"
-                android:title="@string/custom_header_provider_title"
-                android:persistent="false"
-                android:entries="@array/custom_header_provider_entries"
-                android:entryValues="@array/custom_header_provider_values"
-                android:dependency="status_bar_custom_header" />
-
-            <ListPreference
-                android:key="daylight_header_pack"
-                android:title="@string/daylight_header_pack_title"
-                android:persistent="false"
-                android:dependency="status_bar_custom_header" />
-
-            <PreferenceScreen
-                android:key="custom_header_browse"
-                android:title="@string/custom_header_browse_title"
-                android:dependency="status_bar_custom_header"
-                android:persistent="false" />
-
-            <org.omnirom.omnigears.preference.SeekBarPreference
-                android:key="status_bar_custom_header_shadow"
-                android:title="@string/status_bar_custom_header_shadow_title"
-                android:summary="@string/status_bar_custom_header_shadow_summary"
-                android:max="100"
-                settings:min="0"
-                settings:unitsLeft=""
-                settings:unitsRight="@string/unit_percent"
-                android:persistent="false"
-                android:dependency="status_bar_custom_header" />
+            </Preference>
         </PreferenceCategory>
 </PreferenceScreen>
diff --git a/src/org/omnirom/omnigears/AmbientSettings.java b/src/org/omnirom/omnigears/AmbientSettings.java
deleted file mode 100644
index ef831a7..0000000
--- a/src/org/omnirom/omnigears/AmbientSettings.java
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- *  Copyright (C) 2015 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- *
-package org.omnirom.omnigears;
-
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.database.ContentObserver;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.PowerManager;
-import android.os.SystemProperties;
-import android.preference.ListPreference;
-import android.preference.Preference;
-import android.preference.Preference.OnPreferenceClickListener;
-import android.preference.PreferenceScreen;
-import android.preference.PreferenceCategory;
-import android.preference.SwitchPreference;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.text.Editable;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.util.Log;
-import android.view.View;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.SeekBar;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.preference.SeekBarPreference;
-import com.android.settings.preference.SystemCheckBoxPreference;
-import org.omnirom.omnigears.sensor.ShakeSensorManager;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class AmbientSettings extends SettingsPreferenceFragment implements
-        Preference.OnPreferenceChangeListener,
-        Indexable, ShakeSensorManager.ShakeListener {
-    private static final String TAG = "AmbientSettings";
-
-    private static final String KEY_DOZE = "doze";
-    private static final String KEY_DOZE_OVERWRITE_VALUE = "doze_overwrite_value";
-    private static final String KEY_DOZE_PULSE_IN = "doze_pulse_in";
-    private static final String KEY_DOZE_PULSE_VISIBLE = "doze_pulse_visible";
-    private static final String KEY_DOZE_PULSE_OUT = "doze_pulse_out";
-    private static final String KEY_DOZE_LIST_MODE = "doze_list_mode";
-    private static final String KEY_DOZE_PULSE_MODE = "doze_pulse_on_notifications";
-    private static final String KEY_DOZE_SHAKE_CATEGORY = "doze_shake_category";
-    private static final String KEY_DOZE_SHAKE_THRESHOLD = "doze_shake_threshold";
-    private static final String KEY_DOZE_TIME_MODE = "doze_time_mode";
-    private static final String KEY_DOZE_BRIGHTNESS_LEVEL = "doze_brightness_level";
-
-    private int mAccValue;
-    private int mOldAccValue;
-    private SwitchPreference mDozePreference;
-    private ListPreference mDozeListMode;
-    private ListPreference mDozePulseIn;
-    private ListPreference mDozePulseVisible;
-    private ListPreference mDozePulseOut;
-    private ListPreference mDozeShakeThreshold;
-    private SystemCheckBoxPreference mDozeTimeMode;
-    private ShakeSensorManager mShakeSensorManager;
-    private AlertDialog mDialog;
-    private Button mShakeFoundButton;
-    private SeekBarPreference mDozeBrightness;
-    private int mCurrentBrightness;
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsLogger.OMNI_SETTINGS;
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        final Activity activity = getActivity();
-
-        addPreferencesFromResource(R.xml.ambient_settings);
-
-        mDozePreference = (SwitchPreference) findPreference(KEY_DOZE);
-        mDozePreference.setOnPreferenceChangeListener(this);
-
-        mDozePulseIn = (ListPreference) findPreference(KEY_DOZE_PULSE_IN);
-        mDozePulseIn.setOnPreferenceChangeListener(this);
-
-        mDozePulseVisible = (ListPreference) findPreference(KEY_DOZE_PULSE_VISIBLE);
-        mDozePulseVisible.setOnPreferenceChangeListener(this);
-
-        mDozePulseOut = (ListPreference) findPreference(KEY_DOZE_PULSE_OUT);
-        mDozePulseOut.setOnPreferenceChangeListener(this);
-
-        if (isAccelerometerAvailable(activity)) {
-            mDozeListMode = (ListPreference) findPreference(KEY_DOZE_LIST_MODE);
-            mDozeListMode.setOnPreferenceChangeListener(this);
-
-            mDozeTimeMode = (SystemCheckBoxPreference) findPreference(KEY_DOZE_TIME_MODE);
-
-            mDozeShakeThreshold = (ListPreference) findPreference(KEY_DOZE_SHAKE_THRESHOLD);
-            mDozeShakeThreshold.setOnPreferenceChangeListener(this);
-
-            removePreference(KEY_DOZE_PULSE_MODE);
-        } else {
-            removePreference(KEY_DOZE_LIST_MODE);
-            removePreference(KEY_DOZE_TIME_MODE);
-            removePreference(KEY_DOZE_SHAKE_THRESHOLD);
-            removePreference(KEY_DOZE_SHAKE_CATEGORY);
-            removePreference(KEY_DOZE_PULSE_MODE);
-        }
-        updateDozeListMode();
-        updateDozeOptions();
-        mShakeSensorManager = new ShakeSensorManager(activity, this);
-
-        final int dozeBrightnessConfig = getResources().getInteger(
-                com.android.internal.R.integer.config_screenBrightnessDoze);
-        mCurrentBrightness = Settings.System.getInt(getContentResolver(),
-                Settings.System.SCREEN_BRIGHTNESS_DOZE, dozeBrightnessConfig);
-        mDozeBrightness = (SeekBarPreference) findPreference(KEY_DOZE_BRIGHTNESS_LEVEL);
-        PowerManager pm = (PowerManager)activity.getSystemService(Context.POWER_SERVICE);
-        mDozeBrightness.setMaxValue(pm.getMaximumScreenBrightnessSetting());
-        mDozeBrightness.setMinValue(pm.getMinimumScreenBrightnessSetting());
-        mDozeBrightness.setValue(mCurrentBrightness);
-        mDozeBrightness.setOnPreferenceChangeListener(this);
-    }
-
-    private static boolean isAccelerometerAvailable(Context context) {
-        boolean useAccelerometer = context.getResources().getBoolean(
-                com.android.internal.R.bool.config_dozeUseAccelerometer);
-        return useAccelerometer;
-    }
-
-    private static boolean isDozeAvailable(Context context) {
-        String name = Build.IS_DEBUGGABLE ? SystemProperties.get("debug.doze.component") : null;
-        if (TextUtils.isEmpty(name)) {
-            name = context.getResources().getString(
-                    com.android.internal.R.string.config_dozeComponent);
-        }
-        return !TextUtils.isEmpty(name);
-    }
-
-    private void updateDozeListMode() {
-        final boolean pocketMode = Settings.System.getInt(getContentResolver(),
-                   Settings.System.DOZE_POCKET_MODE, 0) != 0;
-        final boolean shakeMode = Settings.System.getInt(getContentResolver(),
-                   Settings.System.DOZE_SHAKE_MODE, 0) != 0;
-        final boolean pulseMode = Settings.System.getInt(getContentResolver(),
-                   Settings.System.DOZE_PULSE_ON_NOTIFICATIONS, 1) != 0;
-        int listMode = 6;
-        if (pocketMode && shakeMode && pulseMode) {
-            listMode = 1;
-            enableShakeThreshold(true);
-        } else if (pocketMode && shakeMode && !pulseMode) {
-            listMode = 2;
-            enableShakeThreshold(true);
-        } else if (pocketMode && !shakeMode && pulseMode) {
-            listMode = 3;
-            enableShakeThreshold(false);
-        } else if (pocketMode && !shakeMode && !pulseMode) {
-            listMode = 4;
-            enableShakeThreshold(false);
-        } else if (!pocketMode && shakeMode && pulseMode) {
-            listMode = 5;
-            enableShakeThreshold(true);
-        } else if (!pocketMode && !shakeMode && pulseMode) {
-            listMode = 6;
-            enableShakeThreshold(false);
-        }
-        enabledTimeMode(pocketMode);
-        if (mDozeListMode != null) {
-            mDozeListMode.setValue(String.valueOf(listMode));
-            int index = mDozeListMode.findIndexOfValue(String.valueOf(listMode));
-            if (index != -1) {
-                mDozeListMode.setSummary(mDozeListMode.getEntries()[index]);
-            }
-        }
-    }
-
-    private void enabledTimeMode(boolean enable) {
-        if (mDozeTimeMode != null) {
-            mDozeTimeMode.setEnabled(enable);
-        }
-    }
-
-    private void showAccDialog() {
-        AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());
-        alertDialog.setTitle(R.string.doze_shake_mode_title);
-        alertDialog.setMessage(R.string.doze_shake_mode_test_summary);
-        alertDialog.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
-            public void onClick(DialogInterface dialog, int id) {
-                startAcctest();
-            }
-        });
-        alertDialog.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
-            public void onClick(DialogInterface dialog, int id) {
-                stopAcctest();
-            }
-        });
-        mDialog = alertDialog.create();
-        mDialog.show();
-    }
-
-    @Override
-    public synchronized void onShake() {
-        String msg1 = getResources().getString(R.string.doze_shake_it);
-        String msg2 = getResources().getString(R.string.doze_shake_mode_test_result);
-
-        String msg = msg1 + "\n" + msg2;
-        mDialog.setMessage(msg);
-        Button shakeCancelButton = mDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
-        if (shakeCancelButton != null) {
-            shakeCancelButton.setText(R.string.no);
-        }
-        if (mShakeFoundButton != null) {
-            mShakeFoundButton.setEnabled(true);
-        }
-        mShakeSensorManager.disable();
-    }
-
-    private void startAcctest() {
-        mShakeSensorManager.enable(mAccValue);
-        AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());
-        alertDialog.setTitle(R.string.doze_shake_mode_title);
-        alertDialog.setMessage(R.string.doze_shake_test);
-        alertDialog.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
-            public void onClick(DialogInterface dialog, int id) {
-                stopAcctest();
-            }
-        });
-        alertDialog.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
-            public void onClick(DialogInterface dialog, int id) {
-                revertAcctest();
-            }
-        });
-        mDialog = alertDialog.create();
-        mDialog.show();
-
-        mShakeFoundButton = mDialog.getButton(DialogInterface.BUTTON_POSITIVE);
-        if (mShakeFoundButton != null) {
-            mShakeFoundButton.setEnabled(false);
-        }
-    }
-
-    private void revertAcctest() {
-        mAccValue = mOldAccValue;
-        mDozeShakeThreshold.setValue(String.valueOf(mOldAccValue));
-        mShakeSensorManager.disable();
-    }
-
-    private void stopAcctest() {
-        appliedAccTest();
-        mShakeSensorManager.disable();
-    }
-
-    private void appliedAccTest() {
-        Settings.System.putInt(getContentResolver(),
-                    Settings.System.DOZE_SHAKE_ACC_THRESHOLD, mAccValue);
-        mDozeShakeThreshold.setValue(String.valueOf(mAccValue));
-        int index = mDozeShakeThreshold.findIndexOfValue(String.valueOf(mAccValue));
-        if (index != -1) {
-            mDozeShakeThreshold.setSummary(mDozeShakeThreshold.getEntries()[index]);
-        }
-    }
-
-    private void enableShakeThreshold(boolean enabled) {
-        final boolean writeMode = Settings.System.getInt(getContentResolver(),
-                   Settings.System.DOZE_OVERWRITE_VALUE, 0) != 0;
-        if (mDozeShakeThreshold != null) {
-            mDozeShakeThreshold.setEnabled(enabled && writeMode);
-        }
-    }
-
-    private void updateDozeListModeValue(int listMode) {
-        if (listMode == 1) {
-            enableShakeThreshold(true);
-            enabledTimeMode(true);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_POCKET_MODE, 1);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_SHAKE_MODE, 1);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_PULSE_ON_NOTIFICATIONS, 1);
-        } else if (listMode == 2) {
-            enableShakeThreshold(true);
-            enabledTimeMode(true);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_POCKET_MODE, 1);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_SHAKE_MODE, 1);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_PULSE_ON_NOTIFICATIONS, 0);
-        } else if (listMode == 3) {
-            enableShakeThreshold(false);
-            enabledTimeMode(true);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_POCKET_MODE, 1);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_SHAKE_MODE, 0);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_PULSE_ON_NOTIFICATIONS, 1);
-        } else if (listMode == 4) {
-            enableShakeThreshold(false);
-            enabledTimeMode(true);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_POCKET_MODE, 1);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_SHAKE_MODE, 0);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_PULSE_ON_NOTIFICATIONS, 0);
-        } else if (listMode == 5) {
-            enableShakeThreshold(true);
-            enabledTimeMode(false);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_POCKET_MODE, 0);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_SHAKE_MODE, 1);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_PULSE_ON_NOTIFICATIONS, 1);
-        } else if (listMode == 6) {
-            enableShakeThreshold(false);
-            enabledTimeMode(false);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_POCKET_MODE, 0);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_SHAKE_MODE, 0);
-            Settings.System.putInt(getContentResolver(),
-                   Settings.System.DOZE_PULSE_ON_NOTIFICATIONS, 1);
-        }
-    }
-
-    private void updateDozeOptions() {
-        if (mDozePulseIn != null) {
-            final int statusDozePulseIn = Settings.System.getInt(getContentResolver(),
-                    Settings.System.DOZE_PULSE_DURATION_IN, 1000);
-            mDozePulseIn.setValue(String.valueOf(statusDozePulseIn));
-            int index = mDozePulseIn.findIndexOfValue(String.valueOf(statusDozePulseIn));
-            if (index != -1) {
-                mDozePulseIn.setSummary(mDozePulseIn.getEntries()[index]);
-            }
-        }
-        if (mDozePulseVisible != null) {
-            final int statusDozePulseVisible = Settings.System.getInt(getContentResolver(),
-                    Settings.System.DOZE_PULSE_DURATION_VISIBLE, 3000);
-            mDozePulseVisible.setValue(String.valueOf(statusDozePulseVisible));
-            int index = mDozePulseVisible.findIndexOfValue(String.valueOf(statusDozePulseVisible));
-            if (index != -1) {
-                mDozePulseVisible.setSummary(mDozePulseVisible.getEntries()[index]);
-            }
-        }
-        if (mDozePulseOut != null) {
-            final int statusDozePulseOut = Settings.System.getInt(getContentResolver(),
-                    Settings.System.DOZE_PULSE_DURATION_OUT, 1000);
-            mDozePulseOut.setValue(String.valueOf(statusDozePulseOut));
-            int index = mDozePulseOut.findIndexOfValue(String.valueOf(statusDozePulseOut));
-            if (index != -1) {
-               mDozePulseOut.setSummary(mDozePulseOut.getEntries()[index]);
-            }
-        }
-        if (mDozeShakeThreshold != null) {
-            mAccValue = Settings.System.getInt(getContentResolver(),
-                    Settings.System.DOZE_SHAKE_ACC_THRESHOLD, 10);
-            mDozeShakeThreshold.setValue(String.valueOf(mAccValue));
-            int index = mDozeShakeThreshold.findIndexOfValue(String.valueOf(mAccValue));
-            if (index != -1) {
-                mDozeShakeThreshold.setSummary(mDozeShakeThreshold.getEntries()[index]);
-            }
-        }
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        updateState();
-        updateDozeOptions();
-        updateDozeListMode();
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        mShakeSensorManager.disable();
-        if (mDialog != null) {
-            mDialog.dismiss();
-        }
-    }
-
-    private void updateState() {
-        // Update doze if it is available.
-        if (mDozePreference != null) {
-            int value = Settings.Secure.getInt(getContentResolver(), Settings.Secure.DOZE_ENABLED, 1);
-            mDozePreference.setChecked(value != 0);
-        }
-    }
-
-    @Override
-    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
-        if (preference == findPreference(KEY_DOZE_OVERWRITE_VALUE)) {
-            updateDozeListMode();
-            return true;
-        }
-        return super.onPreferenceTreeClick(preferenceScreen, preference);
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object objValue) {
-        final String key = preference.getKey();
-        if (preference == mDozePreference) {
-            boolean value = (Boolean) objValue;
-            Settings.Secure.putInt(getContentResolver(), Settings.Secure.DOZE_ENABLED, value ? 1 : 0);
-        }
-        if (preference == mDozePulseIn) {
-            int dozePulseIn = Integer.parseInt((String)objValue);
-            int index = mDozePulseIn.findIndexOfValue((String) objValue);
-            mDozePulseIn.setSummary(mDozePulseIn.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.DOZE_PULSE_DURATION_IN, dozePulseIn);
-        }
-        if (preference == mDozePulseVisible) {
-            int dozePulseVisible = Integer.parseInt((String)objValue);
-            int index = mDozePulseVisible.findIndexOfValue((String) objValue);
-            mDozePulseVisible.setSummary(mDozePulseVisible.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.DOZE_PULSE_DURATION_VISIBLE, dozePulseVisible);
-        }
-        if (preference == mDozePulseOut) {
-            int dozePulseOut = Integer.parseInt((String)objValue);
-            int index = mDozePulseOut.findIndexOfValue((String) objValue);
-            mDozePulseOut.setSummary(mDozePulseOut.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.DOZE_PULSE_DURATION_OUT, dozePulseOut);
-        }
-        if (preference == mDozeShakeThreshold) {
-            int accValue = Integer.parseInt((String)objValue);
-            if (accValue != mAccValue) {
-                mOldAccValue = mAccValue;
-                mAccValue = accValue;
-                showAccDialog();
-            }
-        }
-        if (preference == mDozeListMode) {
-            int dozeListMode = Integer.parseInt((String)objValue);
-            updateDozeListModeValue(dozeListMode);
-            int index = mDozeListMode.findIndexOfValue((String) objValue);
-            mDozeListMode.setSummary(mDozeListMode.getEntries()[index]);
-        }
-        if (preference == mDozeBrightness) {
-            mCurrentBrightness = (Integer) objValue;
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.SCREEN_BRIGHTNESS_DOZE, mCurrentBrightness);
-        }
-        return true;
-    }
-
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
-                        boolean enabled) {
-                    ArrayList<SearchIndexableResource> result =
-                            new ArrayList<SearchIndexableResource>();
-
-                    SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.ambient_settings;
-                    result.add(sir);
-
-                    return result;
-                }
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    ArrayList<String> result = new ArrayList<String>();
-                    if (!isDozeAvailable(context)) {
-                        result.add(KEY_DOZE);
-                        result.add(KEY_DOZE_LIST_MODE);
-                        result.add(KEY_DOZE_TIME_MODE);
-                        result.add(KEY_DOZE_OVERWRITE_VALUE);
-                        result.add(KEY_DOZE_PULSE_MODE);
-                        result.add(KEY_DOZE_PULSE_IN);
-                        result.add(KEY_DOZE_PULSE_VISIBLE);
-                        result.add(KEY_DOZE_PULSE_OUT);
-                        result.add(KEY_DOZE_SHAKE_THRESHOLD);
-                    } else {
-                       if (!isAccelerometerAvailable(context)) {
-                           result.add(KEY_DOZE_LIST_MODE);
-                           result.add(KEY_DOZE_SHAKE_THRESHOLD);
-                       }
-                       if (isAccelerometerAvailable(context)) {
-                           result.add(KEY_DOZE_PULSE_MODE);
-                       }
-                    }
-                    return result;
-                }
-            };
-}*/
diff --git a/src/org/omnirom/omnigears/ButtonBrightnessSettings.java b/src/org/omnirom/omnigears/ButtonBrightnessSettings.java
deleted file mode 100644
index ca8c3d0..0000000
--- a/src/org/omnirom/omnigears/ButtonBrightnessSettings.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- *  Copyright (C) 2014 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.omnirom.omnigears;
-
-import com.android.settings.SettingsPreferenceFragment;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.PowerManager;
-import android.os.IPowerManager;
-import android.os.ServiceManager;
-import android.support.v7.preference.CheckBoxPreference;
-import android.support.v7.preference.ListPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceChangeListener;
-import android.support.v7.preference.PreferenceCategory;
-import android.support.v7.preference.PreferenceScreen;
-import android.support.v7.preference.ListPreference;
-import android.support.v14.preference.SwitchPreference;
-import android.provider.Settings;
-import android.provider.SearchIndexableResource;
-import android.view.View;
-import android.util.Log;
-import android.app.AlertDialog;
-import android.text.TextWatcher;
-import android.text.Editable;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.SeekBar;
-import android.widget.TextView;
-
-import org.omnirom.omnigears.R;
-import org.omnirom.omnigears.preference.SeekBarPreference;
-
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-
-import java.util.List;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-public class ButtonBrightnessSettings extends SettingsPreferenceFragment implements
-        Preference.OnPreferenceChangeListener, Indexable {
-    private static final String TAG = "ButtonBrightnessSettings";
-
-    private static final String KEY_BUTTON_BACKLIGHT_ENABLE = "button_backlight_enable";
-    private static final String KEY_BUTTON_LINK_BRIGHTNESS = "button_link_brightness";
-    private static final String KEY_BUTTON_MANUAL_BRIGHTNESS_NEW = "button_manual_brightness_new";
-    private static final String KEY_BUTTON_TIMEOUT = "button_timeout";
-
-    private SwitchPreference mButtonBacklightEnable;
-    private CheckBoxPreference mLinkButtonBrightness;
-    private IPowerManager mPowerService;
-    private SeekBarPreference mButtonTimoutBar;
-    private SeekBarPreference mManualButtonBrightnessNew;
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsEvent.OMNI_SETTINGS;
-    }
-
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.button_brightness_settings);
-
-        PreferenceScreen prefSet = getPreferenceScreen();
-        ContentResolver resolver = getContentResolver();
-
-        mButtonBacklightEnable = (SwitchPreference) findPreference(KEY_BUTTON_BACKLIGHT_ENABLE);
-        mButtonBacklightEnable.setChecked(Settings.System.getInt(resolver,
-                Settings.System.CUSTOM_BUTTON_DISABLE_BRIGHTNESS, 0) == 0);
-
-        mLinkButtonBrightness = (CheckBoxPreference) findPreference(KEY_BUTTON_LINK_BRIGHTNESS);
-        mLinkButtonBrightness.setChecked(Settings.System.getInt(resolver,
-                Settings.System.CUSTOM_BUTTON_USE_SCREEN_BRIGHTNESS, 0) != 0);
-
-        mManualButtonBrightnessNew = (SeekBarPreference) findPreference(KEY_BUTTON_MANUAL_BRIGHTNESS_NEW);
-        final int customButtonBrightness = getResources().getInteger(
-                com.android.internal.R.integer.config_button_brightness_default);
-        final int currentBrightness = Settings.System.getInt(resolver,
-                Settings.System.CUSTOM_BUTTON_BRIGHTNESS, customButtonBrightness);
-        PowerManager pm = (PowerManager)getActivity().getSystemService(Context.POWER_SERVICE);
-        mManualButtonBrightnessNew.setMaxValue(pm.getMaximumScreenBrightnessSetting());
-        mManualButtonBrightnessNew.setValue(currentBrightness);
-        mManualButtonBrightnessNew.setOnPreferenceChangeListener(this);
-
-        mButtonTimoutBar = (SeekBarPreference) findPreference(KEY_BUTTON_TIMEOUT);
-        int currentTimeout = Settings.System.getInt(resolver,
-                        Settings.System.BUTTON_BACKLIGHT_TIMEOUT, 0);
-        mButtonTimoutBar.setValue(currentTimeout);
-        mButtonTimoutBar.setOnPreferenceChangeListener(this);
-
-        mPowerService = IPowerManager.Stub.asInterface(ServiceManager.getService("power"));
-    }
-
-    @Override
-    public boolean onPreferenceTreeClick(Preference preference) {
-        if (preference == mButtonBacklightEnable) {
-            boolean checked = ((SwitchPreference)preference).isChecked();
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.CUSTOM_BUTTON_DISABLE_BRIGHTNESS, checked ? 0 : 1);
-            return true;
-        } else if (preference == mLinkButtonBrightness) {
-            boolean checked = ((CheckBoxPreference)preference).isChecked();
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.CUSTOM_BUTTON_USE_SCREEN_BRIGHTNESS, checked ? 1 : 0);
-            return true;
-        }
-        return super.onPreferenceTreeClick(preference);
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object objValue) {
-        final String key = preference.getKey();
-
-        if (preference == mButtonTimoutBar) {
-            int buttonTimeout = (Integer) objValue;
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.BUTTON_BACKLIGHT_TIMEOUT, buttonTimeout);
-        } else if (preference == mManualButtonBrightnessNew) {
-            int buttonBrightness = (Integer) objValue;
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.CUSTOM_BUTTON_BRIGHTNESS, buttonBrightness);
-        } else {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * For Search.
-     */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-        new BaseSearchIndexProvider() {
-
-            @Override
-            public List<SearchIndexableResource> getXmlResourcesToIndex(
-                    Context context, boolean enabled) {
-                final SearchIndexableResource sir = new SearchIndexableResource(context);
-                sir.xmlResId = R.xml.button_brightness_settings;
-                return Arrays.asList(sir);
-            }
-	};
-}
-
diff --git a/src/org/omnirom/omnigears/ButtonSettings.java b/src/org/omnirom/omnigears/ButtonSettings.java
deleted file mode 100644
index b93c8b2..0000000
--- a/src/org/omnirom/omnigears/ButtonSettings.java
+++ /dev/null
@@ -1,961 +0,0 @@
-/*
- *  Copyright (C) 2013 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- *
-*/
-package org.omnirom.omnigears;
-
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.res.Resources;
-import android.content.Context;
-import android.media.AudioSystem;
-import android.os.Bundle;
-import android.os.Vibrator;
-import android.support.v7.preference.CheckBoxPreference;
-import android.support.v7.preference.ListPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceChangeListener;
-import android.support.v7.preference.PreferenceCategory;
-import android.support.v7.preference.PreferenceScreen;
-import android.support.v7.preference.ListPreference;
-import android.support.v14.preference.SwitchPreference;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.HashMap;
-
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.Utils;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.dashboard.SummaryLoader;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-import org.omnirom.omnigears.preference.SystemCheckBoxPreference;
-
-import static android.provider.Settings.System.VOLUME_BUTTON_WAKE;
-
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.internal.util.omni.OmniSwitchConstants;
-import com.android.internal.util.omni.PackageUtils;
-import com.android.internal.util.omni.DeviceUtils;
-
-public class ButtonSettings extends SettingsPreferenceFragment implements OnPreferenceChangeListener, Indexable {
-
-    private static final String CATEGORY_VOLUME = "button_volume_keys";
-    private static final String CATEGORY_KEYS = "button_keys";
-//    private static final String CATEGORY_BACK = "button_keys_back";
-//    private static final String CATEGORY_HOME = "button_keys_home";
-//    private static final String CATEGORY_MENU = "button_keys_menu";
-//    private static final String CATEGORY_ASSIST = "button_keys_assist";
-//    private static final String CATEGORY_APPSWITCH = "button_keys_appSwitch";
-
-    private static final String BUTTON_VOLUME_WAKE = "button_volume_wake_screen";
-//    private static final String BUTTON_HOME_WAKE = "button_home_wake_screen";
-//    private static final String BUTTON_HOME_ANSWERS_CALL = "button_home_answers_call";
-//    private static final String BUTTON_VOLUME_DEFAULT = "button_volume_default_screen";
-//    private static final String VOLUME_KEY_CURSOR_CONTROL = "volume_key_cursor_control";
-//    private static final String CATEGORY_HEADSETHOOK = "button_headsethook";
-//    private static final String BUTTON_HEADSETHOOK_LAUNCH_VOICE = "button_headsethook_launch_voice";
-
-//    private static final String KEYS_ENABLE_CUSTOM = "keys_enable_custom";
-//    private static final String KEYS_BACK_PRESS = "keys_back_press";
-//    private static final String KEYS_BACK_LONG_PRESS = "keys_back_long_press";
-//    private static final String KEYS_HOME_PRESS = "keys_home_press";
-//    private static final String KEYS_HOME_LONG_PRESS = "keys_home_long_press";
-//    private static final String KEYS_HOME_DOUBLE_TAP = "keys_home_double_tap";
-//    private static final String KEYS_MENU_PRESS = "keys_menu_press";
-//    private static final String KEYS_MENU_LONG_PRESS = "keys_menu_long_press";
-//    private static final String KEYS_ASSIST_PRESS = "keys_assist_press";
-//    private static final String KEYS_ASSIST_LONG_PRESS = "keys_assist_long_press";
-//    private static final String KEYS_APP_SWITCH_PRESS = "keys_app_switch_press";
-//    private static final String KEYS_APP_SWITCH_LONG_PRESS = "keys_app_switch_long_press";
-
-//    private static final String VIRTUAL_KEY_HAPTIC_FEEDBACK = "virtual_key_haptic_feedback";
-//    private static final String FORCE_SHOW_OVERFLOW_MENU = "force_show_overflow_menu";
-    private static final String KEYS_BRIGHTNESS_KEY = "button_brightness";
-    private static final String KEYS_SHOW_NAVBAR_KEY = "navigation_bar_show";
-    private static final String KEYS_DISABLE_HW_KEY = "hardware_keys_disable";
-    private static final String NAVIGATION_BAR_RECENTS_STYLE = "navbar_recents_style";
-    private static final String BUTTON_BACK_KILL_TIMEOUT = "button_back_kill_timeout";
-    private static final String LONG_PRESS_RECENTS_ACTION = "long_press_recents_action";
-    private static final String LONG_PRESS_HOME_ACTION = "long_press_home_action";
-
-    // Available custom actions to perform on a key press.
-//    private static final int ACTION_NOTHING = 0;
-//    private static final int ACTION_MENU = 1;
-//    private static final int ACTION_APP_SWITCH = 2;
-//    private static final int ACTION_SEARCH = 3;
-//    private static final int ACTION_VOICE_SEARCH = 4;
-//    private static final int ACTION_IN_APP_SEARCH = 5;
-//    private static final int ACTION_HOME = 6;
-//    private static final int ACTION_BACK = 7;
-//    private static final int ACTION_LAST_APP = 8;
-//    private static final int ACTION_KILL_APP = 9;
-//    private static final int ACTION_SLEEP = 10;
-    private static final int ACTION_OMNISWITCH = 11;
-
-    // Masks for checking presence of hardware keys.
-    // Must match values in frameworks/base/core/res/res/values/config.xml
-//    private static final int KEY_MASK_HOME = 0x01;
-//    private static final int KEY_MASK_BACK = 0x02;
-//    private static final int KEY_MASK_MENU = 0x04;
-//    private static final int KEY_MASK_ASSIST = 0x08;
-//    private static final int KEY_MASK_APP_SWITCH = 0x10;
-
-    private CheckBoxPreference mVolumeWake;
-//    private CheckBoxPreference mHomeWake;
-//    private CheckBoxPreference mHomeAnswerCall;
-//    private ListPreference mVolumeKeyCursorControl;
-    private SwitchPreference mEnableCustomBindings;
-//    private ListPreference mBackPressAction;
-//    private ListPreference mBackLongPressAction;
-//    private ListPreference mHomePressAction;
-//    private ListPreference mHomeLongPressAction;
-//    private ListPreference mHomeDoubleTapAction;
-//    private ListPreference mMenuPressAction;
-//    private ListPreference mMenuLongPressAction;
-//    private ListPreference mAssistPressAction;
-//    private ListPreference mAssistLongPressAction;
-//    private ListPreference mAppSwitchPressAction;
-//    private ListPreference mAppSwitchLongPressAction;
-    private Map<String, Integer> mKeySettings = new HashMap<String, Integer>();
-//    private ListPreference mVolumeDefault;
-//    private CheckBoxPreference mHeadsetHookLaunchVoice;
-//    private CheckBoxPreference mVirtualKeyHapticFeedback;
-//    private CheckBoxPreference mForceShowOverflowMenu;
-    private boolean mButtonBrightnessSupport;
-    private SwitchPreference mEnableNavBar;
-    private SwitchPreference mDisabkeHWKeys;
-    private PreferenceScreen mButtonBrightness;
-//    private PreferenceCategory mKeysBackCategory;
-//    private PreferenceCategory mKeysHomeCategory;
-//    private PreferenceCategory mKeysMenuCategory;
-//    private PreferenceCategory mKeysAppSwitchCategory;
-//    private PreferenceCategory mKeysAssistCategory;
-    private ListPreference mNavbarRecentsStyle;
-    private ListPreference mBackKillTimeout;
-    private ListPreference mLongPressRecentsAction;
-    private ListPreference mLongPressHomeAction;
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsEvent.OMNI_SETTINGS;
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        addPreferencesFromResource(R.xml.button_settings);
-
-        final ContentResolver resolver = getContentResolver();
-        final PreferenceScreen prefScreen = getPreferenceScreen();
-        final Resources res = getResources();
-//        final boolean mPersistHomeWakeSupport = res.getBoolean(
-//            com.android.internal.R.bool.config_persistHomeWakeSupport);
-
-        final PreferenceCategory volumeCategory =
-                (PreferenceCategory) prefScreen.findPreference(CATEGORY_VOLUME);
-
-        mButtonBrightnessSupport = res.getBoolean(com.android.internal.R.bool.config_button_brightness_support);
-
-        if (hasVolumeRocker()) {
-            mVolumeWake = (CheckBoxPreference) findPreference(BUTTON_VOLUME_WAKE);
-//            mVolumeDefault = (ListPreference) findPreference(BUTTON_VOLUME_DEFAULT);
-            if (!res.getBoolean(R.bool.config_show_volumeRockerWake)) {
-                volumeCategory.removePreference(mVolumeWake);
-            } else {
-                mVolumeWake.setChecked(Settings.System.getInt(resolver,
-                    Settings.System.VOLUME_BUTTON_WAKE, 0) != 0);
-            }
-/*
-//          int currentDefault = Settings.System.getInt(resolver, Settings.System.VOLUME_KEYS_DEFAULT,
-//                  Utils.isVoiceCapable(getActivity()) ? AudioSystem.STREAM_RING : AudioSystem.STREAM_MUSIC);
-//
-//          if (!Utils.isVoiceCapable(getActivity())) {
-//              removeListEntry(mVolumeDefault, Integer.toString(AudioSystem.STREAM_RING));
-//          }
-//
-//          mVolumeDefault.setValue(Integer.toString(currentDefault));
-//          mVolumeDefault.setOnPreferenceChangeListener(this);
-*/
-
-//          mVolumeKeyCursorControl = (ListPreference) findPreference(VOLUME_KEY_CURSOR_CONTROL);
-//          if (mVolumeKeyCursorControl != null) {
-//              mVolumeKeyCursorControl.setValue(Integer.toString(Settings.System.getInt(
-//                      getContentResolver(), Settings.System.VOLUME_KEY_CURSOR_CONTROL, 0)));
-//              mVolumeKeyCursorControl.setSummary(mVolumeKeyCursorControl.getEntry());
-//              mVolumeKeyCursorControl.setOnPreferenceChangeListener(this);
-//          }
-//
-        } else {
-            prefScreen.removePreference(volumeCategory);
-        }
-
-        final int deviceKeys = res.getInteger(
-                com.android.internal.R.integer.config_deviceHardwareKeys);
-        final PreferenceCategory keysCategory =
-                (PreferenceCategory) prefScreen.findPreference(CATEGORY_KEYS);
-        /*final boolean hasBackKey = false; //(deviceKeys & KEY_MASK_BACK) != 0;
-        final boolean hasHomeKey = false; //(deviceKeys & KEY_MASK_HOME) != 0;
-        final boolean hasMenuKey = false; //(deviceKeys & KEY_MASK_MENU) != 0;
-        final boolean hasAssistKey = false; //(deviceKeys & KEY_MASK_ASSIST) != 0;
-        final boolean hasAppSwitchKey = false; //(deviceKeys & KEY_MASK_APP_SWITCH) != 0;
-
-        mKeysBackCategory =
-                (PreferenceCategory) prefScreen.findPreference(CATEGORY_BACK);
-        mKeysHomeCategory =
-                (PreferenceCategory) prefScreen.findPreference(CATEGORY_HOME);
-        mKeysMenuCategory =
-                (PreferenceCategory) prefScreen.findPreference(CATEGORY_MENU);
-        mKeysAssistCategory =
-                (PreferenceCategory) prefScreen.findPreference(CATEGORY_ASSIST);
-        mKeysAppSwitchCategory =
-                (PreferenceCategory) prefScreen.findPreference(CATEGORY_APPSWITCH);*/
-
-        if (deviceKeys == 0) {
-            prefScreen.removePreference(keysCategory);
-            /*prefScreen.removePreference(mKeysBackCategory);
-            prefScreen.removePreference(mKeysHomeCategory);
-            prefScreen.removePreference(mKeysMenuCategory);
-            prefScreen.removePreference(mKeysAssistCategory);
-            prefScreen.removePreference(mKeysAppSwitchCategory);*/
-        } else {
-            /*mEnableCustomBindings = (SwitchPreference) prefScreen.findPreference(
-                    KEYS_ENABLE_CUSTOM);
-            mBackPressAction = (ListPreference) prefScreen.findPreference(
-                    KEYS_BACK_PRESS);
-            mBackLongPressAction = (ListPreference) prefScreen.findPreference(
-                    KEYS_BACK_LONG_PRESS);
-            mHomePressAction = (ListPreference) prefScreen.findPreference(
-                    KEYS_HOME_PRESS);
-            mHomeLongPressAction = (ListPreference) prefScreen.findPreference(
-                    KEYS_HOME_LONG_PRESS);
-            mHomeDoubleTapAction = (ListPreference) prefScreen.findPreference(
-                    KEYS_HOME_DOUBLE_TAP);
-            mMenuPressAction = (ListPreference) prefScreen.findPreference(
-                    KEYS_MENU_PRESS);
-            mMenuLongPressAction = (ListPreference) prefScreen.findPreference(
-                    KEYS_MENU_LONG_PRESS);
-            mAssistPressAction = (ListPreference) prefScreen.findPreference(
-                    KEYS_ASSIST_PRESS);
-            mAssistLongPressAction = (ListPreference) prefScreen.findPreference(
-                    KEYS_ASSIST_LONG_PRESS);
-            mAppSwitchPressAction = (ListPreference) prefScreen.findPreference(
-                    KEYS_APP_SWITCH_PRESS);
-            mAppSwitchLongPressAction = (ListPreference) prefScreen.findPreference(
-                    KEYS_APP_SWITCH_LONG_PRESS);
-//            mVirtualKeyHapticFeedback = (CheckBoxPreference) prefScreen.findPreference(
-//                    VIRTUAL_KEY_HAPTIC_FEEDBACK);
-//            mForceShowOverflowMenu = (CheckBoxPreference) prefScreen.findPreference(
-//                    FORCE_SHOW_OVERFLOW_MENU);
-
-
-            /*if (hasBackKey) {
-                int backPressAction = Settings.System.getInt(resolver,
-                        Settings.System.KEY_BACK_ACTION, ACTION_BACK);
-
-                mBackPressAction.setValue(Integer.toString(backPressAction));
-                mBackPressAction.setSummary(mBackPressAction.getEntry());
-                mBackPressAction.setOnPreferenceChangeListener(this);
-
-                mKeySettings.put(Settings.System.KEY_BACK_ACTION, backPressAction);
-
-                int backLongPressAction = Settings.System.getInt(resolver,
-                        Settings.System.KEY_BACK_LONG_PRESS_ACTION, ACTION_NOTHING);
-
-                mBackLongPressAction.setValue(Integer.toString(backLongPressAction));
-                mBackLongPressAction.setSummary(mBackLongPressAction.getEntry());
-                mBackLongPressAction.setOnPreferenceChangeListener(this);
-
-                mKeySettings.put(Settings.System.KEY_BACK_LONG_PRESS_ACTION, backLongPressAction);
-            } else {
-                prefScreen.removePreference(mKeysBackCategory);
-            }
-
-            if (hasHomeKey) {
-                int homePressAction = Settings.System.getInt(resolver,
-                        Settings.System.KEY_HOME_ACTION, ACTION_HOME);
-
-                mHomePressAction.setValue(Integer.toString(homePressAction));
-                mHomePressAction.setSummary(mHomePressAction.getEntry());
-                mHomePressAction.setOnPreferenceChangeListener(this);
-
-                mKeySettings.put(Settings.System.KEY_HOME_ACTION, homePressAction);
-
-                int homeLongPressAction;
-                int longPressOnHomeBehavior = res.getInteger(
-                        com.android.internal.R.integer.config_longPressOnHomeBehavior);
-
-                if (longPressOnHomeBehavior == 1) {
-                    longPressOnHomeBehavior = ACTION_APP_SWITCH;
-                } else if (longPressOnHomeBehavior == 2) {
-                    longPressOnHomeBehavior = ACTION_SEARCH;
-                } else {
-                    longPressOnHomeBehavior = ACTION_NOTHING;
-                }
-
-                if (hasAppSwitchKey) {
-                    homeLongPressAction = Settings.System.getInt(resolver,
-                            Settings.System.KEY_HOME_LONG_PRESS_ACTION, ACTION_NOTHING);
-                } else {
-                    int defaultAction = ACTION_NOTHING;
-                    homeLongPressAction = Settings.System.getInt(resolver,
-                            Settings.System.KEY_HOME_LONG_PRESS_ACTION, longPressOnHomeBehavior);
-                }
-                mHomeLongPressAction.setValue(Integer.toString(homeLongPressAction));
-                mHomeLongPressAction.setSummary(mHomeLongPressAction.getEntry());
-                mHomeLongPressAction.setOnPreferenceChangeListener(this);
-
-                mKeySettings.put(Settings.System.KEY_HOME_LONG_PRESS_ACTION, homeLongPressAction);
-
-                int doubleTapOnHomeBehavior = res.getInteger(
-                        com.android.internal.R.integer.config_doubleTapOnHomeBehavior);
-
-                int homeDoubleTapAction = Settings.System.getInt(resolver,
-                            Settings.System.KEY_HOME_DOUBLE_TAP_ACTION,
-                            doubleTapOnHomeBehavior == 1 ? ACTION_APP_SWITCH : ACTION_NOTHING);
-
-                mHomeDoubleTapAction.setValue(Integer.toString(homeDoubleTapAction));
-                mHomeDoubleTapAction.setSummary(mHomeDoubleTapAction.getEntry());
-                mHomeDoubleTapAction.setOnPreferenceChangeListener(this);
-
-                mKeySettings.put(Settings.System.KEY_HOME_DOUBLE_TAP_ACTION, homeDoubleTapAction);
-
-                mHomeWake = (CheckBoxPreference) findPreference(BUTTON_HOME_WAKE);
-                if (!res.getBoolean(R.bool.config_show_homeWake)) {
-                    mKeysHomeCategory.removePreference(mHomeWake);
-                } else {
-                    mHomeWake.setChecked(Settings.System.getInt(resolver,
-                        Settings.System.HOME_BUTTON_WAKE,
-                        (mPersistHomeWakeSupport ? 1 : 0)) != 0);
-                }
-
-                mHomeAnswerCall = (CheckBoxPreference) findPreference(BUTTON_HOME_ANSWERS_CALL);
-                if (!Utils.isVoiceCapable(getActivity())) {
-                    mKeysHomeCategory.removePreference(mHomeAnswerCall);
-                } else {
-                    mHomeAnswerCall.setChecked(Settings.System.getInt(resolver,
-                        Settings.System.HOME_BUTTON_ANSWER, 0) != 0);
-                }
-            } else {
-                prefScreen.removePreference(mKeysHomeCategory);
-            }
-
-            if (hasMenuKey) {
-                int menuPressAction = Settings.System.getInt(resolver,
-                        Settings.System.KEY_MENU_ACTION, ACTION_MENU);
-                mMenuPressAction.setValue(Integer.toString(menuPressAction));
-                mMenuPressAction.setSummary(mMenuPressAction.getEntry());
-                mMenuPressAction.setOnPreferenceChangeListener(this);
-
-                mKeySettings.put(Settings.System.KEY_MENU_ACTION, menuPressAction);
-
-                int menuLongPressAction = ACTION_NOTHING;
-                if (!hasAssistKey) {
-                    menuLongPressAction = ACTION_SEARCH;
-                }
-
-                menuLongPressAction = Settings.System.getInt(resolver,
-                            Settings.System.KEY_MENU_LONG_PRESS_ACTION, menuLongPressAction);
-
-                mMenuLongPressAction.setValue(Integer.toString(menuLongPressAction));
-                mMenuLongPressAction.setSummary(mMenuLongPressAction.getEntry());
-                mMenuLongPressAction.setOnPreferenceChangeListener(this);
-
-                mKeySettings.put(Settings.System.KEY_MENU_LONG_PRESS_ACTION, menuLongPressAction);
-            } else {
-                prefScreen.removePreference(mKeysMenuCategory);
-            }
-
-            if (hasAssistKey) {
-                int assistPressAction = Settings.System.getInt(resolver,
-                        Settings.System.KEY_ASSIST_ACTION, ACTION_SEARCH);
-                mAssistPressAction.setValue(Integer.toString(assistPressAction));
-                mAssistPressAction.setSummary(mAssistPressAction.getEntry());
-                mAssistPressAction.setOnPreferenceChangeListener(this);
-
-                mKeySettings.put(Settings.System.KEY_ASSIST_ACTION, assistPressAction);
-
-                int assistLongPressAction = Settings.System.getInt(resolver,
-                        Settings.System.KEY_ASSIST_LONG_PRESS_ACTION, ACTION_VOICE_SEARCH);
-                mAssistLongPressAction.setValue(Integer.toString(assistLongPressAction));
-                mAssistLongPressAction.setSummary(mAssistLongPressAction.getEntry());
-                mAssistLongPressAction.setOnPreferenceChangeListener(this);
-
-                mKeySettings.put(Settings.System.KEY_ASSIST_LONG_PRESS_ACTION, assistLongPressAction);
-            } else {
-                prefScreen.removePreference(mKeysAssistCategory);
-            }
-
-            if (hasAppSwitchKey) {
-                int appSwitchPressAction = Settings.System.getInt(resolver,
-                        Settings.System.KEY_APP_SWITCH_ACTION, ACTION_APP_SWITCH);
-                mAppSwitchPressAction.setValue(Integer.toString(appSwitchPressAction));
-                mAppSwitchPressAction.setSummary(mAppSwitchPressAction.getEntry());
-                mAppSwitchPressAction.setOnPreferenceChangeListener(this);
-
-                mKeySettings.put(Settings.System.KEY_APP_SWITCH_ACTION, appSwitchPressAction);
-
-                int appSwitchLongPressAction = Settings.System.getInt(resolver,
-                        Settings.System.KEY_APP_SWITCH_LONG_PRESS_ACTION, ACTION_NOTHING);
-                mAppSwitchLongPressAction.setValue(Integer.toString(appSwitchLongPressAction));
-                mAppSwitchLongPressAction.setSummary(mAppSwitchLongPressAction.getEntry());
-                mAppSwitchLongPressAction.setOnPreferenceChangeListener(this);
-
-                mKeySettings.put(Settings.System.KEY_APP_SWITCH_LONG_PRESS_ACTION, appSwitchLongPressAction);
-            } else {
-                prefScreen.removePreference(mKeysAppSwitchCategory);
-            }
-
-            if (mEnableCustomBindings != null) {
-                mEnableCustomBindings.setChecked((Settings.System.getInt(resolver,
-                        Settings.System.HARDWARE_KEY_REBINDING, 0) == 1));
-                mEnableCustomBindings.setOnPreferenceChangeListener(this);
-            }
-
-//            Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
-//            if (vibrator == null || !vibrator.hasVibrator()) {
-//                removePreference(VIRTUAL_KEY_HAPTIC_FEEDBACK);
-//            } else {
-//                mVirtualKeyHapticFeedback.setChecked(Settings.System.getInt(resolver,
-//                        Settings.System.VIRTUAL_KEYS_HAPTIC_FEEDBACK, 1) == 1);
-//            }
-
-
-            updateDisableHWKeyEnablement(harwareKeysDisable); */
-
-
-            mButtonBrightness = (PreferenceScreen) prefScreen.findPreference(
-                KEYS_BRIGHTNESS_KEY);
-            if (!mButtonBrightnessSupport) {
-                keysCategory.removePreference(mButtonBrightness);
-            }
-
-            mEnableNavBar = (SwitchPreference) prefScreen.findPreference(
-                   KEYS_SHOW_NAVBAR_KEY);
-
-            mDisabkeHWKeys = (SwitchPreference) prefScreen.findPreference(
-                    KEYS_DISABLE_HW_KEY);
-
-            boolean showNavBarDefault = DeviceUtils.deviceSupportNavigationBar(getActivity());
-            boolean showNavBar = Settings.System.getInt(resolver,
-                        Settings.System.NAVIGATION_BAR_SHOW, showNavBarDefault ? 1:0) == 1;
-            mEnableNavBar.setChecked(showNavBar);
-
-            boolean harwareKeysDisable = Settings.System.getInt(resolver,
-                        Settings.System.HARDWARE_KEYS_DISABLE, 0) == 1;
-            mDisabkeHWKeys.setChecked(harwareKeysDisable);
-        }
-
-        mNavbarRecentsStyle = (ListPreference) findPreference(NAVIGATION_BAR_RECENTS_STYLE);
-        int recentsStyle = Settings.System.getInt(resolver,
-                Settings.System.NAVIGATION_BAR_RECENTS, 0);
-
-        mNavbarRecentsStyle.setValue(Integer.toString(recentsStyle));
-        mNavbarRecentsStyle.setSummary(mNavbarRecentsStyle.getEntry());
-        mNavbarRecentsStyle.setOnPreferenceChangeListener(this);
-
-        mLongPressRecentsAction = (ListPreference) findPreference(LONG_PRESS_RECENTS_ACTION);
-        int longPressRecentsAction = Settings.System.getInt(resolver,
-                Settings.System.BUTTON_LONG_PRESS_RECENTS, 0);
-
-        mLongPressRecentsAction.setValue(Integer.toString(longPressRecentsAction));
-        mLongPressRecentsAction.setSummary(mLongPressRecentsAction.getEntry());
-        mLongPressRecentsAction.setOnPreferenceChangeListener(this);
-
-        // for navbar devices default is always assist LONG_PRESS_HOME_ASSIST = 2
-        int defaultLongPressOnHomeBehavior = (deviceKeys == 0) ? 2 : res.getInteger(com.android.internal.R.integer.config_longPressOnHomeBehavior);
-        mLongPressHomeAction = (ListPreference) findPreference(LONG_PRESS_HOME_ACTION);
-        int longPressHomeAction = Settings.System.getInt(resolver,
-                Settings.System.BUTTON_LONG_PRESS_HOME, defaultLongPressOnHomeBehavior);
-
-        mLongPressHomeAction.setValue(Integer.toString(longPressHomeAction));
-        mLongPressHomeAction.setSummary(mLongPressHomeAction.getEntry());
-        mLongPressHomeAction.setOnPreferenceChangeListener(this);
-
-        mBackKillTimeout = (ListPreference) findPreference(BUTTON_BACK_KILL_TIMEOUT);
-        final int backKillTimeoutDefault = res.getInteger(com.android.internal.R.integer.config_backKillTimeout);
-        final int backKillTimeout = Settings.System.getInt(resolver,
-                Settings.System.BUTTON_BACK_KILL_TIMEOUT, backKillTimeoutDefault);
-
-        mBackKillTimeout.setValue(Integer.toString(backKillTimeout));
-        mBackKillTimeout.setSummary(mBackKillTimeout.getEntry());
-        mBackKillTimeout.setOnPreferenceChangeListener(this);
-
-//        final PreferenceCategory headsethookCategory =
-//                (PreferenceCategory) prefScreen.findPreference(CATEGORY_HEADSETHOOK);
-
-//        mHeadsetHookLaunchVoice = (CheckBoxPreference) findPreference(BUTTON_HEADSETHOOK_LAUNCH_VOICE);
-//        mHeadsetHookLaunchVoice.setChecked(Settings.System.getInt(resolver,
-//                Settings.System.HEADSETHOOK_LAUNCH_VOICE, 1) == 1);
-    }
-
-    @Override
-    public boolean onPreferenceTreeClick(Preference preference) {
-        if (preference == mVolumeWake) {
-            boolean checked = ((CheckBoxPreference)preference).isChecked();
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.VOLUME_BUTTON_WAKE, checked ? 1:0);
-            return true;
-//        else if (preference == mHeadsetHookLaunchVoice) {
-//            boolean checked = ((CheckBoxPreference)preference).isChecked();
-//            Settings.System.putInt(getContentResolver(),
-//                    Settings.System.HEADSETHOOK_LAUNCH_VOICE, checked ? 1:0);
-//
-//            return true;
-//        } else if (preference == mVirtualKeyHapticFeedback) {
-//            boolean checked = ((CheckBoxPreference)preference).isChecked();
-//            Settings.System.putInt(getContentResolver(),
-//                    Settings.System.VIRTUAL_KEYS_HAPTIC_FEEDBACK, checked ? 1:0);
-//            return true;
-//        } else if (preference == mForceShowOverflowMenu) {
-//            boolean checked = ((CheckBoxPreference)preference).isChecked();
-//            Settings.System.putInt(getContentResolver(),
-//                    Settings.System.FORCE_SHOW_OVERFLOW_MENU, checked ? 1:0);
-//            return true;
-        }  else if (preference == mEnableNavBar) {
-            boolean checked = ((SwitchPreference)preference).isChecked();
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.NAVIGATION_BAR_SHOW, checked ? 1:0);
-            // remove hw button disable if we disable navbar
-            if (!checked) {
-                Settings.System.putInt(getContentResolver(),
-                        Settings.System.HARDWARE_KEYS_DISABLE, 0);
-                mDisabkeHWKeys.setChecked(false);
-            }
-            return true;
-        } else if (preference == mDisabkeHWKeys) {
-            boolean checked = ((SwitchPreference)preference).isChecked();
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.HARDWARE_KEYS_DISABLE, checked ? 1:0);
-            //updateDisableHWKeyEnablement(checked);
-            return true;
-          }
-/*        } else if (preference == mHomeWake) {
-            boolean checked = ((CheckBoxPreference)preference).isChecked();
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.HOME_BUTTON_WAKE, checked ? 1:0);
-            return true;
-        } else if (preference == mHomeAnswerCall) {
-            boolean checked = ((CheckBoxPreference)preference).isChecked();
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.HOME_BUTTON_ANSWER, checked ? 1:0);
-            return true;
-        }
-
-*/
-        return super.onPreferenceTreeClick(preference);
-    }
-
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        if (preference == mEnableCustomBindings) {
-//            boolean value = (Boolean) newValue;
-//            Settings.System.putInt(getContentResolver(), Settings.System.HARDWARE_KEY_REBINDING,
-//                    value ? 1 : 0);
-//            boolean harwareKeysDisable = Settings.System.getInt(getContentResolver(),
-//                    Settings.System.HARDWARE_KEYS_DISABLE, 0) == 1;
-//            updateDisableHWKeyEnablement(harwareKeysDisable);
-            return true;
-//        } else if (preference == mVolumeKeyCursorControl) {
-//            String volumeKeyCursorControl = (String) newValue;
-//            int val = Integer.parseInt(volumeKeyCursorControl);
-//            Settings.System.putInt(getContentResolver(),
-//                    Settings.System.VOLUME_KEY_CURSOR_CONTROL, val);
-//            int index = mVolumeKeyCursorControl.findIndexOfValue(volumeKeyCursorControl);
-//            mVolumeKeyCursorControl.setSummary(mVolumeKeyCursorControl.getEntries()[index]);
-//            return true;
-/*        } else if (preference == mBackPressAction) {
-            int value = Integer.valueOf((String) newValue);
-            int index = mBackPressAction.findIndexOfValue((String) newValue);
-            mBackPressAction.setSummary(
-                    mBackPressAction.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.KEY_BACK_ACTION, value);
-            mKeySettings.put(Settings.System.KEY_BACK_ACTION, value);
-            checkForHomeKey();
-            checkForOmniSwitchRecents();
-            return true;
-        } else if (preference == mBackLongPressAction) {
-            int value = Integer.valueOf((String) newValue);
-            int index = mBackLongPressAction.findIndexOfValue((String) newValue);
-            mBackLongPressAction.setSummary(
-                    mBackLongPressAction.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.KEY_BACK_LONG_PRESS_ACTION, value);
-            mKeySettings.put(Settings.System.KEY_BACK_LONG_PRESS_ACTION, value);
-            checkForHomeKey();
-            checkForOmniSwitchRecents();
-            return true;
-        } else if (preference == mHomePressAction) {
-            int value = Integer.valueOf((String) newValue);
-            int index = mHomePressAction.findIndexOfValue((String) newValue);
-            mHomePressAction.setSummary(
-                    mHomePressAction.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.KEY_HOME_ACTION, value);
-            mKeySettings.put(Settings.System.KEY_HOME_ACTION, value);
-            checkForHomeKey();
-            checkForOmniSwitchRecents();
-            return true;
-        } else if (preference == mHomeLongPressAction) {
-            int value = Integer.valueOf((String) newValue);
-            int index = mHomeLongPressAction.findIndexOfValue((String) newValue);
-            mHomeLongPressAction.setSummary(
-                    mHomeLongPressAction.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.KEY_HOME_LONG_PRESS_ACTION, value);
-            mKeySettings.put(Settings.System.KEY_HOME_LONG_PRESS_ACTION, value);
-            checkForHomeKey();
-            checkForOmniSwitchRecents();
-            return true;
-        } else if (preference == mHomeDoubleTapAction) {
-            int value = Integer.valueOf((String) newValue);
-            int index = mHomeDoubleTapAction.findIndexOfValue((String) newValue);
-            mHomeDoubleTapAction.setSummary(
-                    mHomeDoubleTapAction.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.KEY_HOME_DOUBLE_TAP_ACTION, value);
-            mKeySettings.put(Settings.System.KEY_HOME_DOUBLE_TAP_ACTION, value);
-            checkForHomeKey();
-            checkForOmniSwitchRecents();
-            return true;
-        } else if (preference == mMenuPressAction) {
-            int value = Integer.valueOf((String) newValue);
-            int index = mMenuPressAction.findIndexOfValue((String) newValue);
-            mMenuPressAction.setSummary(
-                    mMenuPressAction.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.KEY_MENU_ACTION, value);
-            mKeySettings.put(Settings.System.KEY_MENU_ACTION, value);
-            checkForHomeKey();
-            checkForOmniSwitchRecents();
-            return true;
-        } else if (preference == mMenuLongPressAction) {
-            int value = Integer.valueOf((String) newValue);
-            int index = mMenuLongPressAction.findIndexOfValue((String) newValue);
-            mMenuLongPressAction.setSummary(
-                    mMenuLongPressAction.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.KEY_MENU_LONG_PRESS_ACTION, value);
-            mKeySettings.put(Settings.System.KEY_MENU_LONG_PRESS_ACTION, value);
-            checkForHomeKey();
-            checkForOmniSwitchRecents();
-            return true;
-        } else if (preference == mAssistPressAction) {
-            int value = Integer.valueOf((String) newValue);
-            int index = mAssistPressAction.findIndexOfValue((String) newValue);
-            mAssistPressAction.setSummary(
-                    mAssistPressAction.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.KEY_ASSIST_ACTION, value);
-            mKeySettings.put(Settings.System.KEY_ASSIST_ACTION, value);
-            checkForHomeKey();
-            checkForOmniSwitchRecents();
-            return true;
-        } else if (preference == mAssistLongPressAction) {
-            int value = Integer.valueOf((String) newValue);
-            int index = mAssistLongPressAction.findIndexOfValue((String) newValue);
-            mAssistLongPressAction.setSummary(
-                    mAssistLongPressAction.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.KEY_ASSIST_LONG_PRESS_ACTION, value);
-            mKeySettings.put(Settings.System.KEY_ASSIST_LONG_PRESS_ACTION, value);
-            checkForHomeKey();
-            checkForOmniSwitchRecents();
-            return true;
-        } else if (preference == mAppSwitchPressAction) {
-            int value = Integer.valueOf((String) newValue);
-            int index = mAppSwitchPressAction.findIndexOfValue((String) newValue);
-            mAppSwitchPressAction.setSummary(
-                    mAppSwitchPressAction.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.KEY_APP_SWITCH_ACTION, value);
-            mKeySettings.put(Settings.System.KEY_APP_SWITCH_ACTION, value);
-            checkForHomeKey();
-            checkForOmniSwitchRecents();
-            return true;
-        } else if (preference == mAppSwitchLongPressAction) {
-            int value = Integer.valueOf((String) newValue);
-            int index = mAppSwitchLongPressAction.findIndexOfValue((String) newValue);
-            mAppSwitchLongPressAction.setSummary(
-                    mAppSwitchLongPressAction.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.KEY_APP_SWITCH_LONG_PRESS_ACTION, value);
-            mKeySettings.put(Settings.System.KEY_APP_SWITCH_LONG_PRESS_ACTION, value);
-            checkForHomeKey();
-            checkForOmniSwitchRecents();
-            return true;
-//        } else if (preference == mVolumeDefault) {
-//            int value = Integer.valueOf((String) newValue);
-//            Settings.System.putInt(getContentResolver(), Settings.System.VOLUME_KEYS_DEFAULT, value);
-//            return true; */
-        } else if (preference == mNavbarRecentsStyle) {
-            int value = Integer.valueOf((String) newValue);
-            if (value == 1) {
-                if (!isOmniSwitchInstalled()){
-                    doOmniSwitchUnavail();
-                } else if (!OmniSwitchConstants.isOmniSwitchRunning(getActivity())) {
-                    doOmniSwitchConfig();
-                }
-            }
-            int index = mNavbarRecentsStyle.findIndexOfValue((String) newValue);
-            mNavbarRecentsStyle.setSummary(mNavbarRecentsStyle.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(), Settings.System.NAVIGATION_BAR_RECENTS, value);
-            return true;
-        } else if (preference == mBackKillTimeout) {
-            int value = Integer.valueOf((String) newValue);
-            int index = mBackKillTimeout.findIndexOfValue((String) newValue);
-            mBackKillTimeout.setSummary(mBackKillTimeout.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(), Settings.System.BUTTON_BACK_KILL_TIMEOUT, value);
-            return true;
-        } else if (preference == mLongPressRecentsAction) {
-            int value = Integer.valueOf((String) newValue);
-            int index = mLongPressRecentsAction.findIndexOfValue((String) newValue);
-            mLongPressRecentsAction.setSummary(mLongPressRecentsAction.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(), Settings.System.BUTTON_LONG_PRESS_RECENTS, value);
-            return true;
-        } else if (preference == mLongPressHomeAction) {
-            int value = Integer.valueOf((String) newValue);
-            int index = mLongPressHomeAction.findIndexOfValue((String) newValue);
-            mLongPressHomeAction.setSummary(mLongPressHomeAction.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(), Settings.System.BUTTON_LONG_PRESS_HOME, value);
-            return true;
-        }
-        return false;
-    }
-
-    private boolean hasVolumeRocker() {
-        return getActivity().getResources().getBoolean(R.bool.config_has_volume_rocker);
-    }
-/*
-
-    private boolean hasHomeKey() {
-        Iterator<Integer> nextAction = mKeySettings.values().iterator();
-        while (nextAction.hasNext()) {
-            int action = nextAction.next();
-            if (action == ACTION_HOME) {
-                return true;
-            }
-        }
-        return false;
-    }
-*/
-    private boolean hasOmniSwitchKey() {
-        Iterator<Integer> nextAction = mKeySettings.values().iterator();
-        while (nextAction.hasNext()) {
-            int action = nextAction.next();
-            if (action == ACTION_OMNISWITCH) {
-                return true;
-            }
-        }
-        return false;
-    }
-/*
-    private void checkForHomeKey() {
-        if (!hasHomeKey()) {
-            AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
-            alertDialogBuilder.setTitle(R.string.dialog_no_home_key_title);
-            alertDialogBuilder
-                .setMessage(R.string.no_home_key)
-                .setCancelable(false)
-                .setPositiveButton(R.string.ok,new DialogInterface.OnClickListener() {
-                    public void onClick(DialogInterface dialog,int id) {
-                    }
-                  });
-            AlertDialog alertDialog = alertDialogBuilder.create();
-            alertDialog.show();
-        }
-    }
-*/
-    private void checkForOmniSwitchRecents() {
-        if (hasOmniSwitchKey()) {
-            if (!isOmniSwitchInstalled()){
-                doOmniSwitchUnavail();
-            } else if (!OmniSwitchConstants.isOmniSwitchRunning(getActivity())) {
-                doOmniSwitchConfig();
-            }
-        }
-    }
-
-//    public void removeListEntry(ListPreference list, String valuetoRemove) {
-//        ArrayList<CharSequence> entries = new ArrayList<CharSequence>();
-//        ArrayList<CharSequence> values = new ArrayList<CharSequence>();
-//
-//        for (int i = 0; i < list.getEntryValues().length; i++) {
-//            if (list.getEntryValues()[i].toString().equals(valuetoRemove)) {
-//                continue;
-//            } else {
-//                entries.add(list.getEntries()[i]);
-//                values.add(list.getEntryValues()[i]);
-//            }
-//        }
-//
-//        list.setEntries(entries.toArray(new CharSequence[entries.size()]));
-//        list.setEntryValues(values.toArray(new CharSequence[values.size()]));
-//    }
-
-    private void updateDisableHWKeyEnablement(boolean harwareKeysDisable) {
-//        boolean enableHWKeyRebinding = Settings.System.getInt(getContentResolver(),
-//                    Settings.System.HARDWARE_KEY_REBINDING, 0) == 1;
-
-//        mVirtualKeyHapticFeedback.setEnabled(!harwareKeysDisable);
-//        mForceShowOverflowMenu.setEnabled(!harwareKeysDisable);
-
-          mEnableCustomBindings.setEnabled(!harwareKeysDisable);
-          mButtonBrightness.setEnabled(!harwareKeysDisable);
-//        mKeysHomeCategory.setEnabled(!harwareKeysDisable && enableHWKeyRebinding);
-//        mKeysBackCategory.setEnabled(!harwareKeysDisable && enableHWKeyRebinding);
-//        mKeysMenuCategory.setEnabled(!harwareKeysDisable && enableHWKeyRebinding);
-//        mKeysAppSwitchCategory.setEnabled(!harwareKeysDisable && enableHWKeyRebinding);
-//        mKeysAssistCategory.setEnabled(!harwareKeysDisable && enableHWKeyRebinding);
-    }
-
-    private void doOmniSwitchConfig() {
-        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
-        alertDialogBuilder.setTitle(R.string.omniswitch_title);
-        alertDialogBuilder.setMessage(R.string.omniswitch_dialog_running_new)
-            .setPositiveButton(R.string.omniswitch_settings, new DialogInterface.OnClickListener() {
-                public void onClick(DialogInterface dialog,int id) {
-                    startActivity(OmniSwitchConstants.INTENT_LAUNCH_APP);
-                }
-            });
-        AlertDialog alertDialog = alertDialogBuilder.create();
-        alertDialog.show();
-    }
-
-    private void doOmniSwitchUnavail() {
-        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
-        alertDialogBuilder.setTitle(R.string.omniswitch_title);
-        alertDialogBuilder.setMessage(R.string.omniswitch_dialog_unavail);
-        AlertDialog alertDialog = alertDialogBuilder.create();
-        alertDialog.show();
-    }
-
-    private boolean isOmniSwitchInstalled() {
-        return PackageUtils.isAvailableApp(OmniSwitchConstants.APP_PACKAGE_NAME, getActivity());
-    }
-
-
-    private static class SummaryProvider implements SummaryLoader.SummaryProvider {
-        private final Context mContext;
-        private final SummaryLoader mLoader;
-
-        private SummaryProvider(Context context, SummaryLoader loader) {
-            mContext = context;
-            mLoader = loader;
-        }
-
-        @Override
-        public void setListening(boolean listening) {
-            if (listening) {
-                updateSummary();
-            }
-        }
-
-        private void updateSummary() {
-            boolean enabled = Settings.System.getInt(mContext.getContentResolver(),
-                    VOLUME_BUTTON_WAKE, 0) == 1;
-            mLoader.setSummary(this, mContext.getString( enabled ? R.string.button_volume_wake_enabled_summary
-                        : R.string.button_volume_wake_disabled_summary)); 
-        }
-    }
-
-    public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
-            = new SummaryLoader.SummaryProviderFactory() {
-        @Override
-        public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
-                                                                   SummaryLoader summaryLoader) {
-            return new SummaryProvider(activity, summaryLoader);
-        }
-    };
-
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
-                        boolean enabled) {
-                    ArrayList<SearchIndexableResource> result =
-                            new ArrayList<SearchIndexableResource>();
-
-                    SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.button_settings;
-                    result.add(sir);
-
-                    return result;
-                }
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    ArrayList<String> result = new ArrayList<String>();
-                    final Resources res = context.getResources();
-                    /*final int deviceKeys = res.getInteger(
-                            com.android.internal.R.integer.config_deviceHardwareKeys);
-                    final boolean hasBackKey = (deviceKeys & KEY_MASK_BACK) != 0;
-                    final boolean hasHomeKey = (deviceKeys & KEY_MASK_HOME) != 0;
-                    final boolean hasMenuKey = (deviceKeys & KEY_MASK_MENU) != 0;
-                    final boolean hasAssistKey = (deviceKeys & KEY_MASK_ASSIST) != 0;
-                    final boolean hasAppSwitchKey = (deviceKeys & KEY_MASK_APP_SWITCH) != 0;
-
-                    if (deviceKeys == 0) {
-                        result.add(KEYS_ENABLE_CUSTOM);
-                        result.add(CATEGORY_KEYS);
-                    }
-                    if (!hasBackKey) {
-                        result.add(KEYS_BACK_PRESS);
-                        result.add(KEYS_BACK_LONG_PRESS);
-                        result.add(CATEGORY_BACK);
-                    }
-                    if (!hasHomeKey) {
-                        result.add(KEYS_HOME_PRESS);
-                        result.add(KEYS_HOME_LONG_PRESS);
-                        result.add(KEYS_HOME_DOUBLE_TAP);
-                        result.add(CATEGORY_HOME);
-                    }
-                    if (!hasMenuKey) {
-                        result.add(KEYS_MENU_PRESS);
-                        result.add(KEYS_MENU_LONG_PRESS);
-                        result.add(CATEGORY_MENU);
-                    }
-                    if (!hasAssistKey) {
-                        result.add(KEYS_ASSIST_PRESS);
-                        result.add(KEYS_ASSIST_LONG_PRESS);
-                        result.add(CATEGORY_ASSIST);
-                    }
-                    if (!hasAppSwitchKey) {
-                        result.add(KEYS_APP_SWITCH_PRESS);
-                        result.add(KEYS_APP_SWITCH_PRESS);
-                        result.add(CATEGORY_APPSWITCH);
-                    }*/
-                    if (!res.getBoolean(R.bool.config_show_volumeRockerWake)) {
-                        result.add(BUTTON_VOLUME_WAKE);
-                    }
-                    /*if (!res.getBoolean(R.bool.config_show_homeWake)) {
-                        result.add(BUTTON_HOME_WAKE);
-                    }
-                    if (!Utils.isVoiceCapable(context)) {
-                        result.add(BUTTON_HOME_ANSWERS_CALL);
-                    }*/
-                    return result;
-                }
-            };
-}
diff --git a/src/org/omnirom/omnigears/DisplayRotation.java b/src/org/omnirom/omnigears/DisplayRotation.java
deleted file mode 100644
index 3ebee45..0000000
--- a/src/org/omnirom/omnigears/DisplayRotation.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2012 The CyanogenMod Project
- * Copyright (C) 2017 The OmniROM Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears;
-
-import android.content.Context;
-import android.database.ContentObserver;
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.v7.preference.CheckBoxPreference;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceChangeListener;
-import android.support.v7.preference.PreferenceScreen;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.internal.view.RotationPolicy;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Index;
-import com.android.settings.search.Indexable;
-import com.android.settings.Utils;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class DisplayRotation extends SettingsPreferenceFragment implements OnPreferenceChangeListener, Indexable {
-    private static final String TAG = "DisplayRotation";
-
-    private static final String KEY_ACCELEROMETER = "accelerometer";
-    private static final String LOCKSCREEN_ROTATION = "lockscreen_rotation";
-    private static final String ROTATION_0_PREF = "display_rotation_0";
-    private static final String ROTATION_90_PREF = "display_rotation_90";
-    private static final String ROTATION_180_PREF = "display_rotation_180";
-    private static final String ROTATION_270_PREF = "display_rotation_270";
-
-    private SwitchPreference mAccelerometer;
-    private CheckBoxPreference mLockScreenRotationPref;
-    private CheckBoxPreference mRotation0Pref;
-    private CheckBoxPreference mRotation90Pref;
-    private CheckBoxPreference mRotation180Pref;
-    private CheckBoxPreference mRotation270Pref;
-
-    public static final int ROTATION_0_MODE = 1;
-    public static final int ROTATION_90_MODE = 2;
-    public static final int ROTATION_180_MODE = 4;
-    public static final int ROTATION_270_MODE = 8;
-
-    private ContentObserver mAccelerometerRotationObserver = new ContentObserver(new Handler()) {
-        @Override
-        public void onChange(boolean selfChange) {
-            updateAccelerometerRotationCheckbox();
-        }
-    };
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsEvent.OMNI_SETTINGS;
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        addPreferencesFromResource(R.xml.display_rotation);
-
-        PreferenceScreen prefSet = getPreferenceScreen();
-
-        mAccelerometer = (SwitchPreference) findPreference(KEY_ACCELEROMETER);
-        mLockScreenRotationPref = (CheckBoxPreference) prefSet.findPreference(LOCKSCREEN_ROTATION);
-        mRotation0Pref = (CheckBoxPreference) prefSet.findPreference(ROTATION_0_PREF);
-        mRotation90Pref = (CheckBoxPreference) prefSet.findPreference(ROTATION_90_PREF);
-        mRotation180Pref = (CheckBoxPreference) prefSet.findPreference(ROTATION_180_PREF);
-        mRotation270Pref = (CheckBoxPreference) prefSet.findPreference(ROTATION_270_PREF);
-
-        int allowAllRotations = getResources().
-                getBoolean(com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0;
-
-        int mode = Settings.System.getInt(getContentResolver(),
-                        Settings.System.ACCELEROMETER_ROTATION_ANGLES, -1);
-
-        boolean configEnableLockRotation = getResources().
-                        getBoolean(com.android.internal.R.bool.config_enableLockScreenRotation);
-        Boolean lockScreenRotationEnabled = Settings.System.getInt(getContentResolver(),
-                        Settings.System.LOCKSCREEN_ROTATION, configEnableLockRotation ? 1 : 0) != 0;
-
-        if (mode < 0) {
-            // defaults
-            mode = allowAllRotations == 1 ?
-                    (ROTATION_0_MODE | ROTATION_90_MODE | ROTATION_180_MODE | ROTATION_270_MODE) : // All angles
-                    (ROTATION_0_MODE | ROTATION_90_MODE | ROTATION_270_MODE); // All except 180
-        }
-
-        mRotation0Pref.setChecked((mode & ROTATION_0_MODE) != 0);
-        mRotation90Pref.setChecked((mode & ROTATION_90_MODE) != 0);
-        mRotation180Pref.setChecked((mode & ROTATION_180_MODE) != 0);
-        mRotation270Pref.setChecked((mode & ROTATION_270_MODE) != 0);
-        mLockScreenRotationPref.setChecked(lockScreenRotationEnabled);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        updateState();
-        getContentResolver().registerContentObserver(
-                Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION), true,
-                mAccelerometerRotationObserver);
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-
-        getContentResolver().unregisterContentObserver(mAccelerometerRotationObserver);
-    }
-
-    private void updateState() {
-        updateAccelerometerRotationCheckbox();
-    }
-
-    private void updateAccelerometerRotationCheckbox() {
-        mAccelerometer.setChecked(!RotationPolicy.isRotationLocked(getActivity()));
-    }
-
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        return false;
-    }
-
-    public boolean onPreferenceTreeClick(Preference preference) {
-        boolean value;
-
-        if (preference == mAccelerometer) {
-            RotationPolicy.setRotationLock(getActivity(), !mAccelerometer.isChecked());
-            return true;
-        } else if (preference == mRotation0Pref ||
-                preference == mRotation90Pref ||
-                preference == mRotation180Pref ||
-                preference == mRotation270Pref) {
-            int mode = 0;
-            if (mRotation0Pref.isChecked())
-                mode |= ROTATION_0_MODE;
-            if (mRotation90Pref.isChecked())
-                mode |= ROTATION_90_MODE;
-            if (mRotation180Pref.isChecked())
-                mode |= ROTATION_180_MODE;
-            if (mRotation270Pref.isChecked())
-                mode |= ROTATION_270_MODE;
-            if (mode == 0) {
-                mode |= ROTATION_0_MODE;
-                mRotation0Pref.setChecked(true);
-            }
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.ACCELEROMETER_ROTATION_ANGLES, mode);
-            return true;
-        } else if (preference == mLockScreenRotationPref) {
-            value = mLockScreenRotationPref.isChecked();
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.LOCKSCREEN_ROTATION, value ? 1 : 0);
-            return true;
-        }
-        return super.onPreferenceTreeClick(preference);
-    }
-
-   /**
-     * For Search.
-     */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-        new BaseSearchIndexProvider() {
-
-            @Override
-            public List<SearchIndexableResource> getXmlResourcesToIndex(
-                    Context context, boolean enabled) {
-                final SearchIndexableResource sir = new SearchIndexableResource(context);
-                sir.xmlResId = R.xml.display_rotation;
-                return Arrays.asList(sir);
-            }
-	};
-}
diff --git a/src/org/omnirom/omnigears/OmniDashboardFragment.java b/src/org/omnirom/omnigears/OmniDashboardFragment.java
new file mode 100644
index 0000000..bbde889
--- /dev/null
+++ b/src/org/omnirom/omnigears/OmniDashboardFragment.java
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (C) 2017 The OmniROM Project
+ *
+ * This program 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+*/
+package org.omnirom.omnigears;
+
+import android.content.Context;
+import android.provider.SearchIndexableResource;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class OmniDashboardFragment extends DashboardFragment {
+
+    private static final String TAG = "OmniDashboardFragment";
+    public static final int ACTION_SETTINGS_OMNI = 948;
+    public static final String CATEGORY_OMNI = "com.android.settings.category.ia.omni";
+
+    @Override
+    public int getMetricsCategory() {
+        return ACTION_SETTINGS_OMNI;
+        //return MetricsProto.MetricsEvent.ACTION_SETTINGS_OMNI;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.omni_dashboard_fragment;
+    }
+
+    @Override
+    protected List<PreferenceController> getPreferenceControllers(Context context) {
+        return null;
+    }
+}
diff --git a/src/org/omnirom/omnigears/PackageUtils.java b/src/org/omnirom/omnigears/PackageUtils.java
new file mode 100644
index 0000000..5f7c25f
--- /dev/null
+++ b/src/org/omnirom/omnigears/PackageUtils.java
@@ -0,0 +1,46 @@
+/*
+* Copyright (C) 2014 The OmniROM Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.omnirom.omnigears;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+
+public class PackageUtils {
+
+    public static boolean isAppInstalled(Context context, String appUri) {
+        try {
+            PackageManager pm = context.getPackageManager();
+            pm.getPackageInfo(appUri, PackageManager.GET_ACTIVITIES);
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    public static boolean isAvailableApp(String packageName, Context context) {
+        Context mContext = context;
+        final PackageManager pm = mContext.getPackageManager();
+        try {
+            pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
+            int enabled = pm.getApplicationEnabledSetting(packageName);
+            return enabled != PackageManager.COMPONENT_ENABLED_STATE_DISABLED &&
+                enabled != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
+        } catch (NameNotFoundException e) {
+            return false;
+        }
+    }
+}
diff --git a/src/org/omnirom/omnigears/Startup.java b/src/org/omnirom/omnigears/Startup.java
deleted file mode 100644
index 55a397e..0000000
--- a/src/org/omnirom/omnigears/Startup.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-* Copyright (C) 2017 The OmniROM Project
-*
-* This program 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 2 of the License, or
-* (at your option) any later version.
-*
-* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-package org.omnirom.omnigears;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-import org.omnirom.omnigears.system.TimeInState;
-
-public class Startup extends BroadcastReceiver {
-
-    @Override
-    public void onReceive(final Context context, final Intent bootintent) {
-        TimeInState.triggerResetStats();
-    }
-}
diff --git a/src/org/omnirom/omnigears/batterylight/BatteryLightDialog.java b/src/org/omnirom/omnigears/batterylight/BatteryLightDialog.java
deleted file mode 100644
index cb1e820..0000000
--- a/src/org/omnirom/omnigears/batterylight/BatteryLightDialog.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2010 Daniel Nilsson
- * Copyright (C) 2012 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.batterylight;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.Context;
-import android.graphics.Color;
-import android.graphics.PixelFormat;
-import android.os.Bundle;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.text.InputFilter;
-import android.text.InputFilter.LengthFilter;
-import android.util.Pair;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnFocusChangeListener;
-import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.Spinner;
-import android.widget.SpinnerAdapter;
-import android.widget.TextView;
-
-import com.android.settings.R;
-import org.omnirom.omnigears.ui.ColorPanelView;
-import org.omnirom.omnigears.ui.ColorPickerView;
-import org.omnirom.omnigears.ui.ColorPickerView.OnColorChangedListener;
-
-import java.util.ArrayList;
-import java.util.IllegalFormatException;
-import java.util.Locale;
-
-public class BatteryLightDialog extends AlertDialog implements
-        ColorPickerView.OnColorChangedListener, TextWatcher, OnFocusChangeListener {
-
-    private static final String TAG = "BatteryLightDialog";
-    private final static String STATE_KEY_COLOR = "BatteryLightDialog:color";
-
-    private ColorPickerView mColorPicker;
-
-    private EditText mHexColorInput;
-    private ColorPanelView mNewColor;
-    private LayoutInflater mInflater;
-    private boolean mMultiColor = true;
-    private Spinner mColorList;
-    private LinearLayout mColorListView;
-    private LinearLayout mColorPanelView;
-    private ColorPanelView mNewListColor;
-    private LedColorAdapter mLedColorAdapter;
-    private boolean mWithAlpha;
-
-    protected BatteryLightDialog(Context context, int initialColor) {
-        super(context);
-        mWithAlpha = false;
-        mMultiColor = getContext().getResources().getBoolean(R.bool.config_has_multi_color_led);
-        init(initialColor);
-    }
-
-    private void init(int color) {
-        // To fight color banding.
-        getWindow().setFormat(PixelFormat.RGBA_8888);
-        setUp(color);
-    }
-
-    /**
-     * This function sets up the dialog with the proper values.  If the speedOff parameters
-     * has a -1 value disable both spinners
-     *
-     * @param color - the color to set
-     * @param speedOn - the flash time in ms
-     * @param speedOff - the flash length in ms
-     */
-    private void setUp(int color) {
-        mInflater = (LayoutInflater) getContext()
-                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        View layout = mInflater.inflate(R.layout.dialog_battery_settings, null);
-
-        mColorPicker = (ColorPickerView) layout.findViewById(R.id.color_picker_view);
-        mHexColorInput = (EditText) layout.findViewById(R.id.hex_color_input);
-        mNewColor = (ColorPanelView) layout.findViewById(R.id.color_panel);
-        mColorPanelView = (LinearLayout) layout.findViewById(R.id.color_panel_view);
-
-        mColorListView = (LinearLayout) layout.findViewById(R.id.color_list_view);
-        mColorList = (Spinner) layout.findViewById(R.id.color_list_spinner);
-        mNewListColor = (ColorPanelView) layout.findViewById(R.id.color_list_panel);
-
-        mColorPicker.setOnColorChangedListener(this);
-        mHexColorInput.setOnFocusChangeListener(this);
-        setAlphaSliderVisible(mWithAlpha);
-        mColorPicker.setColor(color, true);
-
-        mColorList = (Spinner) layout.findViewById(R.id.color_list_spinner);
-        mLedColorAdapter = new LedColorAdapter(
-                R.array.entries_led_colors,
-                R.array.values_led_colors);
-        mColorList.setAdapter(mLedColorAdapter);
-        mColorList.setSelection(mLedColorAdapter.getColorPosition(color));
-        mColorList.setOnItemSelectedListener(mColorListListener);
-
-        setView(layout);
-
-        // show and hide the correct UI depending if we have multi-color led or not
-        if (mMultiColor){
-            mColorListView.setVisibility(View.GONE);
-            mColorPicker.setVisibility(View.VISIBLE);
-            mColorPanelView.setVisibility(View.VISIBLE);
-        } else {
-            mColorListView.setVisibility(View.VISIBLE);
-            mColorPicker.setVisibility(View.GONE);
-            mColorPanelView.setVisibility(View.GONE);
-        }
-    }
-
-    private AdapterView.OnItemSelectedListener mColorListListener = new AdapterView.OnItemSelectedListener() {
-
-        @Override
-        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
-            int color = mLedColorAdapter.getColor(position);
-            mNewListColor.setColor(color);
-        }
-
-        @Override
-        public void onNothingSelected(AdapterView<?> parent) {
-        }
-    };
-
-    @Override
-    public Bundle onSaveInstanceState() {
-        Bundle state = super.onSaveInstanceState();
-        state.putInt(STATE_KEY_COLOR, getColor());
-        return state;
-    }
-
-    @Override
-    public void onRestoreInstanceState(Bundle state) {
-        super.onRestoreInstanceState(state);
-        mColorPicker.setColor(state.getInt(STATE_KEY_COLOR), true);
-    }
-
-    @Override
-    public void onColorChanged(int color) {
-        final boolean hasAlpha = mWithAlpha;
-        final String format = hasAlpha ? "%08x" : "%06x";
-        final int mask = hasAlpha ? 0xFFFFFFFF : 0x00FFFFFF;
-
-        mNewColor.setColor(color);
-        mHexColorInput.setText(String.format(Locale.US, format, color & mask));
-    }
-
-    public void setAlphaSliderVisible(boolean visible) {
-        mHexColorInput.setFilters(new InputFilter[] { new InputFilter.LengthFilter(visible ? 8 : 6) } );
-        mColorPicker.setAlphaSliderVisible(visible);
-    }
-
-    public int getColor() {
-        if (mMultiColor){
-            return mColorPicker.getColor();
-        } else {
-            return mNewListColor.getColor();
-        }
-    }
-
-    class LedColorAdapter extends BaseAdapter implements SpinnerAdapter {
-        private ArrayList<Pair<String, Integer>> mColors;
-
-        public LedColorAdapter(int ledColorResource, int ledValueResource) {
-            mColors = new ArrayList<Pair<String, Integer>>();
-
-            String[] color_names = getContext().getResources().getStringArray(ledColorResource);
-            String[] color_values = getContext().getResources().getStringArray(ledValueResource);
-
-            for(int i = 0; i < color_values.length; ++i) {
-                try {
-                    int color = Color.parseColor(color_values[i]);
-                    mColors.add(new Pair<String, Integer>(color_names[i], color));
-                } catch (IllegalArgumentException ex) {
-                    // Number format is incorrect, ignore entry
-                }
-            }
-        }
-
-        /**
-         * Will return the position of the spinner entry with the specified
-         * color. Returns 0 if there is no such entry.
-         */
-        public int getColorPosition(int color) {
-            for (int position = 0; position < getCount(); ++position) {
-                if (getItem(position).second.equals(color)) {
-                    return position;
-                }
-            }
-
-            return 0;
-        }
-
-        public int getColor(int position) {
-            Pair<String, Integer> item = getItem(position);
-            if (item != null){
-                return item.second;
-            }
-
-            // -1 is white
-            return -1;
-        }
-
-        @Override
-        public int getCount() {
-            return mColors.size();
-        }
-
-        @Override
-        public Pair<String, Integer> getItem(int position) {
-            return mColors.get(position);
-        }
-
-        @Override
-        public long getItemId(int position) {
-            return position;
-        }
-
-        @Override
-        public View getView(int position, View view, ViewGroup parent) {
-            if (view == null) {
-                view = mInflater.inflate(R.layout.led_color_item, null);
-            }
-
-            Pair<String, Integer> entry = getItem(position);
-            ((TextView) view.findViewById(R.id.textViewName)).setText(entry.first);
-
-            return view;
-        }
-    }
-
-    @Override
-    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-    }
-
-    @Override
-    public void onTextChanged(CharSequence s, int start, int before, int count) {
-    }
-
-    @Override
-    public void afterTextChanged(Editable s) {
-        String hexColor = mHexColorInput.getText().toString();
-        if (!hexColor.isEmpty()) {
-            try {
-                int color = Color.parseColor('#' + hexColor);
-                if (!mWithAlpha) {
-                    color |= 0xFF000000; // set opaque
-                }
-                mColorPicker.setColor(color);
-                mNewColor.setColor(color);
-            } catch (IllegalArgumentException ex) {
-                // Number format is incorrect, ignore
-            }
-        }
-    }
-
-    @Override
-    public void onFocusChange(View v, boolean hasFocus) {
-        if (!hasFocus) {
-            mHexColorInput.removeTextChangedListener(this);
-            InputMethodManager inputMethodManager = (InputMethodManager) getContext()
-                    .getSystemService(Activity.INPUT_METHOD_SERVICE);
-            inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
-        } else {
-            mHexColorInput.addTextChangedListener(this);
-        }
-    }
-}
diff --git a/src/org/omnirom/omnigears/batterylight/BatteryLightPreference.java b/src/org/omnirom/omnigears/batterylight/BatteryLightPreference.java
deleted file mode 100644
index 5f316c7..0000000
--- a/src/org/omnirom/omnigears/batterylight/BatteryLightPreference.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2012 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.batterylight;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.res.Resources;
-import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.shapes.RectShape;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceViewHolder;
-import android.util.AttributeSet;
-import android.widget.ImageView;
-
-import com.android.settings.R;
-
-public class BatteryLightPreference extends Preference implements DialogInterface.OnDismissListener {
-
-    private static String TAG = "BatteryLightPreference";
-    public static final int DEFAULT_COLOR = 0xFFFFFF; //White
-
-    private ImageView mLightColorView;
-    private Resources mResources;
-    private int mColorValue;
-    private Dialog mDialog;
-
-    /**
-     * @param context
-     * @param attrs
-     */
-    public BatteryLightPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mColorValue = DEFAULT_COLOR;
-        init();
-    }
-
-    public BatteryLightPreference(Context context, int color) {
-        super(context, null);
-        mColorValue = color;
-        init();
-    }
-
-    private void init() {
-        setLayoutResource(R.layout.preference_battery_light);
-        mResources = getContext().getResources();
-    }
-
-    public void setColor(int color) {
-        mColorValue = color;
-        updatePreferenceViews();
-    }
-
-    public int getColor() {
-        return mColorValue;
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-
-        mLightColorView = (ImageView) holder.findViewById(R.id.light_color);
-
-        updatePreferenceViews();
-    }
-
-    private void updatePreferenceViews() {
-        final int width = (int) mResources.getDimension(R.dimen.color_preference_width);
-        final int height = (int) mResources.getDimension(R.dimen.color_preference_height);
-
-        if (mLightColorView != null) {
-            mLightColorView.setEnabled(true);
-            mLightColorView.setImageDrawable(createRectShape(width, height, 0xFF000000 | mColorValue));
-        }
-    }
-
-    @Override
-    protected void onClick() {
-        if (mDialog != null && mDialog.isShowing()) return;
-        mDialog = getDialog();
-        mDialog.setOnDismissListener(this);
-        mDialog.show();
-    }
-
-    public Dialog getDialog() {
-        final BatteryLightDialog d = new BatteryLightDialog(getContext(),
-                0xFF000000 | mColorValue);
-
-        d.setButton(AlertDialog.BUTTON_POSITIVE, mResources.getString(R.string.ok),
-                new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                mColorValue =  d.getColor() & 0x00FFFFFF; // strip alpha, led does not support it
-                updatePreferenceViews();
-                callChangeListener(this);
-            }
-        });
-        d.setButton(AlertDialog.BUTTON_NEGATIVE, mResources.getString(R.string.cancel),
-                (DialogInterface.OnClickListener) null);
-
-        return d;
-    }
-
-    private static ShapeDrawable createRectShape(int width, int height, int color) {
-        ShapeDrawable shape = new ShapeDrawable(new RectShape());
-        shape.setIntrinsicHeight(height);
-        shape.setIntrinsicWidth(width);
-        shape.getPaint().setColor(color);
-        return shape;
-    }
-
-    @Override
-    public void onDismiss(DialogInterface dialog) {
-        mDialog = null;
-    }
-}
diff --git a/src/org/omnirom/omnigears/batterylight/BatteryLightSettings.java b/src/org/omnirom/omnigears/batterylight/BatteryLightSettings.java
deleted file mode 100644
index f44c8aa..0000000
--- a/src/org/omnirom/omnigears/batterylight/BatteryLightSettings.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright (C) 2012 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.batterylight;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.support.v7.preference.PreferenceCategory;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceGroup;
-import android.support.v7.preference.PreferenceScreen;
-import android.support.v14.preference.PreferenceFragment;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-
-import org.omnirom.omnigears.preference.SystemSettingSwitchPreference;
-
-import java.util.List;
-import java.util.ArrayList;
-
-public class BatteryLightSettings extends SettingsPreferenceFragment implements
-        Preference.OnPreferenceChangeListener, Indexable {
-    private static final String TAG = "BatteryLightSettings";
-
-    private static final String LOW_COLOR_PREF = "low_color";
-    private static final String MEDIUM_COLOR_PREF = "medium_color";
-    private static final String FULL_COLOR_PREF = "full_color";
-    private static final String REALLY_FULL_COLOR_PREF = "really_full_color";
-    private static final String KEY_CATEGORY_GENERAL = "general_section";
-    private static final String FAST_COLOR_PREF = "fast_color";
-    private static final String FAST_CHARGING_LED_PREF = "fast_charging_led_enabled";
-    private static final String BATTERY_LIGHT_PREF = "battery_light_enabled";
-    private static final String BATTERY_PULSE_PREF = "battery_light_pulse";
-    private static final String BATTERY_LIGHT_ONLY_FULL_PREF = "battery_light_only_fully_charged";
-    private static final String KEY_CATEGORY_FAST_CHARGE = "fast_color_cat";
-    private static final String KEY_CATEGORY_CHARGE_COLORS = "colors_list";
-
-    private boolean mMultiColorLed;
-    private SystemSettingSwitchPreference mEnabledPref;
-    private SystemSettingSwitchPreference mPulsePref;
-    private SystemSettingSwitchPreference mOnlyFullPref;
-    private SystemSettingSwitchPreference mFastBatteryLightEnabledPref;
-    private PreferenceGroup mColorPrefs;
-    private BatteryLightPreference mLowColorPref;
-    private BatteryLightPreference mMediumColorPref;
-    private BatteryLightPreference mFullColorPref;
-    private BatteryLightPreference mReallyFullColorPref;
-    private BatteryLightPreference mFastColorPref;
-    private static final int MENU_RESET = Menu.FIRST;
-    private int mLowBatteryWarningLevel;
-    private boolean mBatteryLightEnabled;
-    private boolean mFastBatteryLightEnabled;
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsEvent.OMNI_SETTINGS;
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.battery_light_settings);
-
-        PreferenceScreen prefSet = getPreferenceScreen();
-        ContentResolver resolver = getContentResolver();
-        mLowBatteryWarningLevel = getResources().getInteger(
-                com.android.internal.R.integer.config_lowBatteryWarningLevel);
-        mBatteryLightEnabled = getResources().getBoolean(
-                com.android.internal.R.bool.config_intrusiveBatteryLed);
-
-        mEnabledPref = (SystemSettingSwitchPreference)prefSet.findPreference(BATTERY_LIGHT_PREF);
-        mEnabledPref.setChecked(Settings.System.getInt(resolver,
-                        Settings.System.BATTERY_LIGHT_ENABLED, mBatteryLightEnabled ? 1 : 0) != 0);
-        mEnabledPref.setOnPreferenceChangeListener(this);
-
-        mPulsePref = (SystemSettingSwitchPreference)prefSet.findPreference(BATTERY_PULSE_PREF);
-        mPulsePref.setChecked(Settings.System.getInt(resolver,
-                        Settings.System.BATTERY_LIGHT_PULSE, mBatteryLightEnabled ? 1 : 0) != 0);
-        mPulsePref.setOnPreferenceChangeListener(this);
-
-        mOnlyFullPref = (SystemSettingSwitchPreference)prefSet.findPreference(BATTERY_LIGHT_ONLY_FULL_PREF);
-        mOnlyFullPref.setOnPreferenceChangeListener(this);
-
-        // Does the Device support changing battery LED colors?
-        if (getResources().getBoolean(com.android.internal.R.bool.config_multiColorBatteryLed)) {
-            setHasOptionsMenu(true);
-
-            // Low, Medium and full color preferences
-            mLowColorPref = (BatteryLightPreference) prefSet.findPreference(LOW_COLOR_PREF);
-            mLowColorPref.setOnPreferenceChangeListener(this);
-
-            mMediumColorPref = (BatteryLightPreference) prefSet.findPreference(MEDIUM_COLOR_PREF);
-            mMediumColorPref.setOnPreferenceChangeListener(this);
-
-            mFullColorPref = (BatteryLightPreference) prefSet.findPreference(FULL_COLOR_PREF);
-            mFullColorPref.setOnPreferenceChangeListener(this);
-
-            mReallyFullColorPref = (BatteryLightPreference) prefSet.findPreference(REALLY_FULL_COLOR_PREF);
-            mReallyFullColorPref.setOnPreferenceChangeListener(this);
-
-            mFastBatteryLightEnabledPref = (SystemSettingSwitchPreference)prefSet.findPreference(FAST_CHARGING_LED_PREF);
-
-            mFastColorPref = (BatteryLightPreference) prefSet.findPreference(FAST_COLOR_PREF);
-            mFastColorPref.setOnPreferenceChangeListener(this);
-
-            // Does the Device support fast charge ?
-            if (!getResources().getBoolean(com.android.internal.R.bool.config_FastChargingLedSupported)) {
-                prefSet.removePreference(prefSet.findPreference(KEY_CATEGORY_FAST_CHARGE));
-            }
-        } else {
-            prefSet.removePreference(prefSet.findPreference(KEY_CATEGORY_CHARGE_COLORS));
-            // not multi color cant have fast charge
-            prefSet.removePreference(prefSet.findPreference(KEY_CATEGORY_FAST_CHARGE));
-        }
-        boolean showOnlyWhenFull = Settings.System.getInt(resolver,
-                Settings.System.BATTERY_LIGHT_ONLY_FULLY_CHARGED, 0) != 0;
-        updateEnablement(showOnlyWhenFull);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        refreshDefault();
-    }
-
-    private void refreshDefault() {
-        ContentResolver resolver = getContentResolver();
-        Resources res = getResources();
-
-        if (mLowColorPref != null) {
-            int lowColor = Settings.System.getInt(resolver, Settings.System.BATTERY_LIGHT_LOW_COLOR,
-                    res.getInteger(com.android.internal.R.integer.config_notificationsBatteryLowARGB));
-            mLowColorPref.setColor(lowColor);
-        }
-
-        if (mMediumColorPref != null) {
-            int mediumColor = Settings.System.getInt(resolver, Settings.System.BATTERY_LIGHT_MEDIUM_COLOR,
-                    res.getInteger(com.android.internal.R.integer.config_notificationsBatteryMediumARGB));
-            mMediumColorPref.setColor(mediumColor);
-        }
-
-        if (mFullColorPref != null) {
-            int fullColor = Settings.System.getInt(resolver, Settings.System.BATTERY_LIGHT_FULL_COLOR,
-                    res.getInteger(com.android.internal.R.integer.config_notificationsBatteryFullARGB));
-            mFullColorPref.setColor(fullColor);
-        }
-
-        if (mReallyFullColorPref != null) {
-            int reallyFullColor = Settings.System.getInt(resolver, Settings.System.BATTERY_LIGHT_REALLY_FULL_COLOR,
-                    res.getInteger(com.android.internal.R.integer.config_notificationsBatteryFullARGB));
-            mReallyFullColorPref.setColor(reallyFullColor);
-        }
-
-        if (mFastColorPref != null) {
-            int fastColor = Settings.System.getInt(resolver, Settings.System.FAST_BATTERY_LIGHT_COLOR,
-                    res.getInteger(com.android.internal.R.integer.config_notificationsFastBatteryARGB));
-            mFastColorPref.setColor(fastColor);
-        }
-    }
-
-    /**
-     * Updates the default or application specific notification settings.
-     *
-     * @param key of the specific setting to update
-     * @param color
-     */
-    protected void updateValues(String key, Integer color) {
-        ContentResolver resolver = getContentResolver();
-
-        if (key.equals(LOW_COLOR_PREF)) {
-            Settings.System.putInt(resolver, Settings.System.BATTERY_LIGHT_LOW_COLOR, color);
-        } else if (key.equals(MEDIUM_COLOR_PREF)) {
-            Settings.System.putInt(resolver, Settings.System.BATTERY_LIGHT_MEDIUM_COLOR, color);
-        } else if (key.equals(FULL_COLOR_PREF)) {
-            Settings.System.putInt(resolver, Settings.System.BATTERY_LIGHT_FULL_COLOR, color);
-        } else if (key.equals(REALLY_FULL_COLOR_PREF)) {
-            Settings.System.putInt(resolver, Settings.System.BATTERY_LIGHT_REALLY_FULL_COLOR, color);
-        } else if (key.equals(FAST_COLOR_PREF)) {
-            Settings.System.putInt(resolver, Settings.System.FAST_BATTERY_LIGHT_COLOR, color);
-        }
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        menu.add(0, MENU_RESET, 0, R.string.reset)
-                .setIcon(R.drawable.ic_settings_backup_restore)
-                .setAlphabeticShortcut('r')
-                .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case MENU_RESET:
-                resetToDefaults();
-                return true;
-        }
-        return false;
-    }
-
-    protected void resetColors() {
-        ContentResolver resolver = getActivity().getContentResolver();
-        Resources res = getResources();
-
-        // Reset to the framework default colors
-        Settings.System.putInt(resolver, Settings.System.BATTERY_LIGHT_LOW_COLOR,
-                res.getInteger(com.android.internal.R.integer.config_notificationsBatteryLowARGB));
-        Settings.System.putInt(resolver, Settings.System.BATTERY_LIGHT_MEDIUM_COLOR,
-                res.getInteger(com.android.internal.R.integer.config_notificationsBatteryMediumARGB));
-        Settings.System.putInt(resolver, Settings.System.BATTERY_LIGHT_FULL_COLOR,
-                res.getInteger(com.android.internal.R.integer.config_notificationsBatteryFullARGB));
-        Settings.System.putInt(resolver, Settings.System.BATTERY_LIGHT_REALLY_FULL_COLOR,
-                res.getInteger(com.android.internal.R.integer.config_notificationsBatteryFullARGB));
-        Settings.System.putInt(resolver, Settings.System.FAST_BATTERY_LIGHT_COLOR,
-                res.getInteger(com.android.internal.R.integer.config_notificationsFastBatteryARGB));
-        refreshDefault();
-    }
-
-    protected void resetToDefaults() {
-        if (mEnabledPref != null) mEnabledPref.setChecked(true);
-        if (mPulsePref != null) mPulsePref.setChecked(false);
-        if (mOnlyFullPref != null) mOnlyFullPref.setChecked(false);
-        if (mFastBatteryLightEnabledPref != null) mFastBatteryLightEnabledPref.setChecked(false);
-        resetColors();
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object objValue) {
-        if (preference == mEnabledPref) {
-            boolean value = (Boolean) objValue;
-            Settings.System.putInt(getActivity().getContentResolver(),
-                    Settings.System.BATTERY_LIGHT_ENABLED, value ? 1:0);
-        } else if (preference == mPulsePref) {
-            boolean value = (Boolean) objValue;
-            Settings.System.putInt(getActivity().getContentResolver(),
-                    Settings.System.BATTERY_LIGHT_PULSE, value ? 1:0);
-        } else if (preference == mOnlyFullPref) {
-            boolean value = (Boolean) objValue;
-            // If enabled, disable all but really full color preference.
-            updateEnablement(value);
-        } else {
-            BatteryLightPreference lightPref = (BatteryLightPreference) preference;
-            updateValues(lightPref.getKey(), lightPref.getColor());
-        }
-        return true;
-    }
-
-    private void updateEnablement(boolean showOnlyWhenFull) {
-        // If enabled, disable all but really full color preference.
-        if (mLowColorPref != null) {
-            mLowColorPref.setEnabled(!showOnlyWhenFull);
-        }
-        if (mMediumColorPref != null) {
-            mMediumColorPref.setEnabled(!showOnlyWhenFull);
-        }
-        if (mFullColorPref != null) {
-            mFullColorPref.setEnabled(!showOnlyWhenFull);
-        }
-        if (mFastColorPref != null) {
-            mFastColorPref.setEnabled(!showOnlyWhenFull);
-        }
-        if (mFastBatteryLightEnabledPref != null) {
-            mFastBatteryLightEnabledPref.setEnabled(!showOnlyWhenFull);
-        }
-    }
-
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
-                        boolean enabled) {
-                    ArrayList<SearchIndexableResource> result =
-                            new ArrayList<SearchIndexableResource>();
-
-                    SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.battery_light_settings;
-                    result.add(sir);
-                    return result;
-                }
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    ArrayList<String> result = new ArrayList<String>();
-                    final Resources res = context.getResources();
-                    if (!res.getBoolean(com.android.internal.R.bool.config_intrusiveBatteryLed)) {
-                        result.add(BATTERY_LIGHT_PREF);
-                        result.add(BATTERY_PULSE_PREF);
-                        result.add(BATTERY_LIGHT_ONLY_FULL_PREF);
-                    }
-                    if (!res.getBoolean(com.android.internal.R.bool.config_multiColorBatteryLed)) {
-                        result.add(LOW_COLOR_PREF);
-                        result.add(MEDIUM_COLOR_PREF);
-                        result.add(FULL_COLOR_PREF);
-                        result.add(REALLY_FULL_COLOR_PREF);
-                    }
-                    if (!res.getBoolean(com.android.internal.R.bool.config_FastChargingLedSupported)) {
-                        result.add(FAST_CHARGING_LED_PREF);
-                        result.add(FAST_COLOR_PREF);
-                    }
-                    return result;
-                }
-            };
-}
diff --git a/src/org/omnirom/omnigears/batterylight/NotificationLightDialog.java b/src/org/omnirom/omnigears/batterylight/NotificationLightDialog.java
deleted file mode 100644
index fdbfd89..0000000
--- a/src/org/omnirom/omnigears/batterylight/NotificationLightDialog.java
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * Copyright (C) 2010 Daniel Nilsson
- * Copyright (C) 2012 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.batterylight;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.graphics.Color;
-import android.graphics.PixelFormat;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.text.InputFilter;
-import android.text.InputFilter.LengthFilter;
-import android.util.Pair;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnFocusChangeListener;
-import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.Spinner;
-import android.widget.SpinnerAdapter;
-import android.widget.TextView;
-
-import com.android.settings.R;
-import org.omnirom.omnigears.ui.ColorPanelView;
-import org.omnirom.omnigears.ui.ColorPickerView;
-import org.omnirom.omnigears.ui.ColorPickerView.OnColorChangedListener;
-
-import java.util.ArrayList;
-import java.util.Locale;
-
-public class NotificationLightDialog extends AlertDialog implements
-        ColorPickerView.OnColorChangedListener, TextWatcher, OnFocusChangeListener {
-
-    private static final String TAG = "NotificationLightDialog";
-    private final static String STATE_KEY_COLOR = "NotificationLightDialog:color";
-    private final static long LED_UPDATE_DELAY_MS = 250;
-
-    private ColorPickerView mColorPicker;
-    private EditText mHexColorInput;
-    private Spinner mColorList;
-    private ColorPanelView mNewColor;
-    private LinearLayout mColorListView;
-    private Spinner mPulseSpeedOn;
-    private Spinner mPulseSpeedOff;
-    private LayoutInflater mInflater;
-    private boolean mMultiColor = true;
-    private LinearLayout mColorPanelView;
-    private ColorPanelView mNewListColor;
-    private LedColorAdapter mLedColorAdapter;
-    private boolean mWithAlpha;
-
-    private OnColorChangedListener mListener;
-
-    private NotificationManager mNotificationManager;
-
-    private boolean mReadyForLed;
-    private int mLedLastColor;
-    private int mLedLastSpeedOn;
-    private int mLedLastSpeedOff;
-
-
-    /**
-     * @param context
-     * @param initialColor
-     * @param initialSpeedOn
-     * @param initialSpeedOff
-     */
-    protected NotificationLightDialog(Context context, int initialColor, int initialSpeedOn,
-            int initialSpeedOff) {
-        super(context);
-
-        init(context, initialColor, initialSpeedOn, initialSpeedOff, true);
-    }
-
-    /**
-     * @param context
-     * @param initialColor
-     * @param initialSpeedOn
-     * @param initialSpeedOff
-     * @param onOffChangeable
-     */
-    protected NotificationLightDialog(Context context, int initialColor, int initialSpeedOn,
-            int initialSpeedOff, boolean onOffChangeable) {
-        super(context);
-
-        init(context, initialColor, initialSpeedOn, initialSpeedOff, onOffChangeable);
-    }
-
-    private void init(Context context, int color, int speedOn, int speedOff,
-            boolean onOffChangeable) {
-        mNotificationManager =
-                (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
-        mMultiColor = getContext().getResources().getBoolean(R.bool.config_has_multi_color_led);
-        mReadyForLed = false;
-        mLedLastColor = 0;
-
-        // To fight color banding.
-        getWindow().setFormat(PixelFormat.RGBA_8888);
-        setUp(color, speedOn, speedOff, onOffChangeable);
-    }
-
-    /**
-     * This function sets up the dialog with the proper values.  If the speedOff parameters
-     * has a -1 value disable both spinners
-     *
-     * @param color - the color to set
-     * @param speedOn - the flash time in ms
-     * @param speedOff - the flash length in ms
-     */
-    private void setUp(int color, int speedOn, int speedOff, boolean onOffChangeable) {
-        mInflater = (LayoutInflater) getContext()
-                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        View layout = mInflater.inflate(R.layout.dialog_notification_settings, null);
-
-        mColorPicker = (ColorPickerView) layout.findViewById(R.id.color_picker_view);
-        mHexColorInput = (EditText) layout.findViewById(R.id.hex_color_input);
-        mNewColor = (ColorPanelView) layout.findViewById(R.id.color_panel);
-        mColorPanelView = (LinearLayout) layout.findViewById(R.id.color_panel_view);
-
-        mColorListView = (LinearLayout) layout.findViewById(R.id.color_list_view);
-        mColorList = (Spinner) layout.findViewById(R.id.color_list_spinner);
-        mNewListColor = (ColorPanelView) layout.findViewById(R.id.color_list_panel);
-
-        mColorPicker.setOnColorChangedListener(this);
-        mHexColorInput.setOnFocusChangeListener(this);
-        setAlphaSliderVisible(mWithAlpha);
-        mColorPicker.setColor(color, true);
-
-        mColorList = (Spinner) layout.findViewById(R.id.color_list_spinner);
-        mLedColorAdapter = new LedColorAdapter(
-                R.array.entries_led_colors,
-                R.array.values_led_colors);
-        mColorList.setAdapter(mLedColorAdapter);
-        mColorList.setSelection(mLedColorAdapter.getColorPosition(color));
-        mColorList.setOnItemSelectedListener(mColorListListener);
-
-        mPulseSpeedOn = (Spinner) layout.findViewById(R.id.on_spinner);
-        mPulseSpeedOff = (Spinner) layout.findViewById(R.id.off_spinner);
-
-        if (onOffChangeable) {
-            PulseSpeedAdapter pulseSpeedAdapter = new PulseSpeedAdapter(
-                    R.array.notification_pulse_length_entries,
-                    R.array.notification_pulse_length_values,
-                    speedOn);
-            mPulseSpeedOn.setAdapter(pulseSpeedAdapter);
-            mPulseSpeedOn.setSelection(pulseSpeedAdapter.getTimePosition(speedOn));
-            mPulseSpeedOn.setOnItemSelectedListener(mPulseSelectionListener);
-
-            pulseSpeedAdapter = new PulseSpeedAdapter(R.array.notification_pulse_speed_entries,
-                    R.array.notification_pulse_speed_values,
-                    speedOff);
-            mPulseSpeedOff.setAdapter(pulseSpeedAdapter);
-            mPulseSpeedOff.setSelection(pulseSpeedAdapter.getTimePosition(speedOff));
-            mPulseSpeedOff.setOnItemSelectedListener(mPulseSelectionListener);
-        } else {
-            View speedSettingsGroup = layout.findViewById(R.id.speed_title_view);
-            speedSettingsGroup.setVisibility(View.GONE);
-        }
-
-        mPulseSpeedOn.setEnabled(onOffChangeable);
-        mPulseSpeedOff.setEnabled((speedOn != 1) && onOffChangeable);
-
-        setView(layout);
-
-        // show and hide the correct UI depending if we have multi-color led or not
-        if (mMultiColor){
-            mColorListView.setVisibility(View.GONE);
-            mColorPicker.setVisibility(View.VISIBLE);
-            mColorPanelView.setVisibility(View.VISIBLE);
-        } else {
-            mColorListView.setVisibility(View.VISIBLE);
-            mColorPicker.setVisibility(View.GONE);
-            mColorPanelView.setVisibility(View.GONE);
-        }
-
-        mReadyForLed = true;
-        updateLed();
-
-    }
-
-    private AdapterView.OnItemSelectedListener mPulseSelectionListener =
-            new AdapterView.OnItemSelectedListener() {
-        @Override
-        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
-            if (parent == mPulseSpeedOn) {
-                mPulseSpeedOff.setEnabled(mPulseSpeedOn.isEnabled() && getPulseSpeedOn() != 1);
-            }
-            updateLed();
-        }
-
-        @Override
-        public void onNothingSelected(AdapterView<?> parent) {
-        }
-    };
-
-    private AdapterView.OnItemSelectedListener mColorListListener = new AdapterView.OnItemSelectedListener() {
-
-        @Override
-        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
-            int color = mLedColorAdapter.getColor(position);
-            mNewListColor.setColor(color);
-        }
-
-        @Override
-        public void onNothingSelected(AdapterView<?> parent) {
-        }
-    };
-
-    @Override
-    public Bundle onSaveInstanceState() {
-        Bundle state = super.onSaveInstanceState();
-        state.putInt(STATE_KEY_COLOR, getColor());
-        return state;
-    }
-
-    @Override
-    public void onRestoreInstanceState(Bundle state) {
-        super.onRestoreInstanceState(state);
-        mColorPicker.setColor(state.getInt(STATE_KEY_COLOR), true);
-    }
-
-    @Override
-    public void onStop() {
-        super.onStop();
-        dismissLed();
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-        updateLed();
-    }
-
-    @Override
-    public void onColorChanged(int color) {
-        final boolean hasAlpha = mColorPicker.isAlphaSliderVisible();
-        final String format = hasAlpha ? "%08x" : "%06x";
-        final int mask = hasAlpha ? 0xFFFFFFFF : 0x00FFFFFF;
-
-        mNewColor.setColor(color);
-        mHexColorInput.setText(String.format(Locale.US, format, color & mask));
-
-        if (mListener != null) {
-            mListener.onColorChanged(color);
-        }
-
-        updateLed();
-    }
-
-    public void setAlphaSliderVisible(boolean visible) {
-        mHexColorInput.setFilters(new InputFilter[] { new InputFilter.LengthFilter(visible ? 8 : 6) } );
-        mColorPicker.setAlphaSliderVisible(visible);
-    }
-
-    public int getColor() {
-        if (mMultiColor){
-            return mColorPicker.getColor();
-        } else {
-            return mNewListColor.getColor();
-        }
-    }
-
-    class LedColorAdapter extends BaseAdapter implements SpinnerAdapter {
-        private ArrayList<Pair<String, Integer>> mColors;
-
-        public LedColorAdapter(int ledColorResource, int ledValueResource) {
-            mColors = new ArrayList<Pair<String, Integer>>();
-
-            String[] color_names = getContext().getResources().getStringArray(ledColorResource);
-            String[] color_values = getContext().getResources().getStringArray(ledValueResource);
-
-            for(int i = 0; i < color_values.length; ++i) {
-                try {
-                    int color = Color.parseColor(color_values[i]);
-                    mColors.add(new Pair<String, Integer>(color_names[i], color));
-                } catch (IllegalArgumentException ex) {
-                    // Number format is incorrect, ignore entry
-                }
-            }
-        }
-
-        /**
-         * Will return the position of the spinner entry with the specified
-         * color. Returns 0 if there is no such entry.
-         */
-        public int getColorPosition(int color) {
-            for (int position = 0; position < getCount(); ++position) {
-                if (getItem(position).second.equals(color)) {
-                    return position;
-                }
-            }
-
-            return 0;
-        }
-
-        public int getColor(int position) {
-            Pair<String, Integer> item = getItem(position);
-            if (item != null){
-                return item.second;
-            }
-
-            // -1 is white
-            return -1;
-        }
-
-        @Override
-        public int getCount() {
-            return mColors.size();
-        }
-
-        @Override
-        public Pair<String, Integer> getItem(int position) {
-            return mColors.get(position);
-        }
-
-        @Override
-        public long getItemId(int position) {
-            return position;
-        }
-
-        @Override
-        public View getView(int position, View view, ViewGroup parent) {
-            if (view == null) {
-                view = mInflater.inflate(R.layout.led_color_item, null);
-            }
-
-            Pair<String, Integer> entry = getItem(position);
-            ((TextView) view.findViewById(R.id.textViewName)).setText(entry.first);
-
-            return view;
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public int getPulseSpeedOn() {
-        if (mPulseSpeedOn.isEnabled()) {
-            return ((Pair<String, Integer>) mPulseSpeedOn.getSelectedItem()).second;
-        } else {
-            return 1;
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public int getPulseSpeedOff() {
-        // return 0 if 'Always on' is selected
-        return getPulseSpeedOn() == 1 ? 0 : ((Pair<String, Integer>) mPulseSpeedOff.getSelectedItem()).second;
-    }
-
-    private Handler mLedHandler = new Handler() {
-        public void handleMessage(Message msg) {
-            updateLed();
-        }
-    };
-
-    private void updateLed() {
-        if (!mReadyForLed) {
-            return;
-        }
-
-        final int color = getColor() & 0xFFFFFF;
-        final int speedOn, speedOff;
-        if (mPulseSpeedOn.isEnabled()) {
-            speedOn = getPulseSpeedOn();
-            speedOff = getPulseSpeedOff();
-        } else {
-            speedOn = 1;
-            speedOff = 0;
-        }
-
-        if (mLedLastColor == color && mLedLastSpeedOn == speedOn
-                && mLedLastSpeedOff == speedOff) {
-            return;
-        }
-
-        // Dampen rate of consecutive LED changes
-        if (mLedHandler.hasMessages(0)) {
-            return;
-        }
-        mLedHandler.sendEmptyMessageDelayed(0, LED_UPDATE_DELAY_MS);
-
-        mLedLastColor = color;
-        mLedLastSpeedOn = speedOn;
-        mLedLastSpeedOff = speedOff;
-
-        final Bundle b = new Bundle();
-        b.putBoolean(Notification.EXTRA_FORCE_SHOW_LIGHTS, true);
-
-        final Notification.Builder builder = new Notification.Builder(getContext());
-        builder.setLights(color, speedOn, speedOff);
-        builder.setExtras(b);
-
-        // Set a notification
-        builder.setSmallIcon(R.drawable.ic_settings_leds);
-        builder.setContentTitle(getContext().getString(R.string.led_notification_title));
-        builder.setContentText(getContext().getString(R.string.led_notification_text));
-        builder.setOngoing(true);
-
-        mNotificationManager.notify(1, builder.build());
-    }
-
-    public void dismissLed() {
-        mNotificationManager.cancel(1);
-        // ensure we later reset LED if dialog is
-        // hidden and then made visible
-        mLedLastColor = 0;
-    }
-
-    class PulseSpeedAdapter extends BaseAdapter implements SpinnerAdapter {
-        private ArrayList<Pair<String, Integer>> times;
-
-        public PulseSpeedAdapter(int timeNamesResource, int timeValuesResource) {
-            times = new ArrayList<Pair<String, Integer>>();
-
-            String[] time_names = getContext().getResources().getStringArray(timeNamesResource);
-            String[] time_values = getContext().getResources().getStringArray(timeValuesResource);
-
-            for(int i = 0; i < time_values.length; ++i) {
-                times.add(new Pair<String, Integer>(time_names[i], Integer.decode(time_values[i])));
-            }
-
-        }
-
-        /**
-         * This constructor apart from taking a usual time entry array takes the
-         * currently configured time value which might cause the addition of a
-         * "Custom" time entry in the spinner in case this time value does not
-         * match any of the predefined ones in the array.
-         *
-         * @param timeNamesResource The time entry names array
-         * @param timeValuesResource The time entry values array
-         * @param customTime Current time value that might be one of the
-         *            predefined values or a totally custom value
-         */
-        public PulseSpeedAdapter(int timeNamesResource, int timeValuesResource, Integer customTime) {
-            this(timeNamesResource, timeValuesResource);
-
-            // Check if we also need to add the custom value entry
-            if (getTimePosition(customTime) == -1) {
-                times.add(new Pair<String, Integer>(getContext().getResources()
-                        .getString(R.string.custom_time), customTime));
-            }
-        }
-
-        /**
-         * Will return the position of the spinner entry with the specified
-         * time. Returns -1 if there is no such entry.
-         *
-         * @param time Time in ms
-         * @return Position of entry with given time or -1 if not found.
-         */
-        public int getTimePosition(Integer time) {
-            for (int position = 0; position < getCount(); ++position) {
-                if (getItem(position).second.equals(time)) {
-                    return position;
-                }
-            }
-
-            return -1;
-        }
-
-        @Override
-        public int getCount() {
-            return times.size();
-        }
-
-        @Override
-        public Pair<String, Integer> getItem(int position) {
-            return times.get(position);
-        }
-
-        @Override
-        public long getItemId(int position) {
-            return position;
-        }
-
-        @Override
-        public View getView(int position, View view, ViewGroup parent) {
-            if (view == null) {
-                view = mInflater.inflate(R.layout.pulse_time_item, parent, false);
-            }
-
-            Pair<String, Integer> entry = getItem(position);
-            ((TextView) view.findViewById(R.id.textViewName)).setText(entry.first);
-
-            return view;
-        }
-    }
-
-    @Override
-    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-    }
-
-    @Override
-    public void onTextChanged(CharSequence s, int start, int before, int count) {
-    }
-
-    @Override
-    public void afterTextChanged(Editable s) {
-        String hexColor = mHexColorInput.getText().toString();
-        if (!hexColor.isEmpty()) {
-            try {
-                int color = Color.parseColor('#' + hexColor);
-                if (!mColorPicker.isAlphaSliderVisible()) {
-                    color |= 0xFF000000; // set opaque
-                }
-                mColorPicker.setColor(color);
-                mNewColor.setColor(color);
-                updateLed();
-                if (mListener != null) {
-                    mListener.onColorChanged(color);
-                }
-            } catch (IllegalArgumentException ex) {
-                // Number format is incorrect, ignore
-            }
-        }
-    }
-
-    @Override
-    public void onFocusChange(View v, boolean hasFocus) {
-        if (!hasFocus) {
-            mHexColorInput.removeTextChangedListener(this);
-            InputMethodManager inputMethodManager = (InputMethodManager) getContext()
-                    .getSystemService(Activity.INPUT_METHOD_SERVICE);
-            inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
-        } else {
-            mHexColorInput.addTextChangedListener(this);
-        }
-    }
-
-
-
-}
diff --git a/src/org/omnirom/omnigears/batterylight/NotificationLightPreference.java b/src/org/omnirom/omnigears/batterylight/NotificationLightPreference.java
deleted file mode 100644
index 8869ba6..0000000
--- a/src/org/omnirom/omnigears/batterylight/NotificationLightPreference.java
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright (C) 2012 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.batterylight;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.res.Resources;
-import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.shapes.RectShape;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceViewHolder;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.settings.R;
-
-public class NotificationLightPreference extends Preference implements DialogInterface.OnDismissListener,
-            View.OnLongClickListener {
-
-    private static String TAG = "NotificationLightPreference";
-    public static final int DEFAULT_TIME = 1000;
-    public static final int DEFAULT_COLOR = 0xFFFFFF; //White
-
-    private ImageView mLightColorView;
-    private TextView mOnValueView;
-    private TextView mOffValueView;
-    private Resources mResources;
-    private int mColorValue;
-    private Dialog mDialog;
-
-    private int mOnValue;
-    private int mOffValue;
-    private boolean mOnOffChangeable;
-
-    public interface ItemLongClickListener {
-        public boolean onItemLongClick(String key);
-    }
-
-    private ItemLongClickListener mLongClickListener;
-
-    /**
-     * @param context
-     * @param attrs
-     */
-    public NotificationLightPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mColorValue = DEFAULT_COLOR;
-        mOnValue = DEFAULT_TIME;
-        mOffValue = DEFAULT_TIME;
-        mOnOffChangeable = context.getResources().getBoolean(
-                com.android.internal.R.bool.config_ledCanPulse);
-        init();
-    }
-
-    /**
-     * @param context
-     * @param color
-     * @param onValue
-     * @param offValue
-     */
-    public NotificationLightPreference(Context context, int color, int onValue, int offValue) {
-        super(context, null);
-        mColorValue = color;
-        mOnValue = onValue;
-        mOffValue = offValue;
-        mOnOffChangeable = context.getResources().getBoolean(
-                com.android.internal.R.bool.config_ledCanPulse);
-        init();
-    }
-
-    /**
-     * @param context
-     * @param color
-     * @param onValue
-     * @param offValue
-     */
-    public NotificationLightPreference(Context context, int color, int onValue, int offValue, boolean onOffChangeable) {
-        super(context, null);
-        mColorValue = color;
-        mOnValue = onValue;
-        mOffValue = offValue;
-        mOnOffChangeable = onOffChangeable;
-        init();
-    }
-
-    private void init() {
-        setLayoutResource(R.layout.preference_notification_light);
-        mResources = getContext().getResources();
-    }
-
-    public void setColor(int color) {
-        mColorValue = color;
-        updatePreferenceViews();
-    }
-
-    public int getColor() {
-        return mColorValue;
-    }
-
-    public void onStart() {
-        NotificationLightDialog d = (NotificationLightDialog) getDialog();
-        if (d != null) {
-            d.onStart();
-        }
-    }
-
-    public void onStop() {
-        NotificationLightDialog d = (NotificationLightDialog) getDialog();
-        if (d != null) {
-            d.onStop();
-        }
-    }
-
-    @Override
-    public boolean onLongClick(View view) {
-        if (mLongClickListener != null) {
-            return mLongClickListener.onItemLongClick(getKey());
-        }
-        return false;
-    }
-
-    public void setOnLongClickListener(ItemLongClickListener l) {
-        mLongClickListener = l;
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-
-        mLightColorView = (ImageView) holder.findViewById(R.id.light_color);
-        mOnValueView = (TextView) holder.findViewById(R.id.textViewTimeOnValue);
-        mOffValueView = (TextView) holder.findViewById(R.id.textViewTimeOffValue);
-
-        // Hide the summary text - it takes up too much space on a low res device
-        // We use it for storing the package name for the longClickListener
-        TextView tView = (TextView) holder.findViewById(android.R.id.summary);
-        tView.setVisibility(View.GONE);
-
-        // always show color even if we cannot change it
-        /*if (!getContext().getResources().getBoolean(com.android.internal.R.bool.config_multiColorNotificationLed)) {
-            mLightColorView.setVisibility(View.GONE);
-        }*/
-
-        updatePreferenceViews();
-        holder.itemView.setOnLongClickListener(this);
-    }
-
-    private void updatePreferenceViews() {
-        final int width = (int) mResources.getDimension(R.dimen.color_preference_width);
-        final int height = (int) mResources.getDimension(R.dimen.color_preference_height);
-
-        if (mLightColorView != null) {
-            mLightColorView.setEnabled(true);
-            mLightColorView.setImageDrawable(createRectShape(width, height, 0xFF000000 | mColorValue));
-        }
-        if (mOnValueView != null) {
-            mOnValueView.setText(mapLengthValue(mOnValue));
-        }
-        if (mOffValueView != null) {
-            if (mOnValue == 1 || !mOnOffChangeable) {
-                mOffValueView.setEnabled(false);
-            } else {
-                mOffValueView.setEnabled(true);
-            }
-            mOffValueView.setText(mapSpeedValue(mOffValue));
-        }
-    }
-
-    @Override
-    protected void onClick() {
-        if (mDialog != null && mDialog.isShowing()) return;
-        mDialog = getDialog();
-        mDialog.setOnDismissListener(this);
-        mDialog.show();
-    }
-
-    public Dialog getDialog() {
-        final NotificationLightDialog d = new NotificationLightDialog(getContext(),
-                0xFF000000 + mColorValue, mOnValue, mOffValue, mOnOffChangeable); 
-
-        d.setButton(AlertDialog.BUTTON_POSITIVE, mResources.getString(R.string.ok),
-                new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                mColorValue =  d.getColor() & 0x00FFFFFF; // strip alpha, led does not support it
-                mOnValue = d.getPulseSpeedOn();
-                mOffValue = d.getPulseSpeedOff();
-                updatePreferenceViews();
-                callChangeListener(this);
-            }
-        });
-        d.setButton(AlertDialog.BUTTON_NEGATIVE, mResources.getString(R.string.cancel),
-                new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-            }
-        });
-
-        return d;
-    }
-
-    private static ShapeDrawable createRectShape(int width, int height, int color) {
-        ShapeDrawable shape = new ShapeDrawable(new RectShape());
-        shape.setIntrinsicHeight(height);
-        shape.setIntrinsicWidth(width);
-        shape.getPaint().setColor(color);
-        return shape;
-    }
-
-    @Override
-    public void onDismiss(DialogInterface dialog) {
-        mDialog = null;
-    }
-
-    public void setAllValues(int color, int onValue, int offValue) {
-        mColorValue = color;
-        mOnValue = onValue;
-        mOffValue = offValue;
-        updatePreferenceViews();
-    }
-
-    public void setOnValue(int value) {
-        mOnValue = value;
-        updatePreferenceViews();
-    }
-
-    public int getOnValue() {
-        return mOnValue;
-    }
-
-    public void setOffValue(int value) {
-        mOffValue = value;
-        updatePreferenceViews();
-    }
-
-    public int getOffValue() {
-        return mOffValue;
-    }
-
-    private String mapLengthValue(Integer time) {
-        if (!mOnOffChangeable) {
-            return getContext().getResources().getString(R.string.pulse_length_always_on);
-        }
-        if (time == DEFAULT_TIME) {
-            return getContext().getResources().getString(R.string.default_time);
-        }
-
-        String[] timeNames = getContext().getResources().getStringArray(R.array.notification_pulse_length_entries);
-        String[] timeValues = getContext().getResources().getStringArray(R.array.notification_pulse_length_values);
-
-        for (int i = 0; i < timeValues.length; i++) {
-            if (Integer.decode(timeValues[i]).equals(time)) {
-                return timeNames[i];
-            }
-        }
-
-        return getContext().getResources().getString(R.string.custom_time);
-    }
-
-    private String mapSpeedValue(Integer time) {
-        if (time == DEFAULT_TIME) {
-            return getContext().getResources().getString(R.string.default_time);
-        }
-
-        String[] timeNames = getContext().getResources().getStringArray(R.array.notification_pulse_speed_entries);
-        String[] timeValues = getContext().getResources().getStringArray(R.array.notification_pulse_speed_values);
-
-        for (int i = 0; i < timeValues.length; i++) {
-            if (Integer.decode(timeValues[i]).equals(time)) {
-                return timeNames[i];
-            }
-        }
-
-        return getContext().getResources().getString(R.string.custom_time);
-    }
-
-}
diff --git a/src/org/omnirom/omnigears/batterylight/NotificationLightSettings.java b/src/org/omnirom/omnigears/batterylight/NotificationLightSettings.java
deleted file mode 100644
index 677c0f6..0000000
--- a/src/org/omnirom/omnigears/batterylight/NotificationLightSettings.java
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- * Copyright (C) 2012 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.batterylight;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceGroup;
-import android.support.v7.preference.PreferenceScreen;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ListView;
-
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.internal.util.omni.ColorUtils;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-
-import org.omnirom.omnigears.preference.SystemSettingSwitchPreference;
-import org.omnirom.omnigears.preference.AppSelectListPreference;
-import org.omnirom.omnigears.preference.AppSelectListPreference.PackageItem;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class NotificationLightSettings extends SettingsPreferenceFragment implements
-        Preference.OnPreferenceChangeListener, NotificationLightPreference.ItemLongClickListener, Indexable {
-    private static final String TAG = "NotificationLightSettings";
-
-    private static final String NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR = "notification_light_pulse_default_color";
-    private static final String NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_ON = "notification_light_pulse_default_led_on";
-    private static final String NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF = "notification_light_pulse_default_led_off";
-    private static final String DEFAULT_PREF = "default";
-    public static final int ACTION_TEST = 0;
-    public static final int ACTION_DELETE = 1;
-    private static final int MENU_ADD = 0;
-    private static final int DIALOG_APPS = 0;
-
-    private int mDefaultColor;
-    private int mDefaultLedOn;
-    private int mDefaultLedOff;
-    private PackageManager mPackageManager;
-    private PreferenceGroup mApplicationPrefList;
-    private SystemSettingSwitchPreference mEnabledPref;
-    private SystemSettingSwitchPreference mScreenOnLightsPref;
-    private SystemSettingSwitchPreference mCustomEnabledPref;
-    private SystemSettingSwitchPreference mAutoGenerateColors;
-    private NotificationLightPreference mDefaultPref;
-    private Menu mMenu;
-    private AppSelectListPreference mPackageAdapter;
-    private String mPackageList;
-    private Map<String, Package> mPackages;
-    private boolean mMultiColorLed;
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsEvent.OMNI_SETTINGS;
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.notification_light_settings);
-
-        PreferenceScreen prefSet = getPreferenceScreen();
-        Resources resources = getResources();
-
-        PreferenceGroup mAdvancedPrefs = (PreferenceGroup) prefSet.findPreference("advanced_section");
-
-        // Get the system defined default notification color
-        mDefaultColor =
-                resources.getColor(com.android.internal.R.color.config_defaultNotificationColor, null);
-
-        mDefaultLedOn = resources.getInteger(
-                com.android.internal.R.integer.config_defaultNotificationLedOn);
-        mDefaultLedOff = resources.getInteger(
-                com.android.internal.R.integer.config_defaultNotificationLedOff);
-
-        mEnabledPref = (SystemSettingSwitchPreference)
-                findPreference(Settings.System.NOTIFICATION_LIGHT_PULSE);
-        mEnabledPref.setOnPreferenceChangeListener(this);
-
-        mDefaultPref = (NotificationLightPreference) findPreference(DEFAULT_PREF);
-        mDefaultPref.setOnPreferenceChangeListener(this);
-
-        mScreenOnLightsPref = (SystemSettingSwitchPreference)
-                findPreference(Settings.System.NOTIFICATION_LIGHT_SCREEN_ON);
-        mScreenOnLightsPref.setOnPreferenceChangeListener(this);
-
-        mAutoGenerateColors = (SystemSettingSwitchPreference)
-                findPreference(Settings.System.NOTIFICATION_LIGHT_COLOR_AUTO);
-
-        // Advanced light settings
-        mCustomEnabledPref = (SystemSettingSwitchPreference)
-                findPreference(Settings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_ENABLE);
-        mCustomEnabledPref.setOnPreferenceChangeListener(this);
-
-        mApplicationPrefList = (PreferenceGroup) findPreference("applications_list");
-        mApplicationPrefList.setOrderingAsAdded(false);
-
-        // Get launch-able applications
-        mPackageManager = getPackageManager();
-        mPackageAdapter = new AppSelectListPreference(getActivity());
-
-        mPackages = new HashMap<String, Package>();
-        setHasOptionsMenu(true);
-
-        mMultiColorLed = resources.getBoolean(com.android.internal.R.bool.config_multiColorNotificationLed);
-        if (!mMultiColorLed) {
-            resetColors();
-            PreferenceGroup mGeneralPrefs = (PreferenceGroup) prefSet.findPreference("general_section");
-            mGeneralPrefs.removePreference(mAutoGenerateColors);
-        } else {
-            mAutoGenerateColors.setOnPreferenceChangeListener(this);
-        }
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        refreshDefault();
-        refreshCustomApplicationPrefs();
-        getActivity().invalidateOptionsMenu();
-    }
-
-    private void refreshDefault() {
-        ContentResolver resolver = getContentResolver();
-        int color = Settings.System.getInt(resolver,
-                Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR, mDefaultColor);
-        int timeOn = Settings.System.getInt(resolver,
-                Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_ON, mDefaultLedOn);
-        int timeOff = Settings.System.getInt(resolver,
-                Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF, mDefaultLedOff);
-
-        mDefaultPref.setAllValues(color, timeOn, timeOff);
-
-        mApplicationPrefList = (PreferenceGroup) findPreference("applications_list");
-        mApplicationPrefList.setOrderingAsAdded(false);
-    }
-
-    private void refreshCustomApplicationPrefs() {
-        Context context = getActivity();
-
-        if (!parsePackageList()) {
-            return;
-        }
-
-        // Add the Application Preferences
-        if (mApplicationPrefList != null) {
-            mApplicationPrefList.removeAll();
-
-            for (Package pkg : mPackages.values()) {
-                try {
-                    PackageInfo info = mPackageManager.getPackageInfo(pkg.name,
-                            PackageManager.GET_META_DATA);
-                    NotificationLightPreference pref =
-                            new NotificationLightPreference(context, pkg.color, pkg.timeon, pkg.timeoff);
-
-                    pref.setKey(pkg.name);
-                    pref.setTitle(info.applicationInfo.loadLabel(mPackageManager));
-                    pref.setIcon(info.applicationInfo.loadIcon(mPackageManager));
-                    pref.setPersistent(false);
-                    pref.setOnPreferenceChangeListener(this);
-                    pref.setOnLongClickListener(this);
-                    mApplicationPrefList.addPreference(pref);
-                } catch (NameNotFoundException e) {
-                    // Do nothing
-                }
-            }
-
-            /* Display a pref explaining how to add apps */
-            if (mApplicationPrefList.getPreferenceCount() == 0) {
-                String summary = getResources().getString(
-                        R.string.notification_light_no_apps_summary);
-                String useCustom = getResources().getString(
-                        R.string.notification_light_use_custom);
-                Preference pref = new Preference(context);
-                pref.setSummary(String.format(summary, useCustom));
-                pref.setEnabled(false);
-                mApplicationPrefList.addPreference(pref);
-            }
-        }
-    }
-
-    private int getInitialColorForPackage(String packageName) {
-        boolean autoColor = Settings.System.getInt(getContentResolver(),
-                Settings.System.NOTIFICATION_LIGHT_COLOR_AUTO, mMultiColorLed ? 1 : 0) == 1;;
-        int color = mDefaultColor;
-        if (autoColor) {
-            try {
-                Drawable icon = mPackageManager.getApplicationIcon(packageName);
-                color = ColorUtils.getIconColorFromDrawable(icon);
-            } catch (NameNotFoundException e) {
-                // shouldn't happen, but just return default
-            }
-        }
-        return color;
-    }
-
-    private void addCustomApplicationPref(String packageName) {
-        Package pkg = mPackages.get(packageName);
-        if (pkg == null) {
-            int color = getInitialColorForPackage(packageName);
-            pkg = new Package(packageName, color, mDefaultLedOn, mDefaultLedOff);
-            mPackages.put(packageName, pkg);
-            savePackageList(false);
-            refreshCustomApplicationPrefs();
-        }
-    }
-
-    private void removeCustomApplicationPref(String packageName) {
-        if (mPackages.remove(packageName) != null) {
-            savePackageList(false);
-            refreshCustomApplicationPrefs();
-        }
-    }
-
-    private boolean parsePackageList() {
-        final String baseString = Settings.System.getString(getContentResolver(),
-                Settings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_VALUES);
-
-        if (TextUtils.equals(mPackageList, baseString)) {
-            return false;
-        }
-
-        mPackageList = baseString;
-        mPackages.clear();
-
-        if (baseString != null) {
-            final String[] array = TextUtils.split(baseString, "\\|");
-            for (String item : array) {
-                if (TextUtils.isEmpty(item)) {
-                    continue;
-                }
-                Package pkg = Package.fromString(item);
-                if (pkg != null) {
-                    mPackages.put(pkg.name, pkg);
-                }
-            }
-        }
-
-        return true;
-    }
-
-    private void savePackageList(boolean preferencesUpdated) {
-        List<String> settings = new ArrayList<String>();
-        for (Package app : mPackages.values()) {
-            settings.add(app.toString());
-        }
-        final String value = TextUtils.join("|", settings);
-        if (preferencesUpdated) {
-            mPackageList = value;
-        }
-        Settings.System.putString(getContentResolver(),
-                                  Settings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_VALUES, value);
-    }
-
-    /**
-     * Updates the default or package specific notification settings.
-     *
-     * @param packageName Package name of application specific settings to update
-     * @param color
-     * @param timeon
-     * @param timeoff
-     */
-    protected void updateValues(String packageName, Integer color, Integer timeon, Integer timeoff) {
-        ContentResolver resolver = getContentResolver();
-
-        if (packageName.equals(DEFAULT_PREF)) {
-            Settings.System.putInt(resolver, Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR, color);
-            Settings.System.putInt(resolver, Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_ON, timeon);
-            Settings.System.putInt(resolver, Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF, timeoff);
-            refreshDefault();
-            return;
-        }
-
-        // Find the custom package and sets its new values
-        Package app = mPackages.get(packageName);
-        if (app != null) {
-            app.color = color;
-            app.timeon = timeon;
-            app.timeoff = timeoff;
-            savePackageList(true);
-        }
-    }
-
-    protected void resetColors() {
-        ContentResolver resolver = getContentResolver();
-
-        // Reset to the framework default colors
-        Settings.System.putInt(resolver, Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR, mDefaultColor);
-
-        refreshDefault();
-    }
-
-    public boolean onItemLongClick(final String key) {
-        final NotificationLightPreference pref =
-                (NotificationLightPreference) getPreferenceScreen().findPreference(key);
-
-        if (mApplicationPrefList.findPreference(key) == null) {
-            return false;
-        }
-
-        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
-                .setTitle(R.string.dialog_delete_title)
-                .setMessage(R.string.dialog_delete_message)
-                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-                    @Override
-                    public void onClick(DialogInterface dialog, int which) {
-                        removeCustomApplicationPref(key);
-                    }
-                })
-                .setNegativeButton(android.R.string.cancel, null);
-
-        builder.show();
-        return true;
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object objValue) {
-        if (preference == mEnabledPref || preference == mCustomEnabledPref ||
-            preference == mScreenOnLightsPref ||
-            preference == mAutoGenerateColors) {
-            getActivity().invalidateOptionsMenu();
-        } else {
-            NotificationLightPreference lightPref = (NotificationLightPreference) preference;
-            updateValues(lightPref.getKey(), lightPref.getColor(),
-                    lightPref.getOnValue(), lightPref.getOffValue());
-        }
-
-        return true;
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        mMenu = menu;
-        mMenu.add(0, MENU_ADD, 0, R.string.profiles_add)
-                .setIcon(R.drawable.ic_menu_add_white)
-                .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
-    }
-
-    @Override
-    public void onPrepareOptionsMenu(Menu menu) {
-        boolean enableAddButton = mEnabledPref.isChecked() && mCustomEnabledPref.isChecked();
-        menu.findItem(MENU_ADD).setVisible(enableAddButton);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case MENU_ADD:
-                showDialog(DIALOG_APPS);
-                return true;
-        }
-        return false;
-    }
-
-    /**
-     * Utility classes and supporting methods
-     */
-    @Override
-    public Dialog onCreateDialog(int id) {
-        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-        final Dialog dialog;
-        switch (id) {
-            case DIALOG_APPS:
-                final ListView list = new ListView(getActivity());
-                list.setAdapter(mPackageAdapter);
-
-                builder.setTitle(R.string.profile_choose_app);
-                builder.setView(list);
-                dialog = builder.create();
-
-                list.setOnItemClickListener(new OnItemClickListener() {
-                    @Override
-                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                        // Add empty application definition, the user will be able to edit it later
-                        PackageItem info = (PackageItem) parent.getItemAtPosition(position);
-                        addCustomApplicationPref(info.packageName);
-                        dialog.cancel();
-                    }
-                });
-                break;
-            default:
-                dialog = null;
-        }
-        return dialog;
-    }
-
-    /**
-     * Application class
-     */
-    private static class Package {
-        public String name;
-        public Integer color;
-        public Integer timeon;
-        public Integer timeoff;
-
-        /**
-         * Stores all the application values in one call
-         * @param name
-         * @param color
-         * @param timeon
-         * @param timeoff
-         */
-        public Package(String name, Integer color, Integer timeon, Integer timeoff) {
-            this.name = name;
-            this.color = color;
-            this.timeon = timeon;
-            this.timeoff = timeoff;
-        }
-
-        public String toString() {
-            StringBuilder builder = new StringBuilder();
-            builder.append(name);
-            builder.append("=");
-            builder.append(color);
-            builder.append(";");
-            builder.append(timeon);
-            builder.append(";");
-            builder.append(timeoff);
-            return builder.toString();
-        }
-
-        public static Package fromString(String value) {
-            if (TextUtils.isEmpty(value)) {
-                return null;
-            }
-            String[] app = value.split("=", -1);
-            if (app.length != 2)
-                return null;
-
-            String[] values = app[1].split(";", -1);
-            if (values.length != 3)
-                return null;
-
-            try {
-                Package item = new Package(app[0], Integer.parseInt(values[0]), Integer
-                        .parseInt(values[1]), Integer.parseInt(values[2]));
-                return item;
-            } catch (NumberFormatException e) {
-                return null;
-            }
-        }
-
-    }
-
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
-                        boolean enabled) {
-                    ArrayList<SearchIndexableResource> result =
-                            new ArrayList<SearchIndexableResource>();
-
-                    SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.notification_light_settings;
-                    result.add(sir);
-                    return result;
-                }
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    ArrayList<String> result = new ArrayList<String>();
-                    return result;
-                }
-            };
-}
diff --git a/src/org/omnirom/omnigears/interfacesettings/BarsSettings.java b/src/org/omnirom/omnigears/interfacesettings/BarsSettings.java
deleted file mode 100644
index 97d624f..0000000
--- a/src/org/omnirom/omnigears/interfacesettings/BarsSettings.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- *  Copyright (C) 2015 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- *
-*/
-package org.omnirom.omnigears.interfacesettings;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
-import android.net.TrafficStats;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.support.v7.preference.CheckBoxPreference;
-import android.support.v7.preference.ListPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceGroup;
-import android.support.v7.preference.PreferenceScreen;
-import android.support.v7.preference.PreferenceCategory;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
-import android.util.Log;
-
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.R;
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.internal.util.omni.DeviceUtils;
-import com.android.settings.Utils;
-import com.android.settings.dashboard.SummaryLoader;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-
-import static android.provider.Settings.System.STATUS_BAR_BRIGHTNESS_CONTROL;
-import static android.provider.Settings.System.DOUBLE_TAP_SLEEP_GESTURE;
-
-import java.util.List;
-import java.util.ArrayList;
-
-import org.omnirom.omnigears.preference.SystemCheckBoxPreference;
-import org.omnirom.omnigears.preference.SeekBarPreference;
-
-public class BarsSettings extends SettingsPreferenceFragment implements
-        Preference.OnPreferenceChangeListener, Indexable {
-    private static final String TAG = "BarsSettings";
-
-    private static final String NETWORK_TRAFFIC_ROOT = "category_network_traffic";
-    private static final String NAVIGATIONBAR_ROOT = "category_navigationbar";
-    private static final String TABLET_NAVIGATION_BAR = "enable_tablet_navigation";
-    private static final String QUICK_SETTTINGS_PULLDOWN = "status_bar_quick_qs_pulldown";
-
-    private ListPreference mQuickPulldown;
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsEvent.OMNI_SETTINGS;
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.bars_settings);
-
-        PreferenceScreen prefScreen = getPreferenceScreen();
-
-        // Navigationbar catagory will not be displayed when the device is not a tablet
-        // or the device has physical keys
-        //if ((!DeviceUtils.deviceSupportNavigationBar(getActivity())) || DeviceUtils.isPhone(getActivity())) {
-        //    prefScreen.removePreference(findPreference(NAVIGATIONBAR_ROOT));
-        //}
-
-        // TrafficStats will return UNSUPPORTED if the device does not support it.
-        if (TrafficStats.getTotalTxBytes() == TrafficStats.UNSUPPORTED ||
-                TrafficStats.getTotalRxBytes() == TrafficStats.UNSUPPORTED) {
-            prefScreen.removePreference(findPreference(NETWORK_TRAFFIC_ROOT));
-        }
-
-        //mQuickPulldown = (ListPreference) findPreference(QUICK_SETTTINGS_PULLDOWN);
-        //mQuickPulldown.setOnPreferenceChangeListener(this);
-        //int quickPullDownValue = Settings.System.getInt(getContentResolver(), Settings.System.STATUS_BAR_QUICK_QS_PULLDOWN, 0);
-        //mQuickPulldown.setValue(String.valueOf(quickPullDownValue));
-        //updatePulldownSummary(quickPullDownValue);
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        //if (preference == mQuickPulldown) {
-        //    int quickPullDownValue = Integer.valueOf((String) newValue);
-        //    Settings.System.putInt(getContentResolver(),
-         //           Settings.System.STATUS_BAR_QUICK_QS_PULLDOWN, quickPullDownValue);
-         //   updatePulldownSummary(quickPullDownValue);
-        //}
-        return true;
-    }
-
-    /*
-    private void updatePulldownSummary(int value) {
-        Resources res = getResources();
-
-        if (value == 0) {
-            // quick pulldown deactivated
-            mQuickPulldown.setSummary(res.getString(R.string.status_bar_quick_qs_pulldown_off));
-        } else {
-            String direction = res.getString(value == 2
-                    ? R.string.status_bar_quick_qs_pulldown_summary_left
-                    : R.string.status_bar_quick_qs_pulldown_summary_right);
-            mQuickPulldown.setSummary(res.getString(R.string.status_bar_quick_qs_pulldown_summary, direction));
-        }
-    }
-*/
-
-    public static String toString(boolean bool, String trueString, String falseString) {
-        return bool ? trueString : falseString;
-    }
-
-    private static class SummaryProvider implements SummaryLoader.SummaryProvider {
-        private final Context mContext;
-        private final SummaryLoader mLoader;
-
-        private SummaryProvider(Context context, SummaryLoader loader) {
-            mContext = context;
-            mLoader = loader;
-        }
-
-        @Override
-        public void setListening(boolean listening) {
-            if (listening) {
-                updateSummary();
-            }
-        }
-
-        private void updateSummary() {
-            final String summary_text, brightness_summary, dt2s_summary;
-            boolean brightnessEnabled = Settings.System.getInt(mContext.getContentResolver(),
-                    STATUS_BAR_BRIGHTNESS_CONTROL, 0) == 1;
-            boolean dt2sEnabled = Settings.System.getInt(mContext.getContentResolver(),
-                    DOUBLE_TAP_SLEEP_GESTURE, 0) == 1;
-            brightness_summary = brightnessEnabled ? mContext.getString(R.string.bars_brightness_enabled_summary)
-                    : mContext.getString(R.string.bars_brightness_disabled_summary);
-            dt2s_summary = dt2sEnabled ? mContext.getString(R.string.bars_dt2s_enabled_summary)
-                    : mContext.getString(R.string.bars_dt2s_disabled_summary);
-            summary_text = String.format("%s%s%s", brightness_summary, " / ", dt2s_summary);
-            mLoader.setSummary(this, summary_text);
-        }
-    }
-
-    public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
-            = new SummaryLoader.SummaryProviderFactory() {
-        @Override
-        public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
-                                                                   SummaryLoader summaryLoader) {
-            return new SummaryProvider(activity, summaryLoader);
-        }
-    };
-
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
-                        boolean enabled) {
-                    ArrayList<SearchIndexableResource> result =
-                            new ArrayList<SearchIndexableResource>();
-
-                    SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.bars_settings;
-                    result.add(sir);
-
-                    return result;
-                }
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    ArrayList<String> result = new ArrayList<String>();
-                    if ((!DeviceUtils.deviceSupportNavigationBar(context)) ||
-                            DeviceUtils.isPhone(context)) {
-                        result.add(TABLET_NAVIGATION_BAR);
-                    }
-                    return result;
-                }
-            };
-}
diff --git a/src/org/omnirom/omnigears/interfacesettings/GlobalActionsSettings.java b/src/org/omnirom/omnigears/interfacesettings/GlobalActionsSettings.java
deleted file mode 100644
index 8af88ae..0000000
--- a/src/org/omnirom/omnigears/interfacesettings/GlobalActionsSettings.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- *  Copyright (C) 2016 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- *
-*/
-package org.omnirom.omnigears.interfacesettings;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.UserManager;
-import android.support.v7.preference.ListPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceCategory;
-import android.support.v7.preference.PreferenceManager;
-import android.support.v7.preference.PreferenceScreen;
-import android.support.v7.preference.Preference.OnPreferenceChangeListener;
-import android.support.v14.preference.SwitchPreference;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-
-import java.util.List;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-
-import org.omnirom.omnigears.preference.SecureSettingSwitchPreference;
-
-public class GlobalActionsSettings extends SettingsPreferenceFragment implements
-        Preference.OnPreferenceChangeListener, Indexable {
-    private static final String TAG = "GlobalActionsSettings";
-    private static final String POWER_MENU_ANIMATIONS = "power_menu_animations";
-    private static final String GLOBAL_ACTIONS_LIST = "global_actions_list";
-
-    private LinkedHashMap<String, Boolean> mGlobalActionsMap;
-    private ListPreference mPowerMenuAnimations;
-    private SecureSettingSwitchPreference mAdvancedReboot;
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsEvent.OMNI_SETTINGS;
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.global_actions);
-
-        final PreferenceScreen prefScreen = getPreferenceScreen();
-        final ContentResolver contentResolver = getContext().getContentResolver();
-
-        final String[] defaultActions = getContext().getResources().getStringArray(
-                com.android.internal.R.array.config_globalActionsList);
-        final List<String> defaultActionsList = Arrays.asList(defaultActions);
-
-        final String[] allActions = getContext().getResources().getStringArray(
-                com.android.internal.R.array.values_globalActionsList);
-        final List<String> allActionssList = new ArrayList<String>(Arrays.asList(allActions));
-
-        final String enabledActions = Settings.System.getString(contentResolver,
-                Settings.System.GLOBAL_ACTIONS_LIST);
-
-        mPowerMenuAnimations = (ListPreference) findPreference(POWER_MENU_ANIMATIONS);
-        mPowerMenuAnimations.setValue(String.valueOf(Settings.System.getInt(
-                getContentResolver(), Settings.System.POWER_MENU_ANIMATIONS, 0)));
-        mPowerMenuAnimations.setSummary(mPowerMenuAnimations.getEntry());
-        mPowerMenuAnimations.setOnPreferenceChangeListener(this);
-
-        mAdvancedReboot = (SecureSettingSwitchPreference)
-                findPreference(Settings.Secure.ADVANCED_REBOOT);
-        mAdvancedReboot.setOnPreferenceChangeListener(this);
-
-        List<String> enabledActionsList = null;
-        if (enabledActions != null) {
-            enabledActionsList = Arrays.asList(enabledActions.split(","));
-        }
-
-        mGlobalActionsMap = new LinkedHashMap<String, Boolean>();
-        for (String actionKey : allActions) {
-            if (enabledActionsList != null) {
-                mGlobalActionsMap.put(actionKey, enabledActionsList.contains(actionKey));
-            } else {
-                mGlobalActionsMap.put(actionKey, defaultActionsList.contains(actionKey));
-            }
-        }
-        final UserManager um = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
-        boolean multiUser = um.isUserSwitcherEnabled();
-
-        PreferenceCategory actionList = (PreferenceCategory) findPreference(GLOBAL_ACTIONS_LIST);
-        int count = actionList.getPreferenceCount();
-        List<Preference> toRemoveList = new ArrayList<>();
-        for (int i = 0; i < count; i++) {
-            Preference p = actionList.getPreference(i);
-            if (p instanceof SwitchPreference) {
-                SwitchPreference action = (SwitchPreference) p;
-                String key = action.getKey();
-                if (!allActionssList.contains(key)) {
-                    toRemoveList.add(action);
-                    continue;
-                }
-                if (key.equals("users") && !multiUser) {
-                    toRemoveList.add(action);
-                    continue;
-                }
-                action.setChecked(mGlobalActionsMap.get(key));
-            }
-        }
-        for (Preference p : toRemoveList) {
-            actionList.removePreference(p);
-        }
-    }
-
-    @Override
-    public boolean onPreferenceTreeClick(Preference preference) {
-        if (preference instanceof SwitchPreference) {
-            SwitchPreference action = (SwitchPreference) preference;
-            mGlobalActionsMap.put(action.getKey(), action.isChecked());
-
-            List<String> enabledActionsList = new ArrayList<String>();
-            for (String actionKey : mGlobalActionsMap.keySet()) {
-                Boolean checked = mGlobalActionsMap.get(actionKey);
-                if (checked) {
-                    enabledActionsList.add(actionKey);
-                }
-            }
-            setList(enabledActionsList);
-            return true;
-        }
-        return super.onPreferenceTreeClick(preference);
-    }
-
-    private void setList(List<String> actionList) {
-        final ContentResolver contentResolver = getContext().getContentResolver();
-        Settings.System.putString(contentResolver, Settings.System.GLOBAL_ACTIONS_LIST,
-                TextUtils.join(",", actionList));
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object objValue) {
-         boolean result = false;
-         if (preference instanceof ListPreference) {
-             if (preference == mPowerMenuAnimations) {
-                Settings.System.putInt(getContentResolver(), Settings.System.POWER_MENU_ANIMATIONS,
-                        Integer.valueOf((String) objValue));
-                mPowerMenuAnimations.setValue(String.valueOf(objValue));
-                mPowerMenuAnimations.setSummary(mPowerMenuAnimations.getEntry());
-                return true;
-             }
-         } else if (preference instanceof SecureSettingSwitchPreference) {
-             if (preference == mAdvancedReboot) {
-                boolean value = (Boolean) objValue;
-                Settings.Secure.putInt(getContentResolver(), Settings.Secure.ADVANCED_REBOOT,
-                        value ? 1:0);
-                Settings.Secure.putInt(getContentResolver(), Settings.Secure.GLOBAL_ACTION_DNAA,
-                        value ? 1:0);
-             }
-             return true;
-         }
-         return result;
-    }
-
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
-                        boolean enabled) {
-                    ArrayList<SearchIndexableResource> result =
-                            new ArrayList<SearchIndexableResource>();
-
-                    SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.global_actions;
-                    result.add(sir);
-
-                    return result;
-                }
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    ArrayList<String> result = new ArrayList<String>();
-                    return result;
-                }
-            };
-}
diff --git a/src/org/omnirom/omnigears/interfacesettings/LockscreenSettings.java b/src/org/omnirom/omnigears/interfacesettings/LockscreenSettings.java
deleted file mode 100644
index cadb101..0000000
--- a/src/org/omnirom/omnigears/interfacesettings/LockscreenSettings.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- *  Copyright (C) 2015 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- *
-*/
-package org.omnirom.omnigears.interfacesettings;
-
-import android.app.Activity;
-import android.app.WallpaperManager;
-import android.content.Context;
-import android.content.ContentResolver;
-import android.content.Intent;
-import android.graphics.Color;
-import android.graphics.Typeface;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v7.preference.CheckBoxPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-import android.support.v14.preference.SwitchPreference;
-import android.provider.Settings;
-import android.provider.SearchIndexableResource;
-import android.text.TextUtils;
-import android.util.Log;
-import android.widget.Toast;
-
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.settings.dashboard.SummaryLoader;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-
-import org.omnirom.omnigears.R;
-import org.omnirom.omnigears.preference.AppMultiSelectListPreference;
-import org.omnirom.omnigears.preference.FontPreference;
-import org.omnirom.omnigears.preference.NumberPickerPreference;
-import org.omnirom.omnigears.preference.ColorPickerPreference;
-//import org.omnirom.omnigears.ui.ShortcutDialog;
-
-
-import static android.provider.Settings.Secure.LOCK_QS_DISABLED;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-
-public class LockscreenSettings extends SettingsPreferenceFragment implements
-        Preference.OnPreferenceChangeListener, Indexable {
-
-    private static final String KEY_CLOCK_FONT = "lockscreen_clock_font";
-    private static final String KEY_CLOCK_COLOR = "lockscreen_clock_color";
-    private static final String KEY_CLOCK_SIZE = "lockscreen_clock_size";
-    private static final String KEY_CLOCK_SHADOW = "lockscreen_clock_shadow";
-    private static final String KEY_CLOCK_DISPLAY = "lockscreen_clock_display";
-    private static final String KEY_CLOCK_DISPLAY_TIME = "lockscreen_clock_display_time";
-    private static final String KEY_CLOCK_DISPLAY_DATE = "lockscreen_clock_display_date";
-    private static final String KEY_CLOCK_DISPLAY_ALARM = "lockscreen_clock_display_alarm";
-    //private static final String KEY_SHORTCUTS = "lockscreen_shortcuts";
-
-    private FontPreference mClockFont;
-    private NumberPickerPreference mClockSize;
-    private ColorPickerPreference mClockColor;
-    private CheckBoxPreference mClockDisplayTime;
-    private CheckBoxPreference mClockDisplayDate;
-    private CheckBoxPreference mClockDisplayAlarm;
-    private CheckBoxPreference mClockShadow;
-
-    //private Preference mShortcuts;
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsEvent.OMNI_SETTINGS;
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.lockscreen_settings);
-
-        mClockFont = (FontPreference) findPreference(KEY_CLOCK_FONT);
-        mClockFont.setOnPreferenceChangeListener(this);
-        mClockColor = (ColorPickerPreference) findPreference(KEY_CLOCK_COLOR);
-        mClockColor.setOnPreferenceChangeListener(this);
-        mClockSize = (NumberPickerPreference) findPreference(KEY_CLOCK_SIZE);
-        mClockSize.setOnPreferenceChangeListener(this);
-        mClockSize.setMinValue(40);
-        mClockSize.setMaxValue(140);
-        mClockDisplayTime = (CheckBoxPreference) findPreference(KEY_CLOCK_DISPLAY_TIME);
-        mClockDisplayDate = (CheckBoxPreference) findPreference(KEY_CLOCK_DISPLAY_DATE);
-        mClockDisplayAlarm = (CheckBoxPreference) findPreference(KEY_CLOCK_DISPLAY_ALARM);
-        mClockShadow = (CheckBoxPreference) findPreference(KEY_CLOCK_SHADOW);
-
-        ContentResolver resolver = getActivity().getContentResolver();
-        int color = Settings.System.getInt(resolver, Settings.System.LOCK_CLOCK_COLOR, Color.WHITE);
-        mClockColor.setColor(color);
-        String hexColor = String.format("#%08X", color);
-        mClockColor.setSummary(hexColor);
-
-        int defaultSize = Settings.System.getInt(resolver, Settings.System.LOCK_CLOCK_DEFAULT_SIZE, 80);
-        int size = Settings.System.getInt(resolver, Settings.System.LOCK_CLOCK_SIZE, defaultSize);
-        mClockSize.setValue(size);
-        mClockSize.setSummary(String.valueOf(size));
-
-        String font = Settings.System.getString(resolver, Settings.System.LOCK_CLOCK_FONT);
-        if (font != null) {
-            mClockFont.setValue(font);
-            int valueIndex = mClockFont.findIndexOfValue(font);
-            if (valueIndex != -1) {
-                mClockFont.setSummary(mClockFont.getEntries()[valueIndex]);
-            }
-        } else {
-            // default for "sans-serif-light"
-            mClockFont.setSummary("Roboto Light");
-        }
-
-        final int clockDisplay = Settings.System.getInt(resolver,
-                Settings.System.LOCK_CLOCK_DISPLAY, Settings.System.LOCK_CLOCK_ALL);
-        mClockDisplayTime.setChecked((clockDisplay & Settings.System.LOCK_CLOCK_TIME) == Settings.System.LOCK_CLOCK_TIME);
-        mClockDisplayDate.setChecked((clockDisplay & Settings.System.LOCK_CLOCK_DATE) == Settings.System.LOCK_CLOCK_DATE);
-        mClockDisplayAlarm.setChecked((clockDisplay & Settings.System.LOCK_CLOCK_ALARM) == Settings.System.LOCK_CLOCK_ALARM);
-        mClockShadow.setChecked((clockDisplay & Settings.System.LOCK_CLOCK_SHADOW) == Settings.System.LOCK_CLOCK_SHADOW);
-        //mShortcuts = findPreference(KEY_SHORTCUTS);
-    }
-
-    @Override
-    public boolean onPreferenceTreeClick(Preference preference) {
-        ContentResolver resolver = getContentResolver();
-        if (preference == mClockDisplayTime) {
-            Settings.System.putInt(resolver,
-                    Settings.System.LOCK_CLOCK_DISPLAY, getCurrentClockDisplayValue());
-            return true;
-        } else if (preference == mClockDisplayDate) {
-            Settings.System.putInt(resolver,
-                    Settings.System.LOCK_CLOCK_DISPLAY, getCurrentClockDisplayValue());
-            return true;
-        } else if (preference == mClockDisplayAlarm) {
-            Settings.System.putInt(resolver,
-                    Settings.System.LOCK_CLOCK_DISPLAY, getCurrentClockDisplayValue());
-            return true;
-        } else if (preference == mClockShadow) {
-            Settings.System.putInt(resolver,
-                    Settings.System.LOCK_CLOCK_DISPLAY, getCurrentClockDisplayValue());
-            return true;
-        } /*else if (preference == mShortcuts) {
-            ShortcutDialog d = new ShortcutDialog(getContext());
-            d.show();
-            return true;
-        }*/
-
-        return super.onPreferenceTreeClick(preference);
-    }
-
-    private int getCurrentClockDisplayValue() {
-        return (mClockDisplayTime.isChecked() ? Settings.System.LOCK_CLOCK_TIME : 0) +
-            (mClockDisplayDate.isChecked() ? Settings.System.LOCK_CLOCK_DATE : 0) +
-            (mClockDisplayAlarm.isChecked() ? Settings.System.LOCK_CLOCK_ALARM : 0) +
-            (mClockShadow.isChecked() ? Settings.System.LOCK_CLOCK_SHADOW : 0);
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        ContentResolver resolver = getContentResolver();
-        if (preference == mClockFont) {
-            String value = (String) newValue;
-            int valueIndex = mClockFont.findIndexOfValue(value);
-            mClockFont.setSummary(mClockFont.getEntries()[valueIndex]);
-            Settings.System.putString(resolver, Settings.System.LOCK_CLOCK_FONT, value);
-        } else if (preference == mClockColor) {
-            String hexColor = String.format("#%08X", mClockColor.getColor());
-            mClockColor.setSummary(hexColor);
-            Settings.System.putInt(resolver, Settings.System.LOCK_CLOCK_COLOR, mClockColor.getColor());
-        } else if (preference == mClockSize) {
-            Integer value = (Integer) newValue;
-            mClockSize.setSummary(String.valueOf(value));
-            Settings.System.putInt(resolver, Settings.System.LOCK_CLOCK_SIZE, value);
-        }
-
-        return true;
-    }
-
-    private static class SummaryProvider implements SummaryLoader.SummaryProvider {
-        private final Context mContext;
-        private final SummaryLoader mLoader;
-
-        private SummaryProvider(Context context, SummaryLoader loader) {
-            mContext = context;
-            mLoader = loader;
-        }
-
-        @Override
-        public void setListening(boolean listening) {
-            if (listening) {
-                updateSummary();
-            }
-        }
-
-        private void updateSummary() {
-            boolean enabled = Settings.Secure.getInt(mContext.getContentResolver(),
-                    LOCK_QS_DISABLED, 0) == 1;
-            mLoader.setSummary(this, mContext.getString( enabled ? R.string.lockscreen_qs_enabled_summary
-                        : R.string.lockscreen_qs_disabled_summary));
-        }
-    }
-
-    public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
-            = new SummaryLoader.SummaryProviderFactory() {
-        @Override
-        public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
-                                                                   SummaryLoader summaryLoader) {
-            return new SummaryProvider(activity, summaryLoader);
-        }
-    };
-
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
-                        boolean enabled) {
-                    ArrayList<SearchIndexableResource> result =
-                            new ArrayList<SearchIndexableResource>();
-
-                    SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.lockscreen_settings;
-                    result.add(sir);
-
-                    return result;
-                }
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    ArrayList<String> result = new ArrayList<String>();
-                    return result;
-                }
-            };
-}
diff --git a/src/org/omnirom/omnigears/interfacesettings/NetworkTraffic.java b/src/org/omnirom/omnigears/interfacesettings/NetworkTraffic.java
deleted file mode 100644
index d9331cb..0000000
--- a/src/org/omnirom/omnigears/interfacesettings/NetworkTraffic.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- *  Copyright (C) 2015 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.omnirom.omnigears.interfacesettings;
-
-import android.app.AlertDialog;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.res.Resources;
-import android.net.TrafficStats;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.support.v7.preference.ListPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceGroup;
-import android.support.v7.preference.PreferenceScreen;
-import android.support.v7.preference.PreferenceCategory;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
-
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.R;
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.internal.util.omni.DeviceUtils;
-import com.android.settings.Utils;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-
-import java.util.List;
-import java.util.ArrayList;
-
-import org.omnirom.omnigears.preference.SeekBarPreference;
-import org.omnirom.omnigears.preference.SystemCheckBoxPreference;
-
-public class NetworkTraffic extends SettingsPreferenceFragment implements
-        Preference.OnPreferenceChangeListener, Indexable {
-    private static final String TAG = "NetworkTraffic";
-
-    private static final String NETWORK_TRAFFIC_STATE = "network_traffic_state";
-    private static final String NETWORK_TRAFFIC_UNIT = "network_traffic_unit";
-    private static final String NETWORK_TRAFFIC_PERIOD = "network_traffic_period";
-    private static final String NETWORK_TRAFFIC_AUTOHIDE = "network_traffic_autohide";
-    private static final String NETWORK_TRAFFIC_AUTOHIDE_THRESHOLD = "network_traffic_autohide_threshold";
-
-    private ListPreference mNetTrafficState;
-    private ListPreference mNetTrafficUnit;
-    private ListPreference mNetTrafficPeriod;
-    private SystemCheckBoxPreference mNetTrafficAutohide;
-    private SeekBarPreference mNetTrafficAutohideThreshold;
-
-    private int mNetTrafficVal;
-    private int MASK_UP;
-    private int MASK_DOWN;
-    private int MASK_UNIT;
-    private int MASK_PERIOD;
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsEvent.OMNI_SETTINGS;
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.network_traffic);
-        loadResources();
-
-        PreferenceScreen prefScreen = getPreferenceScreen();
-        ContentResolver resolver = getActivity().getContentResolver();
-
-        mNetTrafficState = (ListPreference) prefScreen.findPreference(NETWORK_TRAFFIC_STATE);
-        mNetTrafficUnit = (ListPreference) prefScreen.findPreference(NETWORK_TRAFFIC_UNIT);
-        mNetTrafficPeriod = (ListPreference) prefScreen.findPreference(NETWORK_TRAFFIC_PERIOD);
-        mNetTrafficAutohide = (SystemCheckBoxPreference) prefScreen.findPreference(NETWORK_TRAFFIC_AUTOHIDE);
-        mNetTrafficAutohideThreshold = (SeekBarPreference) prefScreen.findPreference(NETWORK_TRAFFIC_AUTOHIDE_THRESHOLD);
-
-        // TrafficStats will return UNSUPPORTED if the device does not support it.
-        if (TrafficStats.getTotalTxBytes() != TrafficStats.UNSUPPORTED &&
-                TrafficStats.getTotalRxBytes() != TrafficStats.UNSUPPORTED) {
-            mNetTrafficVal = Settings.System.getInt(resolver, Settings.System.NETWORK_TRAFFIC_STATE, 0);
-            int intIndex = mNetTrafficVal & (MASK_UP + MASK_DOWN);
-            intIndex = mNetTrafficState.findIndexOfValue(String.valueOf(intIndex));
-
-            mNetTrafficState.setValueIndex(intIndex >= 0 ? intIndex : 0);
-            mNetTrafficState.setSummary(mNetTrafficState.getEntry());
-            mNetTrafficState.setOnPreferenceChangeListener(this);
-
-            mNetTrafficUnit.setValueIndex(getBit(mNetTrafficVal, MASK_UNIT) ? 1 : 0);
-            mNetTrafficUnit.setSummary(mNetTrafficUnit.getEntry());
-            mNetTrafficUnit.setOnPreferenceChangeListener(this);
-
-            int period = (mNetTrafficVal & MASK_PERIOD) >>> 16;
-            int periodIndex = mNetTrafficPeriod.findIndexOfValue(String.valueOf(period));
-            mNetTrafficPeriod.setValueIndex(periodIndex >= 0 ? periodIndex : 1);
-            mNetTrafficPeriod.setSummary(mNetTrafficPeriod.getEntry());
-            mNetTrafficPeriod.setOnPreferenceChangeListener(this);
-
-            int netTrafficAutohideThreshold = Settings.System.getInt(getContentResolver(),
-                    Settings.System.NETWORK_TRAFFIC_AUTOHIDE_THRESHOLD, 10);
-            mNetTrafficAutohideThreshold.setValue(netTrafficAutohideThreshold / 1);
-            mNetTrafficAutohideThreshold.setOnPreferenceChangeListener(this);
-
-            mNetTrafficUnit.setEnabled(intIndex != 0);
-            mNetTrafficPeriod.setEnabled(intIndex != 0);
-            mNetTrafficAutohide.setEnabled(intIndex != 0);
-            mNetTrafficAutohideThreshold.setEnabled(intIndex != 0);
-        }
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        ContentResolver resolver = getActivity().getContentResolver();
-        if (preference == mNetTrafficState) {
-            int intState = Integer.valueOf((String)newValue);
-            mNetTrafficVal = setBit(mNetTrafficVal, MASK_UP, getBit(intState, MASK_UP));
-            mNetTrafficVal = setBit(mNetTrafficVal, MASK_DOWN, getBit(intState, MASK_DOWN));
-            Settings.System.putInt(resolver, Settings.System.NETWORK_TRAFFIC_STATE, mNetTrafficVal);
-            int index = mNetTrafficState.findIndexOfValue((String) newValue);
-            mNetTrafficState.setSummary(mNetTrafficState.getEntries()[index]);
-            mNetTrafficUnit.setEnabled(intState != 0);
-            mNetTrafficPeriod.setEnabled(intState != 0);
-            mNetTrafficAutohide.setEnabled(intState != 0);
-            mNetTrafficAutohideThreshold.setEnabled(intState != 0);
-        } else if (preference == mNetTrafficUnit) {
-            // 1 = Display as Byte/s; default is bit/s
-            mNetTrafficVal = setBit(mNetTrafficVal, MASK_UNIT, ((String)newValue).equals("1"));
-            Settings.System.putInt(resolver, Settings.System.NETWORK_TRAFFIC_STATE, mNetTrafficVal);
-            int index = mNetTrafficUnit.findIndexOfValue((String) newValue);
-            mNetTrafficUnit.setSummary(mNetTrafficUnit.getEntries()[index]);
-        } else if (preference == mNetTrafficPeriod) {
-            int intState = Integer.valueOf((String)newValue);
-            mNetTrafficVal = setBit(mNetTrafficVal, MASK_PERIOD, false) + (intState << 16);
-            Settings.System.putInt(resolver, Settings.System.NETWORK_TRAFFIC_STATE, mNetTrafficVal);
-            int index = mNetTrafficPeriod.findIndexOfValue((String) newValue);
-            mNetTrafficPeriod.setSummary(mNetTrafficPeriod.getEntries()[index]);
-        } else if (preference == mNetTrafficAutohideThreshold) {
-            int threshold = (Integer) newValue;
-            Settings.System.putInt(getActivity().getContentResolver(),
-                    Settings.System.NETWORK_TRAFFIC_AUTOHIDE_THRESHOLD, threshold * 1);
-        }
-
-        return true;
-    }
-
-    private void loadResources() {
-        Resources resources = getActivity().getResources();
-        MASK_UP = resources.getInteger(R.integer.maskUp);
-        MASK_DOWN = resources.getInteger(R.integer.maskDown);
-        MASK_UNIT = resources.getInteger(R.integer.maskUnit);
-        MASK_PERIOD = resources.getInteger(R.integer.maskPeriod);
-    }
-
-    // intMask should only have the desired bit(s) set
-    private int setBit(int intNumber, int intMask, boolean blnState) {
-        if (blnState) {
-            return (intNumber | intMask);
-        }
-        return (intNumber & ~intMask);
-    }
-
-    private boolean getBit(int intNumber, int intMask) {
-        return (intNumber & intMask) == intMask;
-    }
-
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
-                        boolean enabled) {
-                    ArrayList<SearchIndexableResource> result =
-                            new ArrayList<SearchIndexableResource>();
-
-                    SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.network_traffic;
-                    result.add(sir);
-
-                    return result;
-                }
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    ArrayList<String> result = new ArrayList<String>();
-                    return result;
-                }
-            };
-}
diff --git a/src/org/omnirom/omnigears/interfacesettings/StatusbarBatterySettings.java b/src/org/omnirom/omnigears/interfacesettings/StatusbarBatterySettings.java
deleted file mode 100644
index 00dc9d6..0000000
--- a/src/org/omnirom/omnigears/interfacesettings/StatusbarBatterySettings.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- *  Copyright (C) 2015 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- *
-*/
-package org.omnirom.omnigears.interfacesettings;
-
-import android.app.AlertDialog;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.res.Resources;
-import android.net.TrafficStats;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.support.v7.preference.CheckBoxPreference;
-import android.support.v7.preference.ListPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceGroup;
-import android.support.v7.preference.PreferenceScreen;
-import android.support.v7.preference.PreferenceCategory;
-import android.support.v14.preference.PreferenceFragment;
-import android.support.v14.preference.SwitchPreference;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.internal.util.omni.DeviceUtils;
-import com.android.settings.Utils;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-
-import com.android.internal.util.omni.OmniSwitchConstants;
-import com.android.internal.util.omni.PackageUtils;
-
-import java.util.List;
-import java.util.ArrayList;
-
-import org.omnirom.omnigears.preference.ColorPickerPreference;
-import org.omnirom.omnigears.preference.SeekBarPreference;
-import org.omnirom.omnigears.preference.SystemCheckBoxPreference;
-
-public class StatusbarBatterySettings extends SettingsPreferenceFragment implements
-        Preference.OnPreferenceChangeListener, Indexable {
-    private static final String TAG = "StatusbarBatterySettings";
-
-    private static final String STATUSBAR_BATTERY_STYLE = "statusbar_battery_style";
-    private static final String STATUSBAR_BATTERY_PERCENT = "statusbar_battery_percent";
-    private static final String STATUSBAR_CHARGING_COLOR = "statusbar_battery_charging_color";
-    private static final String STATUSBAR_BATTERY_PERCENT_INSIDE = "statusbar_battery_percent_inside";
-    private static final String STATUSBAR_BATTERY_SHOW_BOLT = "statusbar_battery_charging_image";
-    private static final String STATUSBAR_BATTERY_ENABLE = "statusbar_battery_enable";
-    private static final String STATUSBAR_CATEGORY_CHARGING = "statusbar_category_charging";
-
-    private ListPreference mBatteryStyle;
-    private CheckBoxPreference mBatteryPercent;
-    private ColorPickerPreference mChargingColor;
-    private CheckBoxPreference mPercentInside;
-    private CheckBoxPreference mShowBolt;
-    private int mShowPercent;
-    private int mBatteryStyleValue;
-    private SwitchPreference mBatteryEnable;
-    private int mShowBattery = 1;
-    private PreferenceCategory mChargingCategory;
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsEvent.OMNI_SETTINGS;
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.statusbar_battery_settings);
-
-        PreferenceScreen prefScreen = getPreferenceScreen();
-        ContentResolver resolver = getActivity().getContentResolver();
-
-        mBatteryStyle = (ListPreference) findPreference(STATUSBAR_BATTERY_STYLE);
-        mBatteryStyleValue = Settings.System.getInt(resolver,
-                Settings.System.STATUSBAR_BATTERY_STYLE, 0);
-
-        mBatteryStyle.setValue(Integer.toString(mBatteryStyleValue));
-        mBatteryStyle.setSummary(mBatteryStyle.getEntry());
-        mBatteryStyle.setOnPreferenceChangeListener(this);
-
-        mBatteryPercent = (CheckBoxPreference) findPreference(STATUSBAR_BATTERY_PERCENT);
-        mShowPercent = Settings.System.getInt(resolver,
-                Settings.System.STATUSBAR_BATTERY_PERCENT, 0);
-        mBatteryPercent.setChecked(mShowPercent == 1);
-        mBatteryPercent.setOnPreferenceChangeListener(this);
-
-        mChargingColor = (ColorPickerPreference) prefScreen.findPreference(STATUSBAR_CHARGING_COLOR);
-        // TODO 0xFFFFFFFF is not really the default - but the config value R.color.batterymeter_charge_color is not exposed
-        int chargingColor = Settings.System.getInt(resolver, Settings.System.STATUSBAR_BATTERY_CHARGING_COLOR, 0xFFFFFFFF);
-        mChargingColor.setColor(chargingColor);
-        String hexColor = String.format("#%08X", chargingColor);
-        mChargingColor.setSummary(hexColor);
-        mChargingColor.setOnPreferenceChangeListener(this);
-
-        mPercentInside = (CheckBoxPreference) findPreference(STATUSBAR_BATTERY_PERCENT_INSIDE);
-
-        mShowBolt = (CheckBoxPreference) findPreference(STATUSBAR_BATTERY_SHOW_BOLT);
-
-        mBatteryEnable = (SwitchPreference) findPreference(STATUSBAR_BATTERY_ENABLE);
-        mShowBattery = Settings.System.getInt(resolver,
-                Settings.System.STATUSBAR_BATTERY_ENABLE, 1);
-        mBatteryEnable.setChecked(mShowBattery == 1);
-        mBatteryEnable.setOnPreferenceChangeListener(this);
-
-        mChargingCategory = (PreferenceCategory) findPreference(STATUSBAR_CATEGORY_CHARGING);
-        updateEnablement();
-    }
-
-    @Override
-    public boolean onPreferenceTreeClick(Preference preference) {
-        // If we didn't handle it, let preferences handle it.
-        return super.onPreferenceTreeClick(preference);
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        ContentResolver resolver = getActivity().getContentResolver();
-        if (preference == mBatteryStyle) {
-            mBatteryStyleValue = Integer.valueOf((String) newValue);
-            int index = mBatteryStyle.findIndexOfValue((String) newValue);
-            mBatteryStyle.setSummary(
-                    mBatteryStyle.getEntries()[index]);
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.STATUSBAR_BATTERY_STYLE, mBatteryStyleValue);
-            updateEnablement();
-        } else if (preference == mBatteryPercent) {
-            Boolean value = (Boolean) newValue;
-            mShowPercent = value ? 1 : 0;
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.STATUSBAR_BATTERY_PERCENT, value ? 1 : 0);
-            updateEnablement();
-        } else if (preference == mChargingColor) {
-            String hexColor = String.format("#%08X", mChargingColor.getColor());
-            mChargingColor.setSummary(hexColor);
-            Settings.System.putInt(resolver,
-                    Settings.System.STATUSBAR_BATTERY_CHARGING_COLOR, mChargingColor.getColor());
-        } else if (preference == mBatteryEnable) {
-            Boolean value = (Boolean) newValue;
-            mShowBattery = value ? 1 : 0;
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.STATUSBAR_BATTERY_ENABLE, value ? 1 : 0);
-            updateEnablement();
-        }
-        return true;
-    }
-
-    private void updateEnablement() {
-        if (mBatteryStyleValue == 5) {
-            // theme
-            mPercentInside.setEnabled(false);
-            mShowBolt.setEnabled(false);
-            mBatteryPercent.setEnabled(false);
-        } else {
-            mPercentInside.setEnabled(mShowBattery != 0 && mBatteryStyleValue != 3 && mBatteryStyleValue != 4 && mShowPercent != 0);
-            mShowBolt.setEnabled(mBatteryStyleValue != 3 && mBatteryStyleValue != 4);
-            mBatteryPercent.setEnabled(mShowBattery != 0 && mBatteryStyleValue != 3);
-        }
-        mBatteryStyle.setEnabled(mShowBattery != 0);
-        mChargingCategory.setEnabled(mShowBattery != 0 && mBatteryStyleValue != 5);
-    }
-
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
-                        boolean enabled) {
-                    ArrayList<SearchIndexableResource> result =
-                            new ArrayList<SearchIndexableResource>();
-
-                    SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.statusbar_battery_settings;
-                    result.add(sir);
-
-                    return result;
-                }
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    ArrayList<String> result = new ArrayList<String>();
-                    return result;
-                }
-            };
-}
diff --git a/src/org/omnirom/omnigears/interfacesettings/StyleSettings.java b/src/org/omnirom/omnigears/interfacesettings/StyleSettings.java
index e03c886..7d91b13 100644
--- a/src/org/omnirom/omnigears/interfacesettings/StyleSettings.java
+++ b/src/org/omnirom/omnigears/interfacesettings/StyleSettings.java
@@ -44,55 +44,32 @@
 
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.R;
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.internal.util.omni.DeviceUtils;
-import com.android.internal.util.omni.PackageUtils;
 import com.android.settings.Utils;
 import com.android.settings.dashboard.SummaryLoader;
+import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 
-import static android.provider.Settings.System.STATUS_BAR_BRIGHTNESS_CONTROL;
-import static android.provider.Settings.System.DOUBLE_TAP_SLEEP_GESTURE;
-
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Collections;
 
-import org.omnirom.omnigears.preference.SystemCheckBoxPreference;
-import org.omnirom.omnigears.preference.SeekBarPreference;
+import org.omnirom.omnigears.OmniDashboardFragment;
+import org.omnirom.omnigears.PackageUtils;
 
 public class StyleSettings extends SettingsPreferenceFragment implements
         Preference.OnPreferenceChangeListener, Indexable {
     private static final String TAG = "StyleSettings";
-
-    private static final String CUSTOM_HEADER_IMAGE = "status_bar_custom_header";
-    private static final String DAYLIGHT_HEADER_PACK = "daylight_header_pack";
-    private static final String DEFAULT_HEADER_PACKAGE = "com.android.systemui";
-    private static final String CUSTOM_HEADER_IMAGE_SHADOW = "status_bar_custom_header_shadow";
-    private static final String CUSTOM_HEADER_PROVIDER = "custom_header_provider";
-    private static final String CUSTOM_HEADER_BROWSE = "custom_header_browse";
     private static final String CUSTOM_WALL_BROWSE = "custom_wall_browse";
-    private static final String STATUS_BAR_CUSTOM_HEADER = "status_bar_custom_header";
-    private static final String KEY_NIGHT_MODE = "night_mode";
-    private static final String KEY_OMS_APP = "oms_app";
-    private static final String KEY_OMNI_THEME = "omni_theme";
-    private static final String KEY_CATEGORY_THEMING = "category_theming";
-
-    private ListPreference mDaylightHeaderPack;
-    private SeekBarPreference mHeaderShadow;
-    private ListPreference mHeaderProvider;
-    private String mDaylightHeaderProvider;
-    private PreferenceScreen mHeaderBrowse;
-    private PreferenceScreen mWallBrowse;
-    private ListPreference mNightModePreference;
-    private Preference mOmsApp;
+    
+    private Preference mWallBrowse;
 
     @Override
-    protected int getMetricsCategory() {
-        return MetricsEvent.OMNI_SETTINGS;
+    public int getMetricsCategory() {
+        return OmniDashboardFragment.ACTION_SETTINGS_OMNI;
+        //return MetricsProto.MetricsEvent.ACTION_SETTINGS_OMNI;
     }
 
     @Override
@@ -100,186 +77,20 @@
         super.onCreate(savedInstanceState);
         addPreferencesFromResource(R.xml.style_settings);
 
-        PreferenceScreen prefScreen = getPreferenceScreen();
-
-        String settingHeaderPackage = Settings.System.getString(getContentResolver(),
-                Settings.System.STATUS_BAR_DAYLIGHT_HEADER_PACK);
-        if (settingHeaderPackage == null) {
-            settingHeaderPackage = DEFAULT_HEADER_PACKAGE;
-        }
-        mDaylightHeaderPack = (ListPreference) findPreference(DAYLIGHT_HEADER_PACK);
-
-        List<String> entries = new ArrayList<String>();
-        List<String> values = new ArrayList<String>();
-        getAvailableHeaderPacks(entries, values);
-        mDaylightHeaderPack.setEntries(entries.toArray(new String[entries.size()]));
-        mDaylightHeaderPack.setEntryValues(values.toArray(new String[values.size()]));
-
-        int valueIndex = mDaylightHeaderPack.findIndexOfValue(settingHeaderPackage);
-        if (valueIndex == -1) {
-            // no longer found
-            settingHeaderPackage = DEFAULT_HEADER_PACKAGE;
-            Settings.System.putString(getContentResolver(),
-                    Settings.System.STATUS_BAR_DAYLIGHT_HEADER_PACK, settingHeaderPackage);
-            valueIndex = mDaylightHeaderPack.findIndexOfValue(settingHeaderPackage);
-        }
-        mDaylightHeaderPack.setValueIndex(valueIndex >= 0 ? valueIndex : 0);
-        mDaylightHeaderPack.setSummary(mDaylightHeaderPack.getEntry());
-        mDaylightHeaderPack.setOnPreferenceChangeListener(this);
-
-        mHeaderShadow = (SeekBarPreference) findPreference(CUSTOM_HEADER_IMAGE_SHADOW);
-        final int headerShadow = Settings.System.getInt(getContentResolver(),
-                Settings.System.STATUS_BAR_CUSTOM_HEADER_SHADOW, 80);
-        mHeaderShadow.setValue((int)(((double) headerShadow / 255) * 100));
-        mHeaderShadow.setOnPreferenceChangeListener(this);
-
-        mDaylightHeaderProvider = getResources().getString(R.string.daylight_header_provider);
-        String providerName = Settings.System.getString(getContentResolver(),
-                Settings.System.STATUS_BAR_CUSTOM_HEADER_PROVIDER);
-        if (providerName == null) {
-            providerName = mDaylightHeaderProvider;
-        }
-        mHeaderProvider = (ListPreference) findPreference(CUSTOM_HEADER_PROVIDER);
-        valueIndex = mHeaderProvider.findIndexOfValue(providerName);
-        mHeaderProvider.setValueIndex(valueIndex >= 0 ? valueIndex : 0);
-        mHeaderProvider.setSummary(mHeaderProvider.getEntry());
-        mHeaderProvider.setOnPreferenceChangeListener(this);
-        mDaylightHeaderPack.setEnabled(providerName.equals(mDaylightHeaderProvider));
-
-        mHeaderBrowse = (PreferenceScreen) findPreference(CUSTOM_HEADER_BROWSE);
-        mHeaderBrowse.setEnabled(isBrowseHeaderAvailable());
-        mHeaderBrowse.setTitle(valueIndex == 0 ? R.string.custom_header_browse_title : R.string.custom_header_pick_title);
-        mHeaderBrowse.setSummary(valueIndex == 0 ? R.string.custom_header_browse_summary_new : R.string.custom_header_pick_summary);
-
-        mWallBrowse = (PreferenceScreen) findPreference(CUSTOM_WALL_BROWSE);
+        mWallBrowse = findPreference(CUSTOM_WALL_BROWSE);
         mWallBrowse.setEnabled(isBrowseWallsAvailable());
-
-        mNightModePreference = (ListPreference) findPreference(KEY_NIGHT_MODE);
-        if (mNightModePreference != null) {
-            final UiModeManager uiManager = (UiModeManager) getSystemService(
-                    Context.UI_MODE_SERVICE);
-            final int currentNightMode = uiManager.getNightMode();
-            mNightModePreference.setValue(String.valueOf(currentNightMode));
-            mNightModePreference.setOnPreferenceChangeListener(this);
-        }
-        mOmsApp = (Preference) findPreference(KEY_OMS_APP);
-
-        Preference omniTheme = findPreference(KEY_OMNI_THEME);
-        if (omniTheme != null) {
-            PreferenceCategory themePrefs = (PreferenceCategory) findPreference(KEY_CATEGORY_THEMING);
-            if (themePrefs != null && !PackageUtils.isAvailableApp("org.omnirom.daynight", getActivity())
-                    && !PackageUtils.isAvailableApp("org.omnirom.substratum", getActivity())) {
-                themePrefs.removePreference(omniTheme);
-            }
-        }
     }
 
     @Override
     public boolean onPreferenceTreeClick(Preference preference) {
-        if (preference == mOmsApp) {
-            Intent omsIntent = getPackageManager().getLaunchIntentForPackage("projekt.substratum");
-            if (omsIntent != null) {
-                startActivity(omsIntent);
-            } else {
-                downloadOmsApp();
-            }
-            return true;
-        } else if (preference == mHeaderBrowse) {
-            String providerName = Settings.System.getString(getContentResolver(),
-                Settings.System.STATUS_BAR_CUSTOM_HEADER_PROVIDER);
-            if (providerName == null) {
-                providerName = mDaylightHeaderProvider;
-            }
-            int valueIndex = mHeaderProvider.findIndexOfValue(providerName);
-            startHeaderActivity(valueIndex == 0 ? false : true);
-            return true;
-        }
         return super.onPreferenceTreeClick(preference);
     }
 
     @Override
     public boolean onPreferenceChange(Preference preference, Object newValue) {
-        if (preference == mDaylightHeaderPack) {
-            String value = (String) newValue;
-            Settings.System.putString(getContentResolver(),
-                    Settings.System.STATUS_BAR_DAYLIGHT_HEADER_PACK, value);
-            int valueIndex = mDaylightHeaderPack.findIndexOfValue(value);
-            mDaylightHeaderPack.setSummary(mDaylightHeaderPack.getEntries()[valueIndex]);
-        } else if (preference == mHeaderShadow) {
-            Integer headerShadow = (Integer) newValue;
-            int realHeaderValue = (int) (((double) headerShadow / 100) * 255);
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.STATUS_BAR_CUSTOM_HEADER_SHADOW, realHeaderValue);
-        } else if (preference == mHeaderProvider) {
-            String value = (String) newValue;
-            Settings.System.putString(getContentResolver(),
-                    Settings.System.STATUS_BAR_CUSTOM_HEADER_PROVIDER, value);
-            int valueIndex = mHeaderProvider.findIndexOfValue(value);
-            mHeaderProvider.setSummary(mHeaderProvider.getEntries()[valueIndex]);
-            mDaylightHeaderPack.setEnabled(value.equals(mDaylightHeaderProvider));
-            mHeaderBrowse.setTitle(valueIndex == 0 ? R.string.custom_header_browse_title : R.string.custom_header_pick_title);
-            mHeaderBrowse.setSummary(valueIndex == 0 ? R.string.custom_header_browse_summary_new : R.string.custom_header_pick_summary);
-        } else if (preference == mNightModePreference) {
-            try {
-                final int value = Integer.parseInt((String) newValue);
-                final UiModeManager uiManager = (UiModeManager) getSystemService(
-                        Context.UI_MODE_SERVICE);
-                uiManager.setNightMode(value);
-            } catch (NumberFormatException e) {
-                Log.e(TAG, "could not persist night mode setting", e);
-            }
-        }
         return true;
     }
 
-    private void getAvailableHeaderPacks(List<String> entries, List<String> values) {
-        String defaultLabel = null;
-        Map<String, String> headerMap = new HashMap<String, String>();
-        Intent i = new Intent();
-        PackageManager packageManager = getPackageManager();
-        i.setAction("org.omnirom.DaylightHeaderPack");
-        for (ResolveInfo r : packageManager.queryIntentActivities(i, 0)) {
-            String packageName = r.activityInfo.packageName;
-            String label = r.activityInfo.loadLabel(getPackageManager()).toString();
-            if (label == null) {
-                label = r.activityInfo.packageName;
-            }
-            if (packageName.equals(DEFAULT_HEADER_PACKAGE)) {
-                defaultLabel = label;
-            } else {
-                headerMap.put(label, packageName);
-            }
-        }
-        i.setAction("org.omnirom.DaylightHeaderPack1");
-        for (ResolveInfo r : packageManager.queryIntentActivities(i, 0)) {
-            String packageName = r.activityInfo.packageName;
-            String label = r.activityInfo.loadLabel(getPackageManager()).toString();
-            if (r.activityInfo.name.endsWith(".theme")) {
-                continue;
-            }
-            if (label == null) {
-                label = packageName;
-            }
-            headerMap.put(label, packageName  + "/" + r.activityInfo.name);
-        }
-        List<String> labelList = new ArrayList<String>();
-        labelList.addAll(headerMap.keySet());
-        Collections.sort(labelList);
-        for (String label : labelList) {
-            entries.add(label);
-            values.add(headerMap.get(label));
-        }
-        entries.add(0, defaultLabel);
-        values.add(0, DEFAULT_HEADER_PACKAGE);
-    }
-
-    private boolean isBrowseHeaderAvailable() {
-        PackageManager pm = getPackageManager();
-        Intent browse = new Intent();
-        browse.setClassName("org.omnirom.omnistyle", "org.omnirom.omnistyle.BrowseHeaderActivity");
-        return pm.resolveActivity(browse, 0) != null;
-    }
-
     private boolean isBrowseWallsAvailable() {
         PackageManager pm = getPackageManager();
         Intent browse = new Intent();
@@ -287,44 +98,6 @@
         return pm.resolveActivity(browse, 0) != null;
     }
 
-    public static String toString(boolean bool, String trueString, String falseString) {
-        return bool ? trueString : falseString;
-    }
-
-    private static class SummaryProvider implements SummaryLoader.SummaryProvider {
-        private final Context mContext;
-        private final SummaryLoader mLoader;
-
-        private SummaryProvider(Context context, SummaryLoader loader) {
-            mContext = context;
-            mLoader = loader;
-        }
-
-        @Override
-        public void setListening(boolean listening) {
-            if (listening) {
-                updateSummary();
-            }
-        }
-
-        private void updateSummary() {
-            final String summary_text;
-            boolean customHeaderEnabled = Settings.System.getInt(mContext.getContentResolver(),
-                    STATUS_BAR_CUSTOM_HEADER, 0) == 1;
-            mLoader.setSummary(this, customHeaderEnabled ? mContext.getString(R.string.style_enabled_summary)
-                    : mContext.getString(R.string.style_disabled_summary));
-        }
-    }
-
-    public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
-            = new SummaryLoader.SummaryProviderFactory() {
-        @Override
-        public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
-                                                                   SummaryLoader summaryLoader) {
-            return new SummaryProvider(activity, summaryLoader);
-        }
-    };
-
     public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
@@ -346,15 +119,4 @@
                 }
             };
 
-    private void downloadOmsApp(){
-        Intent omsDownloadIntent = new Intent(Intent.ACTION_VIEW);
-        omsDownloadIntent.setData(Uri.parse("https://play.google.com/store/apps/details?id=projekt.substratum"));
-        startActivity(omsDownloadIntent);
-    }
-
-    private void startHeaderActivity(boolean pick) {
-        Intent headerIntent = new Intent();
-        headerIntent.setClassName("org.omnirom.omnistyle", pick ? "org.omnirom.omnistyle.PickHeaderActivity" : "org.omnirom.omnistyle.BrowseHeaderActivity");
-        startActivity(headerIntent);
-    }
 }
diff --git a/src/org/omnirom/omnigears/lightssettings/LightsSettings.java b/src/org/omnirom/omnigears/lightssettings/LightsSettings.java
deleted file mode 100644
index e157183..0000000
--- a/src/org/omnirom/omnigears/lightssettings/LightsSettings.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- *  Copyright (C) 2017 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- *
-*/
-
-package org.omnirom.omnigears.lightssettings;
-
-import android.app.Activity;
-import android.content.Context;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.provider.SearchIndexableResource;
-import android.support.v7.preference.Preference;
-import android.preference.PreferenceActivity;
-import android.support.v7.preference.PreferenceCategory;
-import android.preference.PreferenceScreen;
-
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.Utils;
-import com.android.settings.dashboard.SummaryLoader;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Index;
-import com.android.settings.search.Indexable;
-
-import java.util.Arrays;
-import java.util.List;
-
-import static android.provider.Settings.System.NOTIFICATION_LIGHT_PULSE;
-
-public class LightsSettings extends SettingsPreferenceFragment implements
-        Preference.OnPreferenceChangeListener, Indexable {
-    private static final String TAG = "ligths_settings";
-
-     private boolean mChargingLedsEnabled;
-     private boolean mNotificationLedsEnabled;
-
-     private PreferenceCategory mChargingLedsCategory;
-     private Preference mChargingLeds;
-     private Preference mNotificationLeds;
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsEvent.OMNI_SETTINGS;
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.lights_settings);
-
-         mChargingLedsEnabled = (getResources().getBoolean(
-                         com.android.internal.R.bool.config_intrusiveBatteryLed));
-         mNotificationLedsEnabled = (getResources().getBoolean(
-                         com.android.internal.R.bool.config_intrusiveNotificationLed));
-         mChargingLedsCategory = (PreferenceCategory) findPreference("leds");
-         mChargingLeds = (Preference) findPreference("charging_light");
-         mNotificationLeds = (Preference) findPreference("notification_light");
-         if (mChargingLeds != null && mNotificationLeds != null) {
-             if (!mChargingLedsEnabled) {
-                 mChargingLedsCategory.removePreference(mChargingLeds);
-             } else if (!mNotificationLedsEnabled) {
-                 mChargingLedsCategory.removePreference(mNotificationLeds);
-            } else if (!mChargingLedsEnabled && !mNotificationLedsEnabled) {
-                 getPreferenceScreen().removePreference(mChargingLedsCategory);
-             }
-         }
-    }
-
-    public boolean onPreferenceChange(Preference preference, Object objValue) {
-        return true;
-    }
-
-    private static class SummaryProvider implements SummaryLoader.SummaryProvider {
-        private final Context mContext;
-        private final SummaryLoader mLoader;
-
-        private SummaryProvider(Context context, SummaryLoader loader) {
-            mContext = context;
-            mLoader = loader;
-        }
-
-        @Override
-        public void setListening(boolean listening) {
-            if (listening) {
-                updateSummary();
-            }
-        }
-
-        private void updateSummary() {
-            boolean enabled = Settings.System.getInt(mContext.getContentResolver(),
-                    NOTIFICATION_LIGHT_PULSE, 0) == 1;
-            mLoader.setSummary(this, mContext.getString( enabled ? R.string.led_category_summary_on
-                        : R.string.led_category_summary_off));
-        }
-    }
-
-    public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
-            = new SummaryLoader.SummaryProviderFactory() {
-        @Override
-        public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
-                                                                   SummaryLoader summaryLoader) {
-            return new SummaryProvider(activity, summaryLoader);
-        }
-    };
-
-    /**
-     * For Search.
-     */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-        new BaseSearchIndexProvider() {
-
-            @Override
-            public List<SearchIndexableResource> getXmlResourcesToIndex(
-                    Context context, boolean enabled) {
-                final SearchIndexableResource sir = new SearchIndexableResource(context);
-                sir.xmlResId = R.xml.lights_settings;
-                return Arrays.asList(sir);
-            }
-	};
-}
diff --git a/src/org/omnirom/omnigears/moresettings/MoreSettings.java b/src/org/omnirom/omnigears/moresettings/MoreSettings.java
deleted file mode 100644
index 7df302e..0000000
--- a/src/org/omnirom/omnigears/moresettings/MoreSettings.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *  Copyright (C) 2017 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- *
-*/
-
-package org.omnirom.omnigears.moresettings;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.support.v7.preference.ListPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceCategory;
-import android.support.v7.preference.PreferenceScreen;
-import android.provider.SearchIndexableResource;
-import android.util.Log;
-
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.internal.util.omni.PackageUtils;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.Utils;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-
-import java.util.List;
-import java.util.ArrayList;
-
-public class MoreSettings extends SettingsPreferenceFragment implements Indexable {
-    private static final String TAG = "MoreSettings";
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsEvent.OMNI_SETTINGS;
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.more_settings);
-        // check for disabled logcat app
-        Preference logcatApp = findPreference("logcat_app");
-        if (logcatApp != null) {
-            PreferenceCategory systemPrefs = (PreferenceCategory) findPreference("category_system");
-            if (systemPrefs != null && !PackageUtils.isAvailableApp("org.omnirom.logcat", getActivity())) {
-                systemPrefs.removePreference(logcatApp);
-            }
-        }
-    }
-
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
-                        boolean enabled) {
-                    ArrayList<SearchIndexableResource> result =
-                            new ArrayList<SearchIndexableResource>();
-
-                    SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.more_settings;
-                    result.add(sir);
-
-                    return result;
-                }
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    ArrayList<String> result = new ArrayList<String>();
-                    return result;
-                }
-    };
-}
diff --git a/src/org/omnirom/omnigears/moresettings/OmniJawsSettings.java b/src/org/omnirom/omnigears/moresettings/OmniJawsSettings.java
deleted file mode 100644
index 4b4daf4..0000000
--- a/src/org/omnirom/omnigears/moresettings/OmniJawsSettings.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- *  Copyright (C) 2017 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- *
-*/
-
-package org.omnirom.omnigears.moresettings;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v7.preference.ListPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceCategory;
-import android.support.v7.preference.PreferenceScreen;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.util.Log;
-
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.internal.util.omni.PackageUtils;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.Utils;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-
-import java.util.List;
-import java.util.ArrayList;
-
-public class OmniJawsSettings extends SettingsPreferenceFragment implements
-        Preference.OnPreferenceChangeListener, Indexable {
-    private static final String TAG = "OmniJawsSettings";
-    private static final String CATEGORY_WEATHER = "weather_category";
-    private static final String WEATHER_ICON_PACK = "weather_icon_pack";
-    private static final String DEFAULT_WEATHER_ICON_PACKAGE = "org.omnirom.omnijaws";
-    private static final String WEATHER_SERVICE_PACKAGE = "org.omnirom.omnijaws";
-    private static final String CHRONUS_ICON_PACK_INTENT = "com.dvtonder.chronus.ICON_PACK";
-
-    private PreferenceCategory mWeatherCategory;
-    private ListPreference mWeatherIconPack;
-    private String mWeatherIconPackNote;
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsEvent.OMNI_SETTINGS;
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.omnijaws_settings);
-        final PreferenceScreen prefScreen = getPreferenceScreen();
-        mWeatherIconPackNote = getResources().getString(R.string.weather_icon_pack_note);
-
-        mWeatherCategory = (PreferenceCategory) prefScreen.findPreference(CATEGORY_WEATHER);
-        if (mWeatherCategory != null && !isOmniJawsServiceInstalled()) {
-            prefScreen.removePreference(mWeatherCategory);
-        } else {
-            String settingHeaderPackage = Settings.System.getString(getContentResolver(),
-                    Settings.System.OMNIJAWS_WEATHER_ICON_PACK);
-            if (settingHeaderPackage == null) {
-                settingHeaderPackage = DEFAULT_WEATHER_ICON_PACKAGE;
-            }
-            mWeatherIconPack = (ListPreference) findPreference(WEATHER_ICON_PACK);
-
-            List<String> entries = new ArrayList<String>();
-            List<String> values = new ArrayList<String>();
-            getAvailableWeatherIconPacks(entries, values);
-            mWeatherIconPack.setEntries(entries.toArray(new String[entries.size()]));
-            mWeatherIconPack.setEntryValues(values.toArray(new String[values.size()]));
-
-            int valueIndex = mWeatherIconPack.findIndexOfValue(settingHeaderPackage);
-            if (valueIndex == -1) {
-                // no longer found
-                settingHeaderPackage = DEFAULT_WEATHER_ICON_PACKAGE;
-                Settings.System.putString(getContentResolver(),
-                        Settings.System.OMNIJAWS_WEATHER_ICON_PACK, settingHeaderPackage);
-                valueIndex = mWeatherIconPack.findIndexOfValue(settingHeaderPackage);
-            }
-            mWeatherIconPack.setValueIndex(valueIndex >= 0 ? valueIndex : 0);
-            mWeatherIconPack.setSummary(mWeatherIconPackNote + "\n\n" + mWeatherIconPack.getEntry());
-            mWeatherIconPack.setOnPreferenceChangeListener(this);
-        }
-    }
-
-    public boolean onPreferenceChange(Preference preference, Object objValue) {
-        if (preference == mWeatherIconPack) {
-            String value = (String) objValue;
-            Settings.System.putString(getContentResolver(),
-                    Settings.System.OMNIJAWS_WEATHER_ICON_PACK, value);
-            int valueIndex = mWeatherIconPack.findIndexOfValue(value);
-            mWeatherIconPack.setSummary(mWeatherIconPackNote + " \n\n" + mWeatherIconPack.getEntries()[valueIndex]);
-        }
-        return true;
-    }
-
-    private boolean isOmniJawsServiceInstalled() {
-        return PackageUtils.isAvailableApp(WEATHER_SERVICE_PACKAGE, getActivity());
-    }
-
-    private void getAvailableWeatherIconPacks(List<String> entries, List<String> values) {
-        Intent i = new Intent();
-        PackageManager packageManager = getPackageManager();
-        i.setAction("org.omnirom.WeatherIconPack");
-        for (ResolveInfo r : packageManager.queryIntentActivities(i, 0)) {
-            String packageName = r.activityInfo.packageName;
-            String label = r.activityInfo.loadLabel(getPackageManager()).toString();
-            if (label == null) {
-                label = r.activityInfo.packageName;
-            }
-            if (entries.contains(label)) {
-                continue;
-            }
-            if (packageName.equals(DEFAULT_WEATHER_ICON_PACKAGE)) {
-                values.add(0, r.activityInfo.name);
-            } else {
-                values.add(r.activityInfo.name);
-            }
-
-            if (packageName.equals(DEFAULT_WEATHER_ICON_PACKAGE)) {
-                entries.add(0, label);
-            } else {
-                entries.add(label);
-            }
-        }
-        i = new Intent(Intent.ACTION_MAIN);
-        i.addCategory(CHRONUS_ICON_PACK_INTENT);
-        for (ResolveInfo r : packageManager.queryIntentActivities(i, 0)) {
-            String packageName = r.activityInfo.packageName;
-            String label = r.activityInfo.loadLabel(getPackageManager()).toString();
-            if (label == null) {
-                label = r.activityInfo.packageName;
-            }
-            if (entries.contains(label)) {
-                continue;
-            }
-            values.add(packageName + ".weather");
-
-            entries.add(label);
-        }
-    }
-
-    private boolean isOmniJawsEnabled() {
-        final Uri SETTINGS_URI
-            = Uri.parse("content://org.omnirom.omnijaws.provider/settings");
-
-        final String[] SETTINGS_PROJECTION = new String[] {
-            "enabled"
-        };
-
-        final Cursor c = getContentResolver().query(SETTINGS_URI, SETTINGS_PROJECTION,
-                null, null, null);
-        if (c != null) {
-            int count = c.getCount();
-            if (count == 1) {
-                c.moveToPosition(0);
-                boolean enabled = c.getInt(0) == 1;
-                return enabled;
-            }
-        }
-        return true;
-    }
-
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
-                        boolean enabled) {
-                    ArrayList<SearchIndexableResource> result =
-                            new ArrayList<SearchIndexableResource>();
-
-                    SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.omnijaws_settings;
-                    result.add(sir);
-
-                    return result;
-                }
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    ArrayList<String> result = new ArrayList<String>();
-                    return result;
-                }
-    };
-}
diff --git a/src/org/omnirom/omnigears/preference/AppMultiSelectListPreference.java b/src/org/omnirom/omnigears/preference/AppMultiSelectListPreference.java
deleted file mode 100644
index 155de13..0000000
--- a/src/org/omnirom/omnigears/preference/AppMultiSelectListPreference.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- *  Copyright (C) 2016 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-package org.omnirom.omnigears.preference;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.CheckBox;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import com.android.settings.R;
-import com.android.settings.CustomDialogPreference;
-
-import java.text.Collator;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-public class AppMultiSelectListPreference extends CustomDialogPreference {
-    private final List<MyApplicationInfo> mPackageInfoList = new ArrayList<MyApplicationInfo>();
-    private AppListAdapter mAdapter;
-    private Set<String> mValues = new HashSet<String>();
-
-    public AppMultiSelectListPreference(Context context) {
-        this(context, null);
-    }
-
-    public AppMultiSelectListPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        setDialogLayoutResource(R.layout.preference_app_list);
-
-        final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
-        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
-        List<ResolveInfo> installedAppsInfo = getContext().getPackageManager().queryIntentActivities(
-                mainIntent, 0);
-
-        for (ResolveInfo info : installedAppsInfo) {
-            MyApplicationInfo myInfo = new MyApplicationInfo();
-            myInfo.resolveInfo = info;
-            myInfo.label = getResolveInfoTitle(info);
-            mPackageInfoList.add(myInfo);
-        }
-        Collections.sort(mPackageInfoList, sDisplayNameComparator);
-    }
-
-    public void setValues(Collection<String> values) {
-        mValues.clear();
-        mValues.addAll(values);
-    }
-
-    public Collection<String> getValues() {
-        return mValues;
-    }
-
-    @Override
-    protected void onBindDialogView(View view) {
-        super.onBindDialogView(view);
-
-        mAdapter = new AppListAdapter(getContext());
-        final ListView listView = (ListView) view.findViewById(R.id.app_list);
-        listView.setAdapter(mAdapter);
-        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-            @Override
-            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                final AppViewHolder holder = (AppViewHolder) view.getTag();
-                final boolean isChecked = !holder.checkBox.isChecked();
-                holder.checkBox.setChecked(isChecked);
-
-                MyApplicationInfo myInfo = mAdapter.getItem(position);
-                ResolveInfo info = myInfo.resolveInfo;
-                Intent intent = getIntentForResolveInfo(info, Intent.ACTION_MAIN);
-                intent.addCategory(Intent.CATEGORY_LAUNCHER);
-
-                String value = intent.toUri(0).toString();
-                if (isChecked) {
-                    mValues.add(value);
-                } else {
-                    mValues.remove(value);
-                }
-            }
-        });
-    }
-
-    @Override
-    protected void onDialogClosed(boolean positiveResult) {
-        super.onDialogClosed(positiveResult);
-        callChangeListener(null);
-    }
-
-    private String getResolveInfoTitle(ResolveInfo info) {
-        CharSequence label = info.loadLabel(getContext().getPackageManager());
-        if (label == null) label = info.activityInfo.name;
-        return label != null ? label.toString() : null;
-    }
-
-    private Intent getIntentForResolveInfo(ResolveInfo info, String action) {
-        Intent intent = new Intent(action);
-        ActivityInfo ai = info.activityInfo;
-        intent.setClassName(ai.packageName, ai.name);
-        return intent;
-    }
-
-    class MyApplicationInfo {
-        ApplicationInfo info;
-        CharSequence label;
-        ResolveInfo resolveInfo;
-    }
-
-    public class AppListAdapter extends ArrayAdapter<MyApplicationInfo> {
-        private final LayoutInflater mInflater;
-
-        public AppListAdapter(Context context) {
-            super(context, 0);
-            mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-            addAll(mPackageInfoList);
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            // A ViewHolder keeps references to children views to avoid unnecessary calls
-            // to findViewById() on each row.
-            AppViewHolder holder = AppViewHolder.createOrRecycle(mInflater, convertView);
-            convertView = holder.rootView;
-            MyApplicationInfo info = getItem(position);
-            holder.appName.setText(info.label);
-            Drawable icon = info.resolveInfo.loadIcon(getContext().getPackageManager());
-            if (icon != null) {
-                holder.appIcon.setImageDrawable(icon);
-            } else {
-                holder.appIcon.setImageDrawable(null);
-            }
-
-            Intent intent = getIntentForResolveInfo(info.resolveInfo, Intent.ACTION_MAIN);
-            intent.addCategory(Intent.CATEGORY_LAUNCHER);
-            String value = intent.toUri(0).toString();
-
-            holder.checkBox.setChecked(mValues.contains(value));
-            return convertView;
-        }
-
-        @Override
-        public MyApplicationInfo getItem(int position) {
-            return mPackageInfoList.get(position);
-        }
-    }
-
-    public static class AppViewHolder {
-        public View rootView;
-        public TextView appName;
-        public ImageView appIcon;
-        public CheckBox checkBox;
-
-        public static AppViewHolder createOrRecycle(LayoutInflater inflater, View convertView) {
-            if (convertView == null) {
-                convertView = inflater.inflate(R.layout.app_select_item, null);
-
-                // Creates a ViewHolder and store references to the two children views
-                // we want to bind data to.
-                AppViewHolder holder = new AppViewHolder();
-                holder.rootView = convertView;
-                holder.appName = (TextView) convertView.findViewById(R.id.app_name);
-                holder.appIcon = (ImageView) convertView.findViewById(R.id.app_icon);
-                holder.checkBox = (CheckBox) convertView.findViewById(android.R.id.checkbox);
-                convertView.setTag(holder);
-                return holder;
-            } else {
-                // Get the ViewHolder back to get fast access to the TextView
-                // and the ImageView.
-                return (AppViewHolder)convertView.getTag();
-            }
-        }
-    }
-
-    private final static Comparator<MyApplicationInfo> sDisplayNameComparator
-            = new Comparator<MyApplicationInfo>() {
-
-        private final Collator collator = Collator.getInstance();
-
-        public final int compare(MyApplicationInfo a, MyApplicationInfo b) {
-            return collator.compare(a.label, b.label);
-        }
-    };
-}
-
diff --git a/src/org/omnirom/omnigears/preference/AppSelectListPreference.java b/src/org/omnirom/omnigears/preference/AppSelectListPreference.java
deleted file mode 100644
index 8e14961..0000000
--- a/src/org/omnirom/omnigears/preference/AppSelectListPreference.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2012-2014 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.preference;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Message;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import org.omnirom.omnigears.R;
-
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.TreeSet;
-
-public class AppSelectListPreference extends BaseAdapter implements Runnable {
-    private PackageManager mPm;
-    private LayoutInflater mInflater;
-    private List<PackageItem> mInstalledPackages = new LinkedList<PackageItem>();
-
-    // Packages which don't have launcher icons, but which we want to show nevertheless
-    private static final String[] PACKAGE_WHITELIST = new String[] {
-        "android",                          /* system server */
-        "com.android.systemui",             /* system UI */
-        "com.android.providers.downloads"   /* download provider */
-    };
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            PackageItem item = (PackageItem) msg.obj;
-            int index = Collections.binarySearch(mInstalledPackages, item);
-            if (index < 0) {
-                mInstalledPackages.add(-index - 1, item);
-            } else {
-                mInstalledPackages.get(index).activityTitles.addAll(item.activityTitles);
-            }
-            notifyDataSetChanged();
-        }
-    };
-
-    public static class PackageItem implements Comparable<PackageItem> {
-        public final String packageName;
-        public final CharSequence title;
-        private final TreeSet<CharSequence> activityTitles = new TreeSet<CharSequence>();
-        public final Drawable icon;
-
-        PackageItem(String packageName, CharSequence title, Drawable icon) {
-            this.packageName = packageName;
-            this.title = title;
-            this.icon = icon;
-        }
-
-        @Override
-        public int compareTo(PackageItem another) {
-            int result = title.toString().compareToIgnoreCase(another.title.toString());
-            return result != 0 ? result : packageName.compareTo(another.packageName);
-        }
-    }
-
-    public AppSelectListPreference(Context context) {
-        mPm = context.getPackageManager();
-        mInflater = LayoutInflater.from(context);
-        reloadList();
-    }
-
-    @Override
-    public int getCount() {
-        synchronized (mInstalledPackages) {
-            return mInstalledPackages.size();
-        }
-    }
-
-    @Override
-    public PackageItem getItem(int position) {
-        synchronized (mInstalledPackages) {
-            return mInstalledPackages.get(position);
-        }
-    }
-
-    @Override
-    public long getItemId(int position) {
-        synchronized (mInstalledPackages) {
-            // packageName is guaranteed to be unique in mInstalledPackages
-            return mInstalledPackages.get(position).packageName.hashCode();
-        }
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        ViewHolder holder;
-        if (convertView != null) {
-            holder = (ViewHolder) convertView.getTag();
-        } else {
-            convertView = mInflater.inflate(R.layout.applist_preference_icon, null, false);
-            holder = new ViewHolder();
-            convertView.setTag(holder);
-            holder.title = (TextView) convertView.findViewById(com.android.internal.R.id.title);
-            holder.summary = (TextView) convertView.findViewById(com.android.internal.R.id.summary);
-            holder.icon = (ImageView) convertView.findViewById(R.id.icon);
-        }
-
-        PackageItem applicationInfo = getItem(position);
-        holder.title.setText(applicationInfo.title);
-        holder.icon.setImageDrawable(applicationInfo.icon);
-
-        boolean needSummary = applicationInfo.activityTitles.size() > 0;
-        if (applicationInfo.activityTitles.size() == 1) {
-            if (TextUtils.equals(applicationInfo.title, applicationInfo.activityTitles.first())) {
-                needSummary = false;
-            }
-        }
-
-        if (needSummary) {
-            holder.summary.setText(TextUtils.join(", ", applicationInfo.activityTitles));
-            holder.summary.setVisibility(View.VISIBLE);
-        } else {
-            holder.summary.setVisibility(View.GONE);
-        }
-
-        return convertView;
-    }
-
-    private void reloadList() {
-        mInstalledPackages.clear();
-        new Thread(this).start();
-    }
-
-    @Override
-    public void run() {
-        final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
-        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
-        List<ResolveInfo> installedAppsInfo = mPm.queryIntentActivities(mainIntent, 0);
-
-        for (ResolveInfo info : installedAppsInfo) {
-            ApplicationInfo appInfo = info.activityInfo.applicationInfo;
-            final PackageItem item = new PackageItem(appInfo.packageName,
-                    appInfo.loadLabel(mPm), appInfo.loadIcon(mPm));
-            item.activityTitles.add(info.loadLabel(mPm));
-            mHandler.obtainMessage(0, item).sendToTarget();
-        }
-
-        for (String packageName : PACKAGE_WHITELIST) {
-            try {
-                ApplicationInfo appInfo = mPm.getApplicationInfo(packageName, 0);
-                final PackageItem item = new PackageItem(appInfo.packageName,
-                        appInfo.loadLabel(mPm), appInfo.loadIcon(mPm));
-                mHandler.obtainMessage(0, item).sendToTarget();
-            } catch (PackageManager.NameNotFoundException ignored) {
-                // package not present, so nothing to add -> ignore it
-            }
-        }
-    }
-
-    private static class ViewHolder {
-        TextView title;
-        TextView summary;
-        ImageView icon;
-    }
-}
diff --git a/src/org/omnirom/omnigears/preference/ColorPickerPreference.java b/src/org/omnirom/omnigears/preference/ColorPickerPreference.java
deleted file mode 100644
index 84e8f1b..0000000
--- a/src/org/omnirom/omnigears/preference/ColorPickerPreference.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2012 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.preference;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.res.Resources;
-import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.shapes.RectShape;
-import android.os.Bundle;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceViewHolder;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import org.omnirom.omnigears.R;
-import org.omnirom.omnigears.ui.ColorPickerDialog;
-
-public class ColorPickerPreference extends Preference implements DialogInterface.OnDismissListener {
-
-    private static String TAG = "ColorPickerPreference";
-    public static final int DEFAULT_COLOR = 0xFFFFFFFF; //White
-
-    private ImageView mLightColorView;
-    private Resources mResources;
-    private int mColorValue;
-    private Dialog mDialog;
-
-    /**
-     * @param context
-     * @param attrs
-     */
-    public ColorPickerPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mColorValue = DEFAULT_COLOR;
-        init();
-    }
-
-    public ColorPickerPreference(Context context, int color) {
-        super(context, null);
-        mColorValue = color;
-        init();
-    }
-
-    private void init() {
-        setWidgetLayoutResource(R.layout.preference_color_picker);
-        mResources = getContext().getResources();
-    }
-
-    public void setColor(int color) {
-        mColorValue = color;
-        updatePreferenceViews();
-    }
-
-    public int getColor() {
-        return mColorValue;
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-        mLightColorView = (ImageView) holder.findViewById(R.id.light_color);
-        updatePreferenceViews();
-    }
-
-    private void updatePreferenceViews() {
-        final int width = (int) mResources.getDimension(R.dimen.color_preference_width);
-        final int height = (int) mResources.getDimension(R.dimen.color_preference_height);
-
-        if (mLightColorView != null) {
-            mLightColorView.setEnabled(true);
-            mLightColorView.setImageDrawable(createRectShape(width, height, mColorValue));
-        }
-    }
-
-    @Override
-    protected void onClick() {
-        if (mDialog != null && mDialog.isShowing()) return;
-        mDialog = getDialog();
-        mDialog.setOnDismissListener(this);
-        mDialog.show();
-    }
-
-    public Dialog getDialog() {
-        final ColorPickerDialog d = new ColorPickerDialog(getContext(), mColorValue, true);
-
-        d.setButton(AlertDialog.BUTTON_POSITIVE, mResources.getString(R.string.ok),
-                new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                mColorValue =  d.getColor();
-                updatePreferenceViews();
-                callChangeListener(this);
-            }
-        });
-        d.setButton(AlertDialog.BUTTON_NEGATIVE, mResources.getString(R.string.cancel),
-                (DialogInterface.OnClickListener) null);
-
-        return d;
-    }
-
-    private static ShapeDrawable createRectShape(int width, int height, int color) {
-        ShapeDrawable shape = new ShapeDrawable(new RectShape());
-        shape.setIntrinsicHeight(height);
-        shape.setIntrinsicWidth(width);
-        shape.getPaint().setColor(color);
-        return shape;
-    }
-
-    @Override
-    public void onDismiss(DialogInterface dialog) {
-        mDialog = null;
-    }
-}
diff --git a/src/org/omnirom/omnigears/preference/FontPreference.java b/src/org/omnirom/omnigears/preference/FontPreference.java
deleted file mode 100644
index a087bc7..0000000
--- a/src/org/omnirom/omnigears/preference/FontPreference.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *  Copyright (C) 2016 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-package org.omnirom.omnigears.preference;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-
-import android.app.AlertDialog.Builder;
-import android.content.Context;
-import android.graphics.Typeface;
-import android.support.v7.preference.ListPreference;
-import android.support.v7.preference.PreferenceViewHolder;
-import android.util.Log;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import org.omnirom.omnigears.R;
-import org.omnirom.omnigears.utils.FontManager;
-
-public class FontPreference extends ListPreference {
-    private TextView mFontSample;
-
-    public FontPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        setLayoutResource(R.layout.preference_font_picker);
-
-        HashMap< String, String > fonts = FontManager.enumerateFonts();
-        List<CharSequence>fontPaths = new ArrayList<CharSequence>();
-        List<CharSequence> fontNames = new ArrayList<CharSequence>();
-
-        List<String> keys = new ArrayList<String>();
-        keys.addAll(fonts.keySet());
-        Collections.sort(keys);
-
-        for (String name : keys) {
-            fontNames.add(name);
-            fontPaths.add(fonts.get(name));
-        }
-
-        setEntries(fontNames.toArray(new CharSequence[fontNames.size()]));
-        setEntryValues(fontPaths.toArray(new CharSequence[fontPaths.size()]));
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-        mFontSample = (TextView) holder.findViewById(R.id.font_sample);
-        if (getValue() != null) {
-            Typeface tface = Typeface.createFromFile(getValue());
-            if (tface != null) {
-                mFontSample.setTypeface(tface);
-            }
-        }
-    }
-}
diff --git a/src/org/omnirom/omnigears/preference/GlobalCheckBoxPreference.java b/src/org/omnirom/omnigears/preference/GlobalCheckBoxPreference.java
deleted file mode 100644
index 2523ff4..0000000
--- a/src/org/omnirom/omnigears/preference/GlobalCheckBoxPreference.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2013 The CyanogenMod project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.preference;
-
-import android.content.Context;
-import android.support.v7.preference.CheckBoxPreference;
-import android.provider.Settings;
-import android.util.AttributeSet;
-
-public class GlobalCheckBoxPreference extends CheckBoxPreference {
-    public GlobalCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    public GlobalCheckBoxPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public GlobalCheckBoxPreference(Context context) {
-        super(context, null);
-    }
-
-    @Override
-    protected boolean persistBoolean(boolean value) {
-        if (shouldPersist()) {
-            if (value == getPersistedBoolean(!value)) {
-                // It's already there, so the same as persisting
-                return true;
-            }
-
-            Settings.Global.putInt(getContext().getContentResolver(), getKey(), value ? 1 : 0);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    protected boolean getPersistedBoolean(boolean defaultReturnValue) {
-        if (!shouldPersist()) {
-            return defaultReturnValue;
-        }
-
-        return Settings.Global.getInt(getContext().getContentResolver(),
-                getKey(), defaultReturnValue ? 1 : 0) != 0;
-    }
-
-    @Override
-    protected boolean isPersisted() {
-        // Using getString instead of getInt so we can simply check for null
-        // instead of catching an exception. (All values are stored as strings.)
-        return Settings.Global.getString(getContext().getContentResolver(), getKey()) != null;
-    }
-}
diff --git a/src/org/omnirom/omnigears/preference/GlobalSettingSwitchPreference.java b/src/org/omnirom/omnigears/preference/GlobalSettingSwitchPreference.java
deleted file mode 100644
index ceae4a5..0000000
--- a/src/org/omnirom/omnigears/preference/GlobalSettingSwitchPreference.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2014 The CyanogenMod project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.preference;
-
-import android.content.Context;
-import android.support.v14.preference.SwitchPreference;
-import android.provider.Settings;
-import android.util.AttributeSet;
-
-public class GlobalSettingSwitchPreference extends SwitchPreference {
-    public GlobalSettingSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    public GlobalSettingSwitchPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public GlobalSettingSwitchPreference(Context context) {
-        super(context, null);
-    }
-
-    @Override
-    protected boolean persistBoolean(boolean value) {
-        if (shouldPersist()) {
-            if (value == getPersistedBoolean(!value)) {
-                // It's already there, so the same as persisting
-                return true;
-            }
-            Settings.Global.putInt(getContext().getContentResolver(), getKey(), value ? 1 : 0);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    protected boolean getPersistedBoolean(boolean defaultReturnValue) {
-        if (!shouldPersist()) {
-            return defaultReturnValue;
-        }
-        return Settings.Global.getInt(getContext().getContentResolver(),
-                getKey(), defaultReturnValue ? 1 : 0) != 0;
-    }
-
-    @Override
-    protected boolean isPersisted() {
-        // Using getString instead of getInt so we can simply check for null
-        // instead of catching an exception. (All values are stored as strings.)
-        return Settings.Global.getString(getContext().getContentResolver(), getKey()) != null;
-    }
-}
diff --git a/src/org/omnirom/omnigears/preference/HostnamePreference.java b/src/org/omnirom/omnigears/preference/HostnamePreference.java
deleted file mode 100644
index efa33d7..0000000
--- a/src/org/omnirom/omnigears/preference/HostnamePreference.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2013 The CyanogenMod project
- * Copyright (C) 2016 The OmniROM project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.preference;
-
-import android.content.Context;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.text.InputFilter;
-import android.text.Spanned;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.widget.EditText;
-
-import org.omnirom.omnigears.R;
-
-import com.android.settings.CustomDialogPreference;
-
-public class HostnamePreference extends CustomDialogPreference {
-
-    private static final String TAG = "HostnamePreference";
-
-    private static final String PROP_HOSTNAME = "net.hostname";
-
-    private final String DEFAULT_HOSTNAME;
-    private EditText mEditText;
-
-    public HostnamePreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        // determine the default hostname
-        String id = Settings.Secure.getString(getContext().getContentResolver(),
-                Settings.Secure.ANDROID_ID);
-        if (id != null && id.length() > 0) {
-            DEFAULT_HOSTNAME =  "android-".concat(id);
-        } else {
-            DEFAULT_HOSTNAME = "";
-        }
-
-        // set layout
-        setDialogLayoutResource(R.layout.preference_edit_text);
-        setPositiveButtonText(android.R.string.ok);
-        setNegativeButtonText(android.R.string.cancel);
-        setDialogIcon(null);
-        setSummary(getText());
-    }
-
-    public HostnamePreference(Context context, AttributeSet attrs) {
-        this(context, attrs, com.android.internal.R.attr.editTextPreferenceStyle);
-    }
-
-    public HostnamePreference(Context context) {
-        this(context, null);
-    }
-
-    @Override
-    protected void onBindDialogView(View view) {
-        super.onBindDialogView(view);
-
-        mEditText = (EditText) view.findViewById(R.id.edit_text);
-        mEditText.setHint(DEFAULT_HOSTNAME);
-        mEditText.setText(getText());
-    }
-
-    @Override
-    protected void onDialogClosed(boolean positiveResult) {
-        if (positiveResult) {
-            String hostname = mEditText.getText().toString();
-
-            // remove any preceding or succeeding periods or hyphens
-            hostname = hostname.replaceAll("(?:\\.|-)+$", "");
-            hostname = hostname.replaceAll("^(?:\\.|-)+", "");
-            // remove any character that is not alphanumeric, period, or hyphen
-            hostname = hostname.replaceAll("[^-.a-zA-Z0-9]", "");
-
-            if (hostname.length() == 0) {
-                if (DEFAULT_HOSTNAME.length() != 0) {
-                    // if no hostname is given, use the default
-                    hostname = DEFAULT_HOSTNAME;
-                } else {
-                    // if no other name can be determined
-                    // fall back on the current hostname
-                    hostname = getText();
-                }
-            }
-            setText(hostname);
-        }
-    }
-
-    public void setText(String text) {
-        if (text == null) {
-            Log.e(TAG, "tried to set null hostname, request ignored");
-            return;
-        } else if (text.length() == 0) {
-            Log.w(TAG, "setting empty hostname");
-        } else {
-            Log.i(TAG, "hostname has been set: " + text);
-        }
-        SystemProperties.set(PROP_HOSTNAME, text);
-        persistHostname(text);
-        setSummary(text);
-    }
-
-    public String getText() {
-        return SystemProperties.get(PROP_HOSTNAME);
-    }
-
-    @Override
-    public void onSetInitialValue(boolean restoreValue, Object defaultValue) {
-        String hostname = getText();
-        persistHostname(hostname);
-    }
-
-    public void persistHostname(String hostname) {
-        Settings.Secure.putString(getContext().getContentResolver(),
-                Settings.Secure.DEVICE_HOSTNAME, hostname);
-    }
-}
diff --git a/src/org/omnirom/omnigears/preference/NumberPickerPreference.java b/src/org/omnirom/omnigears/preference/NumberPickerPreference.java
deleted file mode 100644
index 1e8bdfd..0000000
--- a/src/org/omnirom/omnigears/preference/NumberPickerPreference.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Based on: http://www.lukehorvat.com/blog/android-numberpickerdialogpreference/
- * Thanks to the original author!
- */
-
-package org.omnirom.omnigears.preference;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.NumberPicker;
-
-import org.omnirom.omnigears.R;
-
-import com.android.settings.CustomDialogPreference;
-
-/**
-* A {@link DialogPreference} that provides a user with the means to select an integer from a {@link NumberPicker}, and persist it.
-*
-* @author lukehorvat
-*
-*/
-public class NumberPickerPreference extends CustomDialogPreference
-{
-    private static final int DEFAULT_MIN_VALUE = 0;
-    private static final int DEFAULT_MAX_VALUE = 100;
-    private static final int DEFAULT_VALUE = 0;
-
-    private int mMinValue;
-    private int mMaxValue;
-    private int mValue;
-    private NumberPicker mNumberPicker;
-
-    public NumberPickerPreference(Context context) {
-        this(context, null);
-    }
-
-    public NumberPickerPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        setMinValue(DEFAULT_MIN_VALUE);
-        setMaxValue(DEFAULT_MAX_VALUE);
-
-        // set layout
-        setDialogLayoutResource(R.layout.preference_number_picker);
-        setPositiveButtonText(android.R.string.ok);
-        setNegativeButtonText(android.R.string.cancel);
-        setDialogIcon(null);
-    }
-
-    @Override
-    protected void onSetInitialValue(boolean restore, Object defaultValue) {
-        setValue(restore ? getPersistedInt(DEFAULT_VALUE) : (Integer) defaultValue);
-    }
-
-    @Override
-    protected Object onGetDefaultValue(TypedArray a, int index) {
-        return a.getInt(index, DEFAULT_VALUE);
-    }
-
-    @Override
-    protected void onBindDialogView(View view) {
-        super.onBindDialogView(view);
-
-        mNumberPicker = (NumberPicker) view.findViewById(R.id.number_picker);
-        mNumberPicker.setMinValue(mMinValue);
-        mNumberPicker.setMaxValue(mMaxValue);
-        mNumberPicker.setValue(mValue);
-    }
-
-    public int getMinValue() {
-        return mMinValue;
-    }
-
-    public void setMinValue(int minValue) {
-        mMinValue = minValue;
-        setValue(Math.max(mValue, mMinValue));
-    }
-
-    public int getMaxValue() {
-        return mMaxValue;
-    }
-
-    public void setMaxValue(int maxValue) {
-        mMaxValue = maxValue;
-        setValue(Math.min(mValue, mMaxValue));
-    }
-
-    public int getValue() {
-        return mValue;
-    }
-
-    public void setValue(int value) {
-        value = Math.max(Math.min(value, mMaxValue), mMinValue);
-
-        if (value != mValue) {
-            mValue = value;
-            persistInt(value);
-            notifyChanged();
-        }
-    }
-
-    @Override
-    protected void onDialogClosed(boolean positiveResult) {
-        super.onDialogClosed(positiveResult);
-
-        // when the user selects "OK", persist the new value
-        if (positiveResult) {
-            int numberPickerValue = mNumberPicker.getValue();
-            if (callChangeListener(numberPickerValue)) {
-                setValue(numberPickerValue);
-            }
-        }
-    }
-}
diff --git a/src/org/omnirom/omnigears/preference/SecureCheckBoxPreference.java b/src/org/omnirom/omnigears/preference/SecureCheckBoxPreference.java
deleted file mode 100644
index 189e73d..0000000
--- a/src/org/omnirom/omnigears/preference/SecureCheckBoxPreference.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2013 The CyanogenMod project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.preference;
-
-import android.content.Context;
-import android.support.v7.preference.CheckBoxPreference;
-import android.provider.Settings;
-import android.util.AttributeSet;
-
-public class SecureCheckBoxPreference extends CheckBoxPreference {
-    public SecureCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    public SecureCheckBoxPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public SecureCheckBoxPreference(Context context) {
-        super(context, null);
-    }
-
-    @Override
-    protected boolean persistBoolean(boolean value) {
-        if (shouldPersist()) {
-            if (value == getPersistedBoolean(!value)) {
-                // It's already there, so the same as persisting
-                return true;
-            }
-
-            Settings.Secure.putInt(getContext().getContentResolver(), getKey(), value ? 1 : 0);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    protected boolean getPersistedBoolean(boolean defaultReturnValue) {
-        if (!shouldPersist()) {
-            return defaultReturnValue;
-        }
-
-        return Settings.Secure.getInt(getContext().getContentResolver(),
-                getKey(), defaultReturnValue ? 1 : 0) != 0;
-    }
-
-    @Override
-    protected boolean isPersisted() {
-        // Using getString instead of getInt so we can simply check for null
-        // instead of catching an exception. (All values are stored as strings.)
-        return Settings.Secure.getString(getContext().getContentResolver(), getKey()) != null;
-    }
-}
diff --git a/src/org/omnirom/omnigears/preference/SecureSettingSwitchPreference.java b/src/org/omnirom/omnigears/preference/SecureSettingSwitchPreference.java
deleted file mode 100644
index 2e4ab88..0000000
--- a/src/org/omnirom/omnigears/preference/SecureSettingSwitchPreference.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2015 The CyanogenMod project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.preference;
-
-import android.content.Context;
-import android.support.v14.preference.SwitchPreference;
-import android.util.AttributeSet;
-
-import android.provider.Settings;
-
-public class SecureSettingSwitchPreference extends SwitchPreference {
-    public SecureSettingSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    public SecureSettingSwitchPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public SecureSettingSwitchPreference(Context context) {
-        super(context, null);
-    }
-
-    @Override
-    protected boolean persistBoolean(boolean value) {
-        if (shouldPersist()) {
-            if (value == getPersistedBoolean(!value)) {
-                // It's already there, so the same as persisting
-                return true;
-            }
-            Settings.Secure.putInt(getContext().getContentResolver(), getKey(), value ? 1 : 0);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    protected boolean getPersistedBoolean(boolean defaultReturnValue) {
-        if (!shouldPersist()) {
-            return defaultReturnValue;
-        }
-        return Settings.Secure.getInt(getContext().getContentResolver(),
-                getKey(), defaultReturnValue ? 1 : 0) != 0;
-    }
-
-    @Override
-    protected boolean isPersisted() {
-        // Using getString instead of getInt so we can simply check for null
-        // instead of catching an exception. (All values are stored as strings.)
-        return Settings.Secure.getString(getContext().getContentResolver(), getKey()) != null;
-    }
-}
diff --git a/src/org/omnirom/omnigears/preference/SeekBarPreference.java b/src/org/omnirom/omnigears/preference/SeekBarPreference.java
deleted file mode 100644
index 5dd88ee..0000000
--- a/src/org/omnirom/omnigears/preference/SeekBarPreference.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
-** Copyright 2013, The ChameleonOS Open Source Project
-** Copyright 2016, The OmniROM Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-package org.omnirom.omnigears.preference;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceViewHolder;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.widget.SeekBar;
-import android.widget.SeekBar.OnSeekBarChangeListener;
-import android.widget.TextView;
-import com.android.settings.R;
-
-public class SeekBarPreference extends Preference implements OnSeekBarChangeListener {
-
-    private final String TAG = getClass().getName();
-
-    private static final String ANDROIDNS = "http://schemas.android.com/apk/res/android";
-    private static final String SETTINGS = "http://schemas.android.com/apk/res/com.android.settings";
-    private static final int DEFAULT_VALUE = 50;
-
-    private int mMaxValue      = 100;
-    private int mMinValue      = 0;
-    private int mInterval      = 1;
-    private int mCurrentValue;
-    private String mUnitsLeft  = "";
-    private String mUnitsRight = "";
-    private SeekBar mSeekBar;
-    private TextView mStatusText;
-
-    public SeekBarPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        initPreference(context, attrs);
-    }
-
-    public SeekBarPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        initPreference(context, attrs);
-    }
-
-    private void initPreference(Context context, AttributeSet attrs) {
-        setValuesFromXml(attrs);
-        setLayoutResource(R.layout.seek_bar_preference);
-    }
-
-    private void setValuesFromXml(AttributeSet attrs) {
-        final TypedArray typedArray = getContext().obtainStyledAttributes(
-                      attrs, R.styleable.SeekBarPreference);
-
-        mMaxValue = attrs.getAttributeIntValue(ANDROIDNS, "max", 100);
-        mMinValue = attrs.getAttributeIntValue(SETTINGS, "min", 0);
-        mUnitsLeft = getAttributeStringValue(attrs, SETTINGS, "unitsLeft", "");
-        String units = getAttributeStringValue(attrs, SETTINGS, "units", "");
-        mUnitsRight = getAttributeStringValue(attrs, SETTINGS, "unitsRight", units);
-
-        Integer id = typedArray.getResourceId(R.styleable.SeekBarPreference_unitsRight, 0);
-        if (id > 0) {
-            mUnitsRight = getContext().getResources().getString(id);
-        }
-        id = typedArray.getResourceId(R.styleable.SeekBarPreference_unitsLeft, 0);
-        if (id > 0) {
-            mUnitsLeft = getContext().getResources().getString(id);
-        }
-
-        try {
-            String newInterval = attrs.getAttributeValue(SETTINGS, "interval");
-            if(newInterval != null)
-                mInterval = Integer.parseInt(newInterval);
-        } catch(Exception e) {
-            Log.e(TAG, "Invalid interval value", e);
-        }
-        typedArray.recycle();
-    }
-
-    private String getAttributeStringValue(AttributeSet attrs, String namespace, String name, String defaultValue) {
-        String value = attrs.getAttributeValue(namespace, name);
-        if(value == null) {
-            value = defaultValue;
-        }
-        return value;
-    }
-
-    @Override
-    public void onDependencyChanged(Preference dependency, boolean disableDependent) {
-        super.onDependencyChanged(dependency, disableDependent);
-        this.setShouldDisableView(true);
-        if (mSeekBar != null) {
-            mSeekBar.setEnabled(!disableDependent);
-        }
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-
-        mSeekBar = (SeekBar) holder.findViewById(R.id.seekbar);
-        mSeekBar.setMax(mMaxValue - mMinValue);
-        mSeekBar.setProgress(mCurrentValue - mMinValue);
-        mSeekBar.setOnSeekBarChangeListener(this);
-        mSeekBar.setEnabled(isEnabled());
-
-        mStatusText = (TextView)holder.findViewById(R.id.seekBarPrefValue);
-        mStatusText.setText(String.valueOf(mCurrentValue));
-        mStatusText.setMinimumWidth(30);
-
-        TextView unitsRight = (TextView)holder.findViewById(R.id.seekBarPrefUnitsRight);
-        unitsRight.setText(mUnitsRight);
-        TextView unitsLeft = (TextView)holder.findViewById(R.id.seekBarPrefUnitsLeft);
-        unitsLeft.setText(mUnitsLeft);
-    }
-
-    @Override
-    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-        int newValue = progress + mMinValue;
-
-        if(newValue > mMaxValue) {
-            newValue = mMaxValue;
-        } else if(newValue < mMinValue) {
-            newValue = mMinValue;
-        } else if(mInterval != 1 && newValue % mInterval != 0) {
-            newValue = Math.round(((float)newValue)/mInterval)*mInterval;
-        }
-
-        // change rejected, revert to the previous value
-        if (!callChangeListener(newValue)) {
-            seekBar.setProgress(mCurrentValue - mMinValue);
-            return;
-        }
-
-        // change accepted, store it
-        mCurrentValue = newValue;
-        mStatusText.setText(String.valueOf(newValue));
-        persistInt(newValue);
-    }
-
-    @Override
-    public void onStartTrackingTouch(SeekBar seekBar) {}
-
-    @Override
-    public void onStopTrackingTouch(SeekBar seekBar) {
-        notifyChanged();
-    }
-
-    @Override
-    protected Object onGetDefaultValue(TypedArray ta, int index){
-        int defaultValue = ta.getInt(index, DEFAULT_VALUE);
-        return defaultValue;
-    }
-
-    @Override
-    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
-        if (restoreValue) {
-            mCurrentValue = getPersistedInt(mCurrentValue);
-        } else {
-            int temp = 0;
-            try {
-                temp = (Integer)defaultValue;
-            } catch(Exception ex) {
-                Log.e(TAG, "Invalid default value: " + defaultValue.toString());
-            }
-            persistInt(temp);
-            mCurrentValue = temp;
-        }
-    }
-
-    public void setValue(int value) {
-        mCurrentValue = value;
-    }
-
-    public void setMaxValue(int value) {
-        mMaxValue = value;
-        if (mSeekBar != null) {
-            mSeekBar.setMax(mMaxValue - mMinValue);
-        }
-    }
-
-    public void setMinValue(int value) {
-        mMinValue = value;
-        if (mSeekBar != null) {
-            mSeekBar.setMax(mMaxValue - mMinValue);
-        }
-    }
-
-    @Override
-    public void setEnabled (boolean enabled) {
-        if (mSeekBar != null) {
-            mSeekBar.setEnabled(enabled);
-        }
-        super.setEnabled(enabled);
-    }
-}
diff --git a/src/org/omnirom/omnigears/preference/SystemCheckBoxPreference.java b/src/org/omnirom/omnigears/preference/SystemCheckBoxPreference.java
deleted file mode 100644
index 088f28c..0000000
--- a/src/org/omnirom/omnigears/preference/SystemCheckBoxPreference.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2013 The CyanogenMod project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.preference;
-
-import android.content.Context;
-import android.support.v7.preference.CheckBoxPreference;
-import android.provider.Settings;
-import android.util.AttributeSet;
-
-public class SystemCheckBoxPreference extends CheckBoxPreference {
-    public SystemCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    public SystemCheckBoxPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public SystemCheckBoxPreference(Context context) {
-        super(context, null);
-    }
-
-    @Override
-    protected boolean persistBoolean(boolean value) {
-        if (shouldPersist()) {
-            if (value == getPersistedBoolean(!value)) {
-                // It's already there, so the same as persisting
-                return true;
-            }
-
-            Settings.System.putInt(getContext().getContentResolver(), getKey(), value ? 1 : 0);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    protected boolean getPersistedBoolean(boolean defaultReturnValue) {
-        if (!shouldPersist()) {
-            return defaultReturnValue;
-        }
-
-        return Settings.System.getInt(getContext().getContentResolver(),
-                getKey(), defaultReturnValue ? 1 : 0) != 0;
-    }
-
-    @Override
-    protected boolean isPersisted() {
-        // Using getString instead of getInt so we can simply check for null
-        // instead of catching an exception. (All values are stored as strings.)
-        return Settings.System.getString(getContext().getContentResolver(), getKey()) != null;
-    }
-}
diff --git a/src/org/omnirom/omnigears/preference/SystemSettingSwitchPreference.java b/src/org/omnirom/omnigears/preference/SystemSettingSwitchPreference.java
deleted file mode 100644
index 14b6a08..0000000
--- a/src/org/omnirom/omnigears/preference/SystemSettingSwitchPreference.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2013 The CyanogenMod project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.preference;
-
-import android.content.Context;
-import android.provider.Settings;
-import android.support.v14.preference.SwitchPreference;
-import android.util.AttributeSet;
-
-public class SystemSettingSwitchPreference extends SwitchPreference {
-    public SystemSettingSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    public SystemSettingSwitchPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public SystemSettingSwitchPreference(Context context) {
-        super(context, null);
-    }
-
-    @Override
-    protected boolean persistBoolean(boolean value) {
-        if (shouldPersist()) {
-            if (value == getPersistedBoolean(!value)) {
-                // It's already there, so the same as persisting
-                return true;
-            }
-            Settings.System.putInt(getContext().getContentResolver(), getKey(), value ? 1 : 0);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    protected boolean getPersistedBoolean(boolean defaultReturnValue) {
-        if (!shouldPersist()) {
-            return defaultReturnValue;
-        }
-        return Settings.System.getInt(getContext().getContentResolver(),
-                getKey(), defaultReturnValue ? 1 : 0) != 0;
-    }
-
-    @Override
-    protected boolean isPersisted() {
-        // Using getString instead of getInt so we can simply check for null
-        // instead of catching an exception. (All values are stored as strings.)
-        return Settings.System.getString(getContext().getContentResolver(), getKey()) != null;
-    }
-}
diff --git a/src/org/omnirom/omnigears/sensor/ShakeSensorManager.java b/src/org/omnirom/omnigears/sensor/ShakeSensorManager.java
deleted file mode 100644
index f35fbe0..0000000
--- a/src/org/omnirom/omnigears/sensor/ShakeSensorManager.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.sensor;
-
-import android.content.Context;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-
-public class ShakeSensorManager {
-
-    public interface ShakeListener {
-        public void onShake();
-    }
-
-    private final ShakeSensorEventListener mShakeSensorListener;
-
-    private boolean mManagerEnabled;
-
-    private static float SENSITIVITY = 10;
-
-    private static class ShakeSensorEventListener implements SensorEventListener {
-        private static final int BUFFER = 5;
-        private float[] gravity = new float[3];
-        private float average = 0;
-        private int fill = 0;
-
-        private final SensorManager mSensorManager;
-        private final Sensor mShakeSensor;
-        private final ShakeListener mListener;
-
-        public ShakeSensorEventListener(SensorManager sensorManager, Sensor shakeSensor,
-                ShakeListener listener) {
-            mSensorManager = sensorManager;
-            mShakeSensor = shakeSensor;
-            mListener = listener;
-        }
-
-        @Override
-        public void onSensorChanged(SensorEvent event) {
-            final float alpha = 0.8F;
-            for (int i = 0; i < 3; i++) {
-                 gravity[i] = alpha * gravity[i] + (1 - alpha) * event.values[i];
-            }
-            float x = event.values[0] - gravity[0];
-            float y = event.values[1] - gravity[1];
-            float z = event.values[2] - gravity[2];
-
-            if (fill <= BUFFER) {
-                average += Math.abs(x) + Math.abs(y) + Math.abs(z);
-                fill++;
-            } else {
-                if (average / BUFFER >= SENSITIVITY) {
-                    mListener.onShake();
-                }
-                average = 0;
-                fill = 0;
-            }
-        }
-
-        @Override
-        public void onAccuracyChanged(Sensor sensor, int accuracy) {
-        }
-
-        public synchronized void unregisterWhenIdle() {
-            unregisterWithoutNotification();
-        }
-
-        public synchronized void register() {
-            mSensorManager.registerListener(this, mShakeSensor,
-                   SensorManager.SENSOR_DELAY_GAME,
-                   50 * 1000);
-        }
-
-        public void unregister() {
-            synchronized (this) {
-                unregisterWithoutNotification();
-            }
-        }
-
-        private void unregisterWithoutNotification() {
-            mSensorManager.unregisterListener(this);
-        }
-    }
-
-    public ShakeSensorManager(Context context, ShakeListener listener) {
-        SensorManager sensorManager =
-                (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
-        Sensor shakeSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
-        if (shakeSensor == null) {
-            mShakeSensorListener = null;
-        } else {
-            mShakeSensorListener =
-                    new ShakeSensorEventListener(sensorManager, shakeSensor, listener);
-        }
-    }
-
-    public void enable(float threshold) {
-        SENSITIVITY = threshold;
-        if (mShakeSensorListener != null && !mManagerEnabled) {
-            mShakeSensorListener.register();
-            mManagerEnabled = true;
-        }
-    }
-
-    public void disable() {
-        if (mShakeSensorListener != null && mManagerEnabled) {
-            mShakeSensorListener.unregisterWhenIdle();
-            mManagerEnabled = false;
-        }
-    }
-}
diff --git a/src/org/omnirom/omnigears/system/CPUStateMonitor.java b/src/org/omnirom/omnigears/system/CPUStateMonitor.java
deleted file mode 100644
index 5722e3b..0000000
--- a/src/org/omnirom/omnigears/system/CPUStateMonitor.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Performance Control - An Android CPU Control application Copyright (C)
- * Brandon Valosek, 2011 <bvalosek@gmail.com> Copyright (C) Modified by 2012
- * James Roberts
- * Copyright (C) 2017 The OmniROM Project
- *
- * This program 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.
- * 
- * This program 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
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.omnirom.omnigears.system;
-
-import android.os.SystemClock;
-import android.util.Log;
-
-import java.io.*;
-import java.util.*;
-
-public class CPUStateMonitor {
-    public static final String TIME_IN_STATE_PATH = "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state";
-    public static final String PREF_OFFSETS = "pref_offsets";
-    public static final String TIME_IN_STATE_OVERALL_PATH = "/sys/devices/system/cpu/cpufreq/overall_stats/overall_time_in_state";
-
-    private Map<Integer, ArrayList<CpuState>> mStates;
-    private Map<Integer, Map<Integer, Long>> mOffsets;
-    private boolean mOverallStats;
-    private int mCpuNum;
-    private List<Integer> mFrequencies;
-    private List<Integer> mShowCpus;
-
-    public CPUStateMonitor(List<Integer> showCpus) {
-        mShowCpus = showCpus;
-        mCpuNum = Helpers.getNumOfCpus();
-        mFrequencies = new ArrayList<Integer>();
-        mStates = new HashMap<Integer, ArrayList<CpuState>>();
-        mOffsets = new HashMap<Integer, Map<Integer, Long>>();
-        for (int i = 0; i < mCpuNum; i++) {
-            ArrayList<CpuState> cpuStates = new ArrayList<CpuState>();
-            mStates.put(i, cpuStates);
-
-            Map<Integer, Long> cpuOffsets = new HashMap<Integer, Long>();
-            mOffsets.put(i, cpuOffsets);
-        }
-        mOverallStats = Helpers.hasOverallStats();
-    }
-
-    public boolean hasOverallStats() {
-        return mOverallStats;
-    }
-
-    @SuppressWarnings("serial")
-    public class CPUStateMonitorException extends Exception {
-        public CPUStateMonitorException(String s) {
-            super(s);
-        }
-    }
-
-    // @SuppressLint({"UseValueOf", "UseValueOf"})
-    public class CpuState implements Comparable<CpuState> {
-        public CpuState(int cpu, int a, long b) {
-            mCpu = cpu;
-            freq = a;
-            duration = b;
-        }
-
-        public int freq = 0;
-        public long duration = 0;
-        public int mCpu = 0;
-
-        @Override
-        public String toString() {
-            return mCpu + ":" + freq + ":" + duration;
-        }
-
-        public int compareTo(CpuState state) {
-            Integer a = freq;
-            Integer b = state.freq;
-            return a.compareTo(b);
-        }
-
-        public long getDuration() {
-            Map<Integer, Long> offsets = getOffsets(mCpu);
-            Long offset = offsets.get(freq);
-            if (offset != null) {
-                return duration - offset;
-            }
-            return duration;
-        }
-    }
-
-    public List<CpuState> getStates(int cpu) {
-        return mStates.get(cpu);
-    }
-
-    public List<Integer> getFrequencies() {
-        return mFrequencies;
-    }
-
-    public CpuState getFreqState(int cpu, int freq) {
-        List<CpuState> cpuStates = mStates.get(cpu);
-        for (CpuState state : cpuStates) {
-            if (state.freq == freq) {
-                return state;
-            }
-        }
-        return null;
-    }
-
-    public CpuState getDeepSleepState() {
-        List<CpuState> cpuStates = mStates.get(0);
-        for (CpuState state : cpuStates) {
-            if (state.freq == 0) {
-                return state;
-            }
-        }
-        return null;
-    }
-
-    public long getTotalStateTime(int cpu, boolean withOffset) {
-        long sum = 0;
-        long offset = 0;
-
-        List<CpuState> cpuStates = mStates.get(cpu);
-        for (CpuState state : cpuStates) {
-            if (withOffset) {
-                sum += state.getDuration();
-            } else {
-                sum += state.duration;
-            }
-        }
-        return sum;
-    }
-
-    public Map<Integer, Long> getOffsets(int cpu) {
-        Map<Integer, Long> cpuOffsets = mOffsets.get(cpu);
-        return cpuOffsets;
-    }
-
-    public void setOffsets(int cpu, Map<Integer, Long> offsets) {
-        mOffsets.put(cpu, offsets);
-    }
-
-    public void setOffsets() throws CPUStateMonitorException {
-        updateStates();
-        for (int i = 0; i < mCpuNum; i++) {
-            if (mShowCpus != null) {
-                if (!mShowCpus.contains(i)) {
-                    continue;
-                }
-            }
-            setOffsets(i);
-        }
-    }
-
-    private void setOffsets(int cpu) throws CPUStateMonitorException {
-        Map<Integer, Long> cpuOffsets = mOffsets.get(cpu);
-        cpuOffsets.clear();
-
-        List<CpuState> cpuStates = mStates.get(cpu);
-        for (CpuState state : cpuStates) {
-            cpuOffsets.put(state.freq, state.duration);
-        }
-    }
-
-    public void removeOffsets() {
-        for (int i = 0; i < mCpuNum; i++) {
-            removeOffsets(i);
-        }
-    }
-
-    private void removeOffsets(int cpu) {
-        Map<Integer, Long> cpuOffsets = mOffsets.get(cpu);
-        cpuOffsets.clear();
-    }
-
-    public void clear() {
-        for (int i = 0; i < mCpuNum; i++) {
-            List<CpuState> cpuStates = mStates.get(i);
-            cpuStates.clear();
-        }
-    }
-
-    public void updateStates() throws CPUStateMonitorException {
-        mFrequencies.clear();
-        if (mOverallStats) {
-            try {
-                InputStream is = new FileInputStream(TIME_IN_STATE_OVERALL_PATH);
-                InputStreamReader ir = new InputStreamReader(is);
-                BufferedReader br = new BufferedReader(ir);
-                clear();
-                readInOverallStates(br);
-                is.close();
-            } catch (IOException e) {
-                throw new CPUStateMonitorException(
-                        "Problem opening time-in-states file");
-            }
-        } else {
-            try {
-                clear();
-                for (int i = 0; i < mCpuNum; i++) {
-                    if (mShowCpus != null) {
-                        if (!mShowCpus.contains(i)) {
-                            continue;
-                        }
-                    }
-                    List<CpuState> cpuStates = mStates.get(i);
-                    InputStream is = new FileInputStream(getCpuFreqPathFor(i));
-                    InputStreamReader ir = new InputStreamReader(is);
-                    BufferedReader br = new BufferedReader(ir);
-                    readInStates(br, i, cpuStates);
-                    is.close();
-                }
-            } catch (IOException e) {
-                throw new CPUStateMonitorException(
-                        "Problem opening time-in-states file");
-            }
-        }
-
-        List<CpuState> cpuStates = mStates.get(0);
-        long sleepTime = Math.max((SystemClock.elapsedRealtime() - SystemClock
-                .uptimeMillis()) / 10, 0);
-        cpuStates.add(new CpuState(0, 0, sleepTime));
-        Collections.sort(mFrequencies);
-    }
-
-    private void readInStates(BufferedReader br, int cpu,
-            List<CpuState> cpuStates) throws CPUStateMonitorException {
-        try {
-            String line;
-            while ((line = br.readLine()) != null) {
-                String[] nums = line.split(" ");
-                int freq = Integer.parseInt(nums[0]);
-                cpuStates.add(new CpuState(cpu, freq, Long
-                        .parseLong(nums[1])));
-                if (!mFrequencies.contains(freq)) {
-                    mFrequencies.add(freq);
-                }
-            }
-            Collections.sort(cpuStates, Collections.reverseOrder());
-        } catch (IOException e) {
-            throw new CPUStateMonitorException(
-                    "Problem processing time-in-states file");
-        }
-    }
-
-    private void readInOverallStates(BufferedReader br)
-            throws CPUStateMonitorException {
-        int cpu = 0;
-        List<CpuState> cpuStates = null;
-        ;
-        int firstFreq = 0;
-        try {
-            String line;
-            while ((line = br.readLine()) != null) {
-                String[] nums = line.split(" ");
-                int freq = Integer.parseInt(nums[0]);
-                if (firstFreq == 0) {
-                    firstFreq = freq;
-                } else if (freq == firstFreq) {
-                    cpu++;
-                    if (cpuStates != null) {
-                        Collections.sort(cpuStates, Collections.reverseOrder());
-                    }
-                }
-                cpuStates = mStates.get(cpu);
-                cpuStates.add(new CpuState(cpu, freq, Long.parseLong(nums[1])));
-                if (!mFrequencies.contains(freq)) {
-                    mFrequencies.add(freq);
-                }
-            }
-        } catch (IOException e) {
-            throw new CPUStateMonitorException(
-                    "Problem processing time-in-states file");
-        }
-    }
-
-    public void dump() {
-        Log.d("PC", "states = " + mStates + "\noffsets = " + mOffsets);
-    }
-
-    private String getCpuFreqPathFor(int cpu) {
-        return TIME_IN_STATE_PATH.replace("cpu0", "cpu" + cpu);
-    }
-}
diff --git a/src/org/omnirom/omnigears/system/DozeSettings.java b/src/org/omnirom/omnigears/system/DozeSettings.java
deleted file mode 100644
index e37bdf6..0000000
--- a/src/org/omnirom/omnigears/system/DozeSettings.java
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- *  Copyright (C) 2017 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- *
-*/
-package org.omnirom.omnigears.system;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.provider.Settings;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.EditText;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-
-public class DozeSettings extends SettingsPreferenceFragment {
-    private static final String TAG = "DozeSettings";
-
-    private static final String SHARED_PREFERENCES_NAME = "doze_settings";
-    private static final String DEVICE_IDLE_CONSTANTS = "device_idle_constants";
-    private static final String KEY_LIGHT_IDLE_FACTOR = "light_idle_factor";
-    private static final String KEY_LOCATION_ACCURACY = "location_accuracy";
-    private static final String KEY_IDLE_PENDING_FACTOR = "idle_pending_factor";
-    private static final String KEY_IDLE_FACTOR = "idle_factor";
-    private static final String KEY_SHOW_ADVANCED = "show_advanced";
-
-    final long LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = 5 * 60 * 1000L;
-    final long LIGHT_PRE_IDLE_TIMEOUT = 10 * 60 * 1000L;
-    final long LIGHT_IDLE_TIMEOUT = 5 * 60 * 1000L;
-    final float LIGHT_IDLE_FACTOR = 2f;
-    final long LIGHT_MAX_IDLE_TIMEOUT = 15 * 60 * 1000L;
-    final long LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = 1 * 60 * 1000L;
-    final long LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = 5 * 60 * 1000L;
-    final long MIN_LIGHT_MAINTENANCE_TIME = 5 * 1000L;
-    final long MIN_DEEP_MAINTENANCE_TIME = 30 * 1000L;
-    final long INACTIVE_TIMEOUT = 30 * 60 * 1000L;
-    final long SENSING_TIMEOUT = 4 * 60 * 1000L;
-    final long LOCATING_TIMEOUT = 30 * 1000L;
-    final float LOCATION_ACCURACY = 20;
-    final long MOTION_INACTIVE_TIMEOUT = 10 * 60 * 1000L;
-    final long IDLE_AFTER_INACTIVE_TIMEOUT = 30 * 60 * 1000L;
-    final long IDLE_PENDING_TIMEOUT = 5 * 60 * 1000L;
-    final long MAX_IDLE_PENDING_TIMEOUT = 10 * 60 * 1000L;
-    final float IDLE_PENDING_FACTOR = 2;
-    final long IDLE_TIMEOUT = 60 * 60 * 1000L;
-    final long MAX_IDLE_TIMEOUT = 6 * 60 * 60 * 1000L;
-    final float IDLE_FACTOR = 2;
-    final long MIN_TIME_TO_ALARM = 60 * 60 * 1000L;
-    final long MAX_TEMP_APP_WHITELIST_DURATION = 5 * 60 * 1000L;
-    final long MMS_TEMP_APP_WHITELIST_DURATION = 60 * 1000L;
-    final long SMS_TEMP_APP_WHITELIST_DURATION = 20 * 1000L;
-    final long NOTIFICATION_WHITELIST_DURATION = 30 * 1000L;
-
-    private int millisecondsInOneSecond = 1000;
-    private LinearLayout mContainer;
-    private List<String> mIdleConfigKeys = new ArrayList<String>();
-    private List<String> mIdleConfigDesc = new ArrayList<String>();
-    private List<String> mIdleConfigShort = new ArrayList<String>();
-    private List<Object> mIdleConfigValues = new ArrayList<Object>();
-    private List<String> mIdleConfigKeysBasic = new ArrayList<String>();
-    private List<EditText> mIdleConfigEdit = new ArrayList<EditText>();
-    private List<View> mIdleConfigViews = new ArrayList<View>();
-
-    private Context mContext;
-    private boolean mShowAdvanced;
-
-    private SharedPreferences getPrefs() {
-        return mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        mContext = getActivity();
-        setHasOptionsMenu(true);
-    }
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsEvent.OMNI_SETTINGS;
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup root,
-            Bundle savedInstanceState) {
-        super.onCreateView(inflater, root, savedInstanceState);
-
-        mShowAdvanced = getPrefs().getBoolean(KEY_SHOW_ADVANCED, false);
-        View view = inflater.inflate(R.layout.doze_settings, root, false);
-
-        Profiles.initProfiles();
-        Profiles.loadUserProfiles(getPrefs());
-
-        mIdleConfigKeys.addAll(Arrays.asList(getResources().getStringArray(R.array.idle_config_keys)));
-        mIdleConfigDesc.addAll(Arrays.asList(getResources().getStringArray(R.array.idle_config_desc)));
-        mIdleConfigShort.addAll(Arrays.asList(getResources().getStringArray(R.array.idle_config_short)));
-        mIdleConfigKeysBasic.addAll(Arrays.asList(getResources().getStringArray(R.array.idle_config_keys_basic)));
-
-        mIdleConfigValues.add(LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT);
-        mIdleConfigValues.add(LIGHT_PRE_IDLE_TIMEOUT);
-        mIdleConfigValues.add(LIGHT_IDLE_TIMEOUT);
-        mIdleConfigValues.add(LIGHT_IDLE_FACTOR);
-        mIdleConfigValues.add(LIGHT_MAX_IDLE_TIMEOUT);
-        mIdleConfigValues.add(LIGHT_IDLE_MAINTENANCE_MIN_BUDGET);
-        mIdleConfigValues.add(LIGHT_IDLE_MAINTENANCE_MAX_BUDGET);
-        mIdleConfigValues.add(MIN_LIGHT_MAINTENANCE_TIME);
-        mIdleConfigValues.add(MIN_DEEP_MAINTENANCE_TIME);
-        mIdleConfigValues.add(INACTIVE_TIMEOUT);
-        mIdleConfigValues.add(SENSING_TIMEOUT);
-        mIdleConfigValues.add(LOCATING_TIMEOUT);
-        mIdleConfigValues.add(LOCATION_ACCURACY);
-        mIdleConfigValues.add(MOTION_INACTIVE_TIMEOUT);
-        mIdleConfigValues.add(IDLE_AFTER_INACTIVE_TIMEOUT);
-        mIdleConfigValues.add(IDLE_PENDING_TIMEOUT);
-        mIdleConfigValues.add(MAX_IDLE_PENDING_TIMEOUT);
-        mIdleConfigValues.add(IDLE_PENDING_FACTOR);
-        mIdleConfigValues.add(IDLE_TIMEOUT);
-        mIdleConfigValues.add(MAX_IDLE_TIMEOUT);
-        mIdleConfigValues.add(IDLE_FACTOR);
-        mIdleConfigValues.add(MIN_TIME_TO_ALARM);
-        mIdleConfigValues.add(MAX_TEMP_APP_WHITELIST_DURATION);
-        mIdleConfigValues.add(MMS_TEMP_APP_WHITELIST_DURATION);
-        mIdleConfigValues.add(SMS_TEMP_APP_WHITELIST_DURATION);
-        mIdleConfigValues.add(NOTIFICATION_WHITELIST_DURATION);
-
-        mContainer = (LinearLayout) view.findViewById(R.id.idle_config_container);
-        createOptionsList(inflater);
-
-        getSettings();
-        return view;
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        inflater.inflate(R.menu.doze_settings_menu, menu);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        int id = item.getItemId();
-
-        switch (id) {
-            case R.id.action_profile:
-                displayProfiles();
-                break;
-            case R.id.action_save:
-                save();
-                break;
-            case R.id.action_save_as_profile:
-                saveAsProfile();
-                break;
-            case R.id.action_restoredefault:
-                restoreDefaults();
-                break;
-            case R.id.action_filter:
-                mShowAdvanced = !mShowAdvanced;
-                getPrefs().edit().putBoolean(KEY_SHOW_ADVANCED, mShowAdvanced).commit();
-                int i = 0;
-                for (View idleConfig : mIdleConfigViews) {
-                    final String configKey = mIdleConfigKeys.get(i);
-                    if (mShowAdvanced) {
-                        idleConfig.setVisibility(View.VISIBLE);
-                    } else {
-                        idleConfig.setVisibility(!mIdleConfigKeysBasic.contains(configKey) ? View.GONE : View.VISIBLE);
-                    }
-                    i++;
-                }
-                break;
-            }
-
-        return super.onOptionsItemSelected(item);
-    }
-
-    private String getMessage(String desc, String value) {
-        return desc +
-                "\n\n" + getResources().getString(R.string.string_default) +
-                ": " +
-                value +
-                " " +
-                getResources().getString(R.string.string_seconds);
-    }
-
-
-    private void getSettings() {
-        String line = Settings.Global.getString(getContentResolver(), DEVICE_IDLE_CONSTANTS);
-        Log.d(TAG, "getSettings = " + line);
-
-        KeyValueListParser parser = new KeyValueListParser(',');
-        if ("null".equals(line)) {
-            parser.setString(line + "=0");
-        } else {
-            parser.setString(line);
-        }
-        int divideBy = getDisplayValueFix();
-        for (int i = 0; i < mIdleConfigKeys.size(); i++) {
-            EditText editText = mIdleConfigEdit.get(i);
-            String key = mIdleConfigKeys.get(i);
-            Object defaultValue = mIdleConfigValues.get(i);
-
-            if (!key.equals(KEY_IDLE_FACTOR) && !key.equals(KEY_IDLE_PENDING_FACTOR) && !key.equals(KEY_IDLE_PENDING_FACTOR) && !key.equals(KEY_LOCATION_ACCURACY) && !key.equals(KEY_LIGHT_IDLE_FACTOR)) {
-                Long value = parser.getLong(key, (Long) defaultValue);
-                value = value / divideBy;
-                editText.setText(String.valueOf(value));
-            } else {
-                Float value = parser.getFloat(key, (Float) defaultValue);
-                editText.setText(String.valueOf(value));
-            }
-        }
-    }
-
-
-    private int getDisplayValueFix() {
-        return millisecondsInOneSecond;
-    }
-
-    private void save() {
-        int multiplyBy = getDisplayValueFix();
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < mIdleConfigKeys.size(); i++) {
-            EditText editText = mIdleConfigEdit.get(i);
-            String key = mIdleConfigKeys.get(i);
-
-            if (!key.equals(KEY_IDLE_FACTOR) && !key.equals(KEY_IDLE_PENDING_FACTOR) && !key.equals(KEY_IDLE_PENDING_FACTOR) && !key.equals(KEY_LOCATION_ACCURACY) && !key.equals(KEY_LIGHT_IDLE_FACTOR)) {
-                Long value = Long.valueOf(editText.getText().toString()) * multiplyBy;
-                sb.append(key + "=" + value + ",");
-            } else {
-                Float value = Float.valueOf(editText.getText().toString());
-                sb.append(key + "=" + value + ",");
-            }
-        }
-        if (sb.length() != 0) {
-            sb.deleteCharAt(sb.length() - 1);
-        }
-        Log.d(TAG, "save = " + sb.toString());
-        Settings.Global.putString(getContentResolver(), DEVICE_IDLE_CONSTANTS, sb.toString());
-        showApplyToast();
-    }
-
-    private void restoreDefaults() {
-        Log.d(TAG, "restoreDefaults");
-        Settings.Global.putString(getContentResolver(), DEVICE_IDLE_CONSTANTS, null);
-        getSettings();
-        showApplyToast();
-    }
-
-    private void applyProfile(String settings) {
-        Log.d(TAG, "apply = " + settings);
-        Settings.Global.putString(getContentResolver(), DEVICE_IDLE_CONSTANTS, settings);
-        getSettings();
-        showApplyToast();
-    }
-
-    private void displayProfiles() {
-        final ArrayList<Profiles.Profile> combinedProfileList = new ArrayList<>();
-        combinedProfileList.addAll(Profiles.getSystemProfileList());
-        combinedProfileList.addAll(Profiles.getUserProfileList());
-        Collections.sort(combinedProfileList);
-        int profileCount = 0;
-        String[] names = new String[combinedProfileList.size()];
-        for (Profiles.Profile profile : combinedProfileList) {
-            if (Profiles.getSystemProfileList().contains(profile)) {
-                names[profileCount] = profile.getName() + " *";
-            } else {
-                names[profileCount] = profile.getName();
-            }
-            profileCount++;
-        }
-        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
-        builder.setTitle(getResources().getString(R.string.action_profile));
-        builder.setItems(names, new DialogInterface.OnClickListener() {
-            public void onClick(DialogInterface dialog, int item) {
-                applyProfile(combinedProfileList.get(item).getSettings());
-            }
-        });
-        final AlertDialog alert = builder.create();
-        alert.setOnShowListener(new DialogInterface.OnShowListener() {
-            @Override
-            public void onShow(DialogInterface dialog) {
-                ListView lv = alert.getListView();
-                lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
-                    @Override
-                    public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
-                        Profiles.Profile p = combinedProfileList.get(position);
-                        if (Profiles.getUserProfileList().contains(p)) {
-                            AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
-                            dialog.setTitle(getResources().getString(R.string.delete_profile));
-                            dialog.setMessage(p.getName());
-                            dialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-                                @Override
-                                public void onClick(DialogInterface dialog, int which) {
-                                    Profiles.removeProfile(p);
-                                    combinedProfileList.remove(p);
-                                    Profiles.saveUserProfiles(getPrefs());
-                                    alert.hide();
-                                }
-                            });
-                            dialog.setNegativeButton(android.R.string.cancel, null);
-                            dialog.create().show();
-                        }
-                        return true;
-                    }
-                });
-            }
-        });
-        alert.show();
-    }
-
-    private void saveAsProfile() {
-        AlertDialog.Builder alert = new AlertDialog.Builder(mContext);
-        final EditText edittext = new EditText(mContext);
-        alert.setTitle(getResources().getString(R.string.profile_name));
-
-        alert.setView(edittext);
-
-        alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-            public void onClick(DialogInterface dialog, int whichButton) {
-                String name = edittext.getText().toString();
-                int multiplyBy = getDisplayValueFix();
-                StringBuilder sb = new StringBuilder();
-                for (int i = 0; i < mIdleConfigKeys.size(); i++) {
-                    EditText editText = mIdleConfigEdit.get(i);
-                    String key = mIdleConfigKeys.get(i);
-
-                    if (!key.equals(KEY_IDLE_FACTOR) && !key.equals(KEY_IDLE_PENDING_FACTOR) && !key.equals(KEY_IDLE_PENDING_FACTOR) && !key.equals(KEY_LOCATION_ACCURACY) && !key.equals(KEY_LIGHT_IDLE_FACTOR)) {
-                        Long value = Long.valueOf(editText.getText().toString()) * multiplyBy;
-                        sb.append(key + "=" + value + ",");
-                    } else {
-                        Float value = Float.valueOf(editText.getText().toString());
-                        sb.append(key + "=" + value + ",");
-                    }
-                }
-                if (sb.length() != 0) {
-                    sb.deleteCharAt(sb.length() - 1);
-                }
-                Profiles.Profile profile = new Profiles.Profile(name, sb.toString());
-                Profiles.addProfile(profile);
-                Profiles.saveUserProfiles(getPrefs());
-            }
-        });
-
-        alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
-            public void onClick(DialogInterface dialog, int whichButton) {
-                // what ever you want to do with No option.
-            }
-        });
-
-        alert.show();
-    }
-
-    private void createOptionsList(LayoutInflater inflater) {
-        mContainer.removeAllViews();
-        for (int i = 0; i < mIdleConfigKeys.size(); i++) {
-            final String configKey = mIdleConfigKeys.get(i);
-            final int idx = i;
-            View idleConfig = inflater.inflate(R.layout.doze_item, null, false);
-            TextView idleConfigText = (TextView) idleConfig.findViewById(R.id.idle_config_text);
-            idleConfigText.setText(mIdleConfigShort.get(i));
-            EditText idleConfigValue = (EditText) idleConfig.findViewById(R.id.idle_config_edit);
-            idleConfigValue.setSaveEnabled(false);
-            mIdleConfigEdit.add(idleConfigValue);
-            ImageView idleConfigImage = (ImageView) idleConfig.findViewById(R.id.idle_config_image);
-            idleConfig.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    String key = mIdleConfigKeys.get(idx);
-                    int divideBy = getDisplayValueFix();
-                    AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
-                    builder.setTitle(key);
-                    Object value = mIdleConfigValues.get(idx);
-                    if (!key.equals(KEY_IDLE_FACTOR) && !key.equals(KEY_IDLE_PENDING_FACTOR) && !key.equals(KEY_IDLE_PENDING_FACTOR) && !key.equals(KEY_LOCATION_ACCURACY) && !key.equals(KEY_LIGHT_IDLE_FACTOR)) {
-                        if (value instanceof Long) {
-                            value = ((Long) value) / divideBy;
-                        }
-                        builder.setMessage(getMessage(mIdleConfigDesc.get(idx), String.valueOf(value)));
-                    } else {
-                        builder.setMessage(mIdleConfigDesc.get(idx) +
-                                "\n\n" +
-                                getResources().getString(R.string.string_default) +
-                                ": " +
-                                String.valueOf(value));
-                    }
-                    builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-                        public void onClick(DialogInterface dialog, int id) {
-                        }
-                    });
-                    AlertDialog dialog = builder.create();
-                    dialog.show();
-                }
-            });
-            mContainer.addView(idleConfig);
-            mIdleConfigViews.add(idleConfig);
-            if (mShowAdvanced) {
-                idleConfig.setVisibility(View.VISIBLE);
-            } else {
-                idleConfig.setVisibility(!mIdleConfigKeysBasic.contains(configKey) ? View.GONE : View.VISIBLE);
-            }
-        }
-    }
-
-    private void showApplyToast() {
-        Toast.makeText(mContext, getResources().getString(R.string.doze_settings_applied), Toast.LENGTH_SHORT).show();
-    }
-}
diff --git a/src/org/omnirom/omnigears/system/Helpers.java b/src/org/omnirom/omnigears/system/Helpers.java
deleted file mode 100644
index 6f747ad..0000000
--- a/src/org/omnirom/omnigears/system/Helpers.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Performance Control - An Android CPU Control application Copyright (C) 2012
- * Jared Rummler Copyright (C) 2012 James Roberts
- * 
- * This program 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.
- * 
- * This program 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
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.omnirom.omnigears.system;
-
-import android.app.Activity;
-import android.content.Context;
-import android.util.Log;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-
-public class Helpers {
-    public static final String TIME_IN_STATE_PATH = "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state";
-    public static final String NUM_OF_CPUS_PATH = "/sys/devices/system/cpu/present";
-    public static final String TIME_IN_STATE_OVERALL_PATH = "/sys/devices/system/cpu/cpufreq/overall_stats/overall_time_in_state";
-
-    /**
-     * Read one line from file
-     *
-     * @param fname
-     * @return line
-     */
-    public static String readOneLine(String fname) {
-        String line = null;
-        if (new File(fname).exists()) {
-            BufferedReader br;
-            try {
-                br = new BufferedReader(new FileReader(fname), 512);
-                try {
-                    line = br.readLine();
-                } finally {
-                    br.close();
-                }
-            } catch (Exception e) {
-            }
-        }
-        return line;
-    }
-
-    /**
-     * Get total number of cpus
-     *
-     * @return total number of cpus
-     */
-    public static int getNumOfCpus() {
-        int numOfCpu = 1;
-        String numOfCpus = Helpers.readOneLine(NUM_OF_CPUS_PATH);
-        if (numOfCpus == null) {
-            return numOfCpu;
-        }
-        String[] cpuCount = numOfCpus.split("-");
-        if (cpuCount.length > 1) {
-            try {
-                int cpuStart = Integer.parseInt(cpuCount[0]);
-                int cpuEnd = Integer.parseInt(cpuCount[1]);
-
-                numOfCpu = cpuEnd - cpuStart + 1;
-
-                if (numOfCpu < 0)
-                    numOfCpu = 1;
-            } catch (NumberFormatException ex) {
-                numOfCpu = 1;
-            }
-        }
-        return numOfCpu;
-    }
-
-    public static boolean hasOverallStats() {
-        return new File(TIME_IN_STATE_OVERALL_PATH).exists();
-    }
-}
diff --git a/src/org/omnirom/omnigears/system/KeyValueListParser.java b/src/org/omnirom/omnigears/system/KeyValueListParser.java
deleted file mode 100644
index 3669d78..0000000
--- a/src/org/omnirom/omnigears/system/KeyValueListParser.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package org.omnirom.omnigears.system;
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import android.text.TextUtils;
-import android.util.ArrayMap;
-
-/**
- * Parses a list of key=value pairs, separated by some delimiter, and puts the results in
- * an internal Map. Values can be then queried by key, or if not found, a default value
- * can be used.
- * @hide
- */
-public class KeyValueListParser {
-    private final ArrayMap<String, String> mValues = new ArrayMap<>();
-    private final TextUtils.StringSplitter mSplitter;
-
-    /**
-     * Constructs a new KeyValueListParser. This can be reused for different strings
-     * by calling {@link #setString(String)}.
-     * @param delim The delimiter that separates key=value pairs.
-     */
-    public KeyValueListParser(char delim) {
-        mSplitter = new TextUtils.SimpleStringSplitter(delim);
-    }
-
-    /**
-     * Resets the parser with a new string to parse. The string is expected to be in the following
-     * format:
-     * <pre>key1=value,key2=value,key3=value</pre>
-     *
-     * where the delimiter is a comma.
-     *
-     * @param str the string to parse.
-     * @throws IllegalArgumentException if the string is malformed.
-     */
-    public void setString(String str) throws IllegalArgumentException {
-        mValues.clear();
-        if (str != null) {
-            mSplitter.setString(str);
-            for (String pair : mSplitter) {
-                int sep = pair.indexOf('=');
-                if (sep < 0) {
-                    mValues.clear();
-                    throw new IllegalArgumentException(
-                            "'" + pair + "' in '" + str + "' is not a valid key-value pair");
-                }
-                mValues.put(pair.substring(0, sep).trim(), pair.substring(sep + 1).trim());
-            }
-        }
-    }
-
-    /**
-     * Get the value for key as a long.
-     * @param key The key to lookup.
-     * @param def The value to return if the key was not found, or the value was not a long.
-     * @return the long value associated with the key.
-     */
-    public long getLong(String key, long def) {
-        String value = mValues.get(key);
-        if (value != null) {
-            try {
-                return Long.parseLong(value);
-            } catch (NumberFormatException e) {
-                // fallthrough
-            }
-        }
-        return def;
-    }
-
-    /**
-     * Get the value for key as a float.
-     * @param key The key to lookup.
-     * @param def The value to return if the key was not found, or the value was not a float.
-     * @return the float value associated with the key.
-     */
-    public float getFloat(String key, float def) {
-        String value = mValues.get(key);
-        if (value != null) {
-            try {
-                return Float.parseFloat(value);
-            } catch (NumberFormatException e) {
-                // fallthrough
-            }
-        }
-        return def;
-    }
-
-    /**
-     * Get the value for key as a string.
-     * @param key The key to lookup.
-     * @param def The value to return if the key was not found.
-     * @return the string value associated with the key.
-     */
-    public String getString(String key, String def) {
-        String value = mValues.get(key);
-        if (value != null) {
-            return value;
-        }
-        return def;
-    }
-}
diff --git a/src/org/omnirom/omnigears/system/Profiles.java b/src/org/omnirom/omnigears/system/Profiles.java
deleted file mode 100644
index e2e28a6..0000000
--- a/src/org/omnirom/omnigears/system/Profiles.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- *  Copyright (C) 2017 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- *
-*/
-package org.omnirom.omnigears.system;
-
-import android.content.SharedPreferences;
-import android.text.TextUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class Profiles {
-
-    public static class Profile implements Comparable<Profile> {
-
-        private String mName;
-        private String mSettings;
-
-        public Profile(String name, String settings){
-            mName = name;
-            mSettings = settings;
-        }
-
-        public String getName() {
-            return mName;
-        }
-
-        public String getSettings() {
-            return mSettings;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (o == null || ! (o instanceof Profile)) {
-                return false;
-            }
-            return mName.equals(((Profile)o).getName());
-        }
-
-        @Override
-        public int compareTo(Profile profile) {
-            return mName.compareTo(profile.getName());
-        }
-    }
-
-    private static final String PROFILE_PREFS = "profiles";
-
-    private static List<Profile> mUserProfileList = new ArrayList<>();
-    private static List<Profile> mSysteProfileList = new ArrayList<>();
-
-    public static void initProfiles() {
-        mSysteProfileList.clear();
-        mSysteProfileList.add(new Profile("aggressive", "light_after_inactive_to=30000,light_pre_idle_to=30000,light_idle_to=30000,light_idle_factor=2.0,light_max_idle_to=60000,light_idle_maintenance_min_budget=30000,light_idle_maintenance_max_budget=60000,min_light_maintenance_time=5000,min_deep_maintenance_time=10000,inactive_to=60000,sensing_to=0,locating_to=10000,location_accuracy=20.0,motion_inactive_to=60000,idle_after_inactive_to=0,idle_pending_to=30000,max_idle_pending_to=60000,idle_pending_factor=2.0,idle_to=3600000,max_idle_to=21600000,idle_factor=2.0,min_time_to_alarm=3600000,max_temp_app_whitelist_duration=20000,mms_temp_app_whitelist_duration=20000,sms_temp_app_whitelist_duration=20000,notification_whitelist_duration=20000"));
-    }
-
-    public static List<Profile> getUserProfileList() {
-        return mUserProfileList;
-    }
-
-    public static List<Profile> getSystemProfileList() {
-        return mSysteProfileList;
-    }
-
-    public static void addProfile(Profile profile) {
-        if (mUserProfileList.contains(profile)) {
-            mUserProfileList.remove(profile);
-        }
-        mUserProfileList.add(profile);
-    }
-
-    public static void removeProfile(Profile profile) {
-        mUserProfileList.remove(profile);
-    }
-
-    public static void loadUserProfiles(SharedPreferences sharedPref) {
-        String userProfile = sharedPref.getString(PROFILE_PREFS , null);
-        mUserProfileList.clear();
-        if (!TextUtils.isEmpty(userProfile)) {
-            String[] profiles = userProfile.split(";");
-            for (String profile : profiles) {
-                String[] profileParts = profile.split(":");
-                Profile p = new Profile(profileParts[0], profileParts[1]);
-                mUserProfileList.add(p);
-            }
-        }
-    }
-
-    public static void saveUserProfiles(SharedPreferences sharedPref){
-        if (mUserProfileList.size() != 0) {
-            StringBuffer sb = new StringBuffer();
-            for (Profile p : mUserProfileList) {
-                sb.append(p.getName() + ":" + p.getSettings() + ";");
-            }
-            sharedPref.edit().putString(PROFILE_PREFS, sb.toString()).commit();
-        } else {
-            sharedPref.edit().remove(PROFILE_PREFS).commit();
-        }
-    }
-}
diff --git a/src/org/omnirom/omnigears/system/TimeInState.java b/src/org/omnirom/omnigears/system/TimeInState.java
deleted file mode 100644
index 2dd083d..0000000
--- a/src/org/omnirom/omnigears/system/TimeInState.java
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- *  Copyright (C) 2017 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- *
-*/
-package org.omnirom.omnigears.system;
-
-import android.app.Fragment;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.*;
-import android.widget.*;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-
-import org.omnirom.omnigears.system.CPUStateMonitor.CpuState;
-import org.omnirom.omnigears.system.CPUStateMonitor.CPUStateMonitorException;
-
-public class TimeInState extends SettingsPreferenceFragment {
-    private static final String TAG = "TimeInState";
-    public static final String PREF_OFFSETS = "pref_offsets";
-    public static final String PREF_STATE_MODE = "pref_state_mode";
-    public static final String PREF_CORE_MODE = "pref_core_mode";
-
-    private LinearLayout mStatesView;
-    private TextView mTotalStateTime;
-    private TextView mStatesWarning;
-    private CheckBox mStateMode;
-    private boolean mUpdatingData = false;
-    private CPUStateMonitor monitor;
-    private Context mContext;
-    private int mCpuNum;
-    private boolean mActiveStateMode;
-    private boolean mActiveCoreMode;
-    private Spinner mPeriodTypeSelect;
-    private LinearLayout mProgress;
-    private CheckBox mCoreMode;
-    private int mPeriodType = 1;
-    private boolean sHasRefData;
-    private Intent mShareIntent;
-    private List<Integer> mShowCpus;
-    private static boolean sResetStats;
-
-    private static final int MENU_REFRESH = Menu.FIRST;
-    private static final int MENU_SHARE = MENU_REFRESH + 1;
-    private static final String SHARED_PREFERENCES_NAME = "time_in_state";
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        mContext = getActivity();
-        mShowCpus = new ArrayList<Integer>();
-        String showCpus = getResources().getString(R.string.config_cpufreq_show_cpus);
-        if (!TextUtils.isEmpty(showCpus)) {
-            String[] parts = showCpus.split(",");
-            for (String cpu : parts) {
-                mShowCpus.add(Integer.valueOf(cpu));
-            }
-        }
-        monitor = new CPUStateMonitor(mShowCpus);
-        mActiveCoreMode = mShowCpus.size() > 1;
-
-        mCpuNum = Helpers.getNumOfCpus();
-        mPeriodType = getPrefs().getInt("which", 1);
-        if (savedInstanceState != null) {
-            mUpdatingData = savedInstanceState.getBoolean("updatingData");
-            mPeriodType = savedInstanceState.getInt("which");
-        }
-
-        if (sResetStats) {
-            sResetStats = false;
-            clearOffsets();
-        }
-        loadOffsets();
-
-        setHasOptionsMenu(true);
-    }
-
-    private SharedPreferences getPrefs() {
-        return mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
-    }
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsEvent.OMNI_SETTINGS;
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup root,
-            Bundle savedInstanceState) {
-        super.onCreateView(inflater, root, savedInstanceState);
-
-        View view = inflater.inflate(R.layout.time_in_state, root, false);
-
-        mStatesView = (LinearLayout) view.findViewById(R.id.ui_states_view);
-        mStatesWarning = (TextView) view.findViewById(R.id.ui_states_warning);
-        mTotalStateTime = (TextView) view
-                .findViewById(R.id.ui_total_state_time);
-
-        mStateMode = (CheckBox) view.findViewById(R.id.ui_mode_switch);
-        mActiveStateMode = getPrefs().getBoolean(PREF_STATE_MODE, false);
-        mStateMode.setChecked(mActiveStateMode);
-        mStateMode.setOnCheckedChangeListener(new OnCheckedChangeListener() {
-            @Override
-            public void onCheckedChanged(CompoundButton buttonView,
-                    boolean isChecked) {
-                mActiveStateMode = isChecked;
-                SharedPreferences.Editor editor = getPrefs().edit();
-                editor.putBoolean(PREF_STATE_MODE, mActiveStateMode).commit();
-                updateView();
-            }
-        });
-
-        mCoreMode = (CheckBox) view.findViewById(R.id.ui_core_switch);
-        mCoreMode.setVisibility(View.GONE);
-
-        mPeriodTypeSelect = (Spinner) view
-                .findViewById(R.id.period_type_select);
-        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
-                mContext, R.array.period_type_entries, R.layout.spinner_item);
-        mPeriodTypeSelect.setAdapter(adapter);
-        mPeriodTypeSelect
-                .setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {
-                    @Override
-                    public void onItemSelected(AdapterView<?> parent,
-                            View view, int position, long id) {
-                        mPeriodType = position;
-                        if (position == 0) {
-                            loadOffsets();
-                        } else if (position == 1) {
-                            monitor.removeOffsets();
-                        }
-                        refreshData();
-                    }
-
-                    @Override
-                    public void onNothingSelected(AdapterView<?> arg0) {
-                    }
-                });
-        mPeriodTypeSelect.setSelection(mPeriodType);
-        mProgress = (LinearLayout) view.findViewById(R.id.ui_progress);
-        return view;
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        outState.putBoolean("updatingData", mUpdatingData);
-        outState.putInt("which", mPeriodType);
-    }
-
-    @Override
-    public void onResume() {
-        refreshData();
-        super.onResume();
-    }
-
-    @Override
-    public void onPause() {
-        getPrefs().edit().putInt("which", mPeriodType).commit();
-        super.onPause();
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        inflater.inflate(R.menu.time_in_state_menu, menu);
-
-        menu.add(0, MENU_REFRESH, 0, R.string.mt_refresh)
-                .setIcon(R.drawable.ic_menu_refresh_new)
-                .setAlphabeticShortcut('r')
-                .setShowAsAction(
-                        MenuItem.SHOW_AS_ACTION_IF_ROOM
-                                | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
-
-        menu.add(1, MENU_SHARE, 0, R.string.mt_share)
-                .setIcon(R.drawable.ic_menu_share_material)
-                .setAlphabeticShortcut('s')
-                .setShowAsAction(
-                        MenuItem.SHOW_AS_ACTION_IF_ROOM
-                                | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-        case MENU_REFRESH:
-            refreshData();
-            break;
-        case R.id.reset:
-            createResetPoint();
-            break;
-        case MENU_SHARE:
-            if (mShareIntent != null) {
-                Intent intent = Intent.createChooser(mShareIntent, null);
-                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                mContext.startActivity(intent);
-            }
-            break;
-        }
-        return super.onOptionsItemSelected(item);
-    }
-
-    private void createResetPoint() {
-        try {
-            monitor.setOffsets();
-        } catch (Exception e) {
-            // not good
-        }
-        saveOffsets();
-        if (mPeriodType == 1) {
-            monitor.removeOffsets();
-        }
-        refreshData();
-    }
-
-    public void updateView() {
-        Log.d(TAG, "updateView " + mUpdatingData);
-        if (mUpdatingData) {
-            return;
-        }
-
-        StringBuffer data = new StringBuffer();
-        mStatesView.removeAllViews();
-
-        if (monitor.getStates(0).size() == 0) {
-            mStatesWarning.setVisibility(View.VISIBLE);
-            mTotalStateTime.setText(getResources().getString(R.string.total_time)
-                    + " " + toString(0));
-            mStatesView.setVisibility(View.GONE);
-        } else {
-            if (mPeriodType == 0 && !sHasRefData) {
-                mStatesWarning.setVisibility(View.VISIBLE);
-                mStatesWarning.setText(getResources().getString(R.string.no_stat_because_reset_state));
-                mTotalStateTime.setText(getResources().getString(R.string.total_time)
-                        + " " + toString(0));
-                mStatesView.setVisibility(View.VISIBLE);
-            } else {
-                mStatesWarning.setVisibility(View.GONE);
-                mStatesView.setVisibility(View.VISIBLE);
-                long totTime = getStateTime(mActiveStateMode);
-                data.append(totTime + "\n");
-                totTime = totTime / 100;
-                if (!mActiveStateMode) {
-                    CpuState deepSleepState = monitor.getDeepSleepState();
-                    if (deepSleepState != null) {
-                        generateStateRowHeader(deepSleepState, mStatesView);
-                        generateStateRow(deepSleepState, mStatesView);
-                        data.append(deepSleepState.freq + " "
-                                + deepSleepState.getDuration() + "\n");
-                    }
-                }
-                if (mActiveCoreMode) {
-                    int cpu = 0;
-                    for (int freq : monitor.getFrequencies()) {
-                        boolean headerCreated = false;
-                        for (cpu = 0; cpu < mCpuNum; cpu++) {
-                            if (mShowCpus != null) {
-                                if (!mShowCpus.contains(cpu)) {
-                                    continue;
-                                }
-                            }
-                            CpuState state = monitor.getFreqState(cpu, freq);
-                            if (state == null) {
-                                continue;
-                            }
-                            if (!headerCreated) {
-                                generateStateRowHeader(state, mStatesView);
-                                headerCreated = true;
-                            }
-                            generateStateRow(state, mStatesView);
-                            data.append(state.mCpu + " " + state.freq + " "
-                                    + state.getDuration() + "\n");
-                        }
-                    }
-                } else {
-                    for (CpuState state : monitor.getStates(0)) {
-                        if (state.freq == 0) {
-                            continue;
-                        }
-                        generateStateRowHeader(state, mStatesView);
-                        generateStateRow(state, mStatesView);
-                        data.append(state.freq + " " + state.getDuration() + "\n");
-                    }
-                }
-
-                mTotalStateTime.setText(getResources().getString(R.string.total_time)
-                        + " " + toString(totTime));
-            }
-        }
-        updateShareIntent(data.toString());
-    }
-
-    public void refreshData() {
-        if (!mUpdatingData) {
-            new RefreshStateDataTask().execute((Void) null);
-        }
-    }
-
-    private static String toString(long tSec) {
-        long h = (long) Math.max(0, Math.floor(tSec / (60 * 60)));
-        long m = (long) Math.max(0, Math.floor((tSec - h * 60 * 60) / 60));
-        long s = Math.max(0, tSec % 60);
-        String sDur;
-        sDur = h + ":";
-        if (m < 10)
-            sDur += "0";
-        sDur += m + ":";
-        if (s < 10)
-            sDur += "0";
-        sDur += s;
-
-        return sDur;
-    }
-
-    private View generateStateRow(CpuState state, ViewGroup parent) {
-        LayoutInflater inflater = LayoutInflater.from(mContext);
-        LinearLayout view = (LinearLayout) inflater.inflate(
-                R.layout.state_row_line, parent, false);
-
-        float per = 0f;
-        String sPer = "";
-        String sDur = "";
-        String sCpu = " ";
-        long tSec = 0;
-
-        if (state != null) {
-            long duration = state.getDuration();
-            if (duration != 0) {
-                per = (float) duration * 100 / getStateTime(mActiveStateMode);
-                if (per > 100f) {
-                    per = 0f;
-                }
-                if (per < 0f) {
-                    per = 0f;
-                }
-                tSec = duration / 100;
-            }
-            sPer = String.format("%3d", (int) per) + "%";
-            sDur = toString(tSec);
-            if (state.freq != 0 && mActiveCoreMode) {
-                sCpu = String.valueOf(state.mCpu);
-            }
-        }
-
-        TextView cpuText = (TextView) view.findViewById(R.id.ui_cpu_text);
-        TextView durText = (TextView) view.findViewById(R.id.ui_duration_text);
-        TextView perText = (TextView) view
-                .findViewById(R.id.ui_percentage_text);
-        ProgressBar bar = (ProgressBar) view.findViewById(R.id.ui_bar);
-
-        cpuText.setText(sCpu);
-        perText.setText(sPer);
-        durText.setText(sDur);
-        bar.setProgress((int) per);
-
-        parent.addView(view);
-        return view;
-    }
-
-    private View generateStateRowHeader(CpuState state, ViewGroup parent) {
-        LayoutInflater inflater = LayoutInflater.from(mContext);
-        LinearLayout view = (LinearLayout) inflater.inflate(
-                R.layout.state_row_header, parent, false);
-
-        String sFreq;
-        if (state.freq == 0) {
-            sFreq = getString(R.string.deep_sleep);
-        } else {
-            sFreq = state.freq / 1000 + " MHz";
-        }
-
-        TextView freqText = (TextView) view.findViewById(R.id.ui_freq_text);
-        freqText.setText(sFreq);
-
-        parent.addView(view);
-        return view;
-    }
-
-    protected class RefreshStateDataTask extends AsyncTask<Void, Void, Void> {
-        @Override
-        protected Void doInBackground(Void... v) {
-            try {
-                monitor.updateStates();
-            } catch (CPUStateMonitorException e) {
-            }
-            return null;
-        }
-
-        @Override
-        protected void onPreExecute() {
-            mProgress.setVisibility(View.VISIBLE);
-            mUpdatingData = true;
-        }
-
-        @Override
-        protected void onPostExecute(Void v) {
-            try {
-                mProgress.setVisibility(View.GONE);
-                mUpdatingData = false;
-                updateView();
-            } catch(Exception e) {
-            }
-        }
-    }
-
-    private void loadOffsets() {
-        String prefs = getPrefs().getString(PREF_OFFSETS, "");
-        if (TextUtils.isEmpty(prefs)) {
-            return;
-        }
-        String[] cpus = prefs.split(":");
-        if (cpus.length != mCpuNum) {
-            return;
-        }
-        for (int cpu = 0; cpu < mCpuNum; cpu++) {
-            if (mShowCpus != null) {
-                if (!mShowCpus.contains(cpu)) {
-                    continue;
-                }
-            }
-            String cpuData = cpus[cpu];
-            Map<Integer, Long> offsets = new HashMap<Integer, Long>();
-            String[] sOffsets = cpuData.split(",");
-            for (String offset : sOffsets) {
-                String[] parts = offset.split(";");
-                offsets.put(Integer.parseInt(parts[0]),
-                        Long.parseLong(parts[1]));
-            }
-            monitor.setOffsets(cpu, offsets);
-        }
-        sHasRefData = true;
-    }
-
-    private void saveOffsets() {
-        StringBuffer str = new StringBuffer();
-        for (int cpu = 0; cpu < mCpuNum; cpu++) {
-            boolean saveCpu = true;
-            if (mShowCpus != null) {
-                if (!mShowCpus.contains(cpu)) {
-                    // just placeholder
-                    str.append("cpu");
-                    saveCpu = false;
-                }
-            }
-            if (saveCpu) {
-                int size = monitor.getOffsets(cpu).entrySet().size();
-                int i = 0;
-                for (Map.Entry<Integer, Long> entry : monitor.getOffsets(cpu)
-                        .entrySet()) {
-                    str.append(entry.getKey() + ";" + entry.getValue());
-                    if (i < size - 1) {
-                        str.append(",");
-                    }
-                    i++;
-                }
-            }
-            if (cpu < mCpuNum - 1) {
-                str.append(":");
-            }
-        }
-        getPrefs().edit().putString(PREF_OFFSETS, str.toString()).commit();
-        sHasRefData = true;
-    }
-
-    private void clearOffsets() {
-        getPrefs().edit().putString(PREF_OFFSETS, "").commit();
-        sHasRefData = false;
-    }
-
-    private long getStateTime(boolean activeMode) {
-        long total = monitor.getTotalStateTime(0, true);
-        if (activeMode) {
-            CpuState deepSleepState = monitor.getDeepSleepState();
-            return total - deepSleepState.getDuration();
-        }
-        return total;
-    }
-
-    private void updateShareIntent(String data) {
-        mShareIntent = new Intent();
-        mShareIntent.setAction(Intent.ACTION_SEND);
-        mShareIntent.setType("text/plain");
-        mShareIntent.putExtra(Intent.EXTRA_TEXT, data);
-    }
-
-    public static void triggerResetStats() {
-        // on reboot
-        sResetStats = true;
-    }
-}
diff --git a/src/org/omnirom/omnigears/system/Wakelocks.java b/src/org/omnirom/omnigears/system/Wakelocks.java
deleted file mode 100644
index 7035b04..0000000
--- a/src/org/omnirom/omnigears/system/Wakelocks.java
+++ /dev/null
@@ -1,1316 +0,0 @@
-/*
- *  Copyright (C) 2017 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- *
-*/
-package org.omnirom.omnigears.system;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.HashSet;
-import java.util.Arrays;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.app.SearchManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
-import android.os.AsyncTask;
-import android.os.BatteryStats;
-import android.os.BatteryStats.Uid;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.PowerManager;
-import android.preference.PreferenceManager;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.LinearLayout;
-import android.widget.ProgressBar;
-import android.widget.Spinner;
-import android.widget.TextView;
-import android.widget.PopupMenu;
-import android.widget.ImageView;
-import android.widget.Toast;
-import android.content.ClipboardManager;
-import android.content.ClipData;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-
-import com.android.internal.os.BatteryStatsHelper;
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.internal.os.BatteryStatsImpl;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-
-
-public class Wakelocks extends SettingsPreferenceFragment {
-    private static final String TAG = "Wakelocks";
-    private static String sRefFilename = "wakelockdata.ref";
-    private static final int MAX_KERNEL_LIST_ITEMS = 15;
-    private static final int MAX_USER_LIST_ITEMS = 15;
-    private LinearLayout mStatesView;
-    private TextView mTotalStateTime;
-    private TextView mKernelWakelockWarning;
-    private boolean mUpdatingData;
-    private Context mContext;
-    private BatteryStats mBatteryStats;
-    private BatteryStatsHelper mStatsHelper;
-    private long rawUptime;
-    private long rawRealtime;
-    private LinearLayout mProgress;
-    private ArrayList<WakelockStats> mKernelWakelocks = new ArrayList<WakelockStats>();
-    private ArrayList<WakelockStats> mUserWakelocks = new ArrayList<WakelockStats>();
-    private static ArrayList<WakelockStats> sRefKernelWakelocks = new ArrayList<WakelockStats>();
-    private static ArrayList<WakelockStats> sRefUserWakelocks = new ArrayList<WakelockStats>();
-    private static long sRefRealTimestamp = 0;
-    private static long sRefUpTimestamp = 0;
-    private static int sRefBatteryLevel = -1;
-    private int mListType;
-    private Spinner mListTypeSelect;
-    private static boolean sKernelWakelockData = false;
-    private boolean mShowAll;
-    private StringBuffer mShareData;
-    private PopupMenu mPopup;
-    private boolean mIsOnBattery;
-    private List<WakelockAppStats> mAppWakelockList = new ArrayList<WakelockAppStats>();
-    private Intent mShareIntent;
-
-    private static final int MENU_REFRESH = Menu.FIRST;
-    private static final int MENU_SHARE = MENU_REFRESH + 1;
-    private static final String SHARED_PREFERENCES_NAME = "wakelocks";
-
-    private static final int[] WAKEUP_SOURCES_FORMAT = new int[] {
-            Process.PROC_TAB_TERM | Process.PROC_OUT_STRING, // 0: name
-            Process.PROC_TAB_TERM | Process.PROC_COMBINE
-                    | Process.PROC_OUT_LONG, // 1: active count
-            Process.PROC_TAB_TERM | Process.PROC_COMBINE, // 2: event count
-            Process.PROC_TAB_TERM | Process.PROC_COMBINE, // 3: wakeup count
-            Process.PROC_TAB_TERM | Process.PROC_COMBINE, // 4: expire count
-            Process.PROC_TAB_TERM | Process.PROC_COMBINE, // 5: active since
-            Process.PROC_TAB_TERM | Process.PROC_COMBINE
-                    | Process.PROC_OUT_LONG,// 6: totalTime
-            Process.PROC_TAB_TERM | Process.PROC_COMBINE, // 7: maxTime
-            Process.PROC_TAB_TERM | Process.PROC_COMBINE, // 8: last change
-            Process.PROC_TAB_TERM | Process.PROC_COMBINE
-                    | Process.PROC_OUT_LONG, // 9: prevent suspend time
-    };
-
-    private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
-            Process.PROC_TAB_TERM | Process.PROC_OUT_STRING | // 0: name
-                    Process.PROC_QUOTES,
-            Process.PROC_TAB_TERM | Process.PROC_OUT_LONG, // 1: count
-            Process.PROC_TAB_TERM, Process.PROC_TAB_TERM,
-            Process.PROC_TAB_TERM,
-            Process.PROC_TAB_TERM | Process.PROC_OUT_LONG, // 5: total time
-            Process.PROC_TAB_TERM | Process.PROC_OUT_LONG, // 6: sleep time
-    };
-
-    private static final String[] sProcWakelocksName = new String[3];
-    private static final long[] sProcWakelocksData = new long[4];
-
-    static final class WakelockStats {
-        final int mType; // 0 == kernel 1 == user
-        final String mName;
-        int mCount;
-        long mTotalTime;
-        long mPreventSuspendTime;
-        int mUid;
-
-        WakelockStats(int type, String name, int count, long totalTime,
-                long preventSuspendTime, int uid) {
-            mType = type;
-            mName = name;
-            mCount = count;
-            mTotalTime = totalTime;
-            mPreventSuspendTime = preventSuspendTime;
-            mUid = uid;
-        }
-
-        @Override
-        public String toString() {
-            return mType + "||" + mName + "||" + mCount + "||" + mTotalTime
-                    + "||" + mPreventSuspendTime;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-
-            if (!(o instanceof WakelockStats)) {
-                return false;
-            }
-
-            WakelockStats lhs = (WakelockStats) o;
-            return mName.equals(lhs.mName) && mUid == lhs.mUid;
-        }
-
-        @Override
-        public int hashCode() {
-            return mName.hashCode();
-        }
-    }
-
-    static final class WakelockAppStats {
-        int mUid;
-        List<WakelockStats> mAppWakelocks;
-        long mPreventSuspendTime;
-
-        WakelockAppStats(int uid) {
-            mUid = uid;
-            mAppWakelocks = new ArrayList<WakelockStats>();
-        }
-
-        public void addWakelockStat(WakelockStats wakelock) {
-            mAppWakelocks.add(wakelock);
-            mPreventSuspendTime += wakelock.mPreventSuspendTime;
-            Collections.sort(mAppWakelocks, sWakelockStatsComparator);
-        }
-
-        public List<WakelockStats> getWakelocks() {
-            return mAppWakelocks;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-
-            if (!(o instanceof WakelockAppStats)) {
-                return false;
-            }
-
-            WakelockAppStats lhs = (WakelockAppStats) o;
-            return mUid == lhs.mUid;
-        }
-
-        @Override
-        public int hashCode() {
-            return mUid;
-        }
-
-        @Override
-        public String toString() {
-            return mUid + "||" + mAppWakelocks;
-        }
-    }
-
-    final static Comparator<WakelockStats> sWakelockStatsComparator = new Comparator<WakelockStats>() {
-        @Override
-        public int compare(WakelockStats lhs, WakelockStats rhs) {
-            long lhsTime = lhs.mPreventSuspendTime;
-            long rhsTime = rhs.mPreventSuspendTime;
-            if (lhsTime < rhsTime) {
-                return 1;
-            }
-            if (lhsTime > rhsTime) {
-                return -1;
-            }
-            return 0;
-        }
-    };
-
-    final static Comparator<WakelockAppStats> sAppWakelockStatsComparator = new Comparator<WakelockAppStats>() {
-        @Override
-        public int compare(WakelockAppStats lhs, WakelockAppStats rhs) {
-            long lhsTime = lhs.mPreventSuspendTime;
-            long rhsTime = rhs.mPreventSuspendTime;
-            if (lhsTime < rhsTime) {
-                return 1;
-            }
-            if (lhsTime > rhsTime) {
-                return -1;
-            }
-            return 0;
-        }
-    };
-
-    private SharedPreferences getPrefs() {
-        return mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        mContext = getActivity();
-        mListType = getPrefs().getInt("listType", 0);
-
-        if (savedInstanceState != null) {
-            mUpdatingData = savedInstanceState.getBoolean("updatingData");
-            mListType = savedInstanceState.getInt("listType");
-        }
-
-        mStatsHelper = new BatteryStatsHelper(mContext, false);
-        mStatsHelper.create(savedInstanceState);
-        setHasOptionsMenu(true);
-
-        loadWakelockRef();
-    }
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsEvent.OMNI_SETTINGS;
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup root,
-            Bundle savedInstanceState) {
-        super.onCreateView(inflater, root, savedInstanceState);
-
-        View view = inflater.inflate(R.layout.wakelocks, root, false);
-
-        mStatesView = (LinearLayout) view.findViewById(R.id.ui_states_view);
-        mTotalStateTime = (TextView) view
-                .findViewById(R.id.ui_total_state_time);
-        mTotalStateTime.setVisibility(View.GONE);
-
-        mListTypeSelect = (Spinner) view.findViewById(R.id.list_type_select);
-        ArrayAdapter<CharSequence> adapter1 = ArrayAdapter.createFromResource(
-                mContext, R.array.list_type_entries, R.layout.spinner_item);
-        mListTypeSelect.setAdapter(adapter1);
-        mListTypeSelect
-                .setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {
-                    @Override
-                    public void onItemSelected(AdapterView<?> parent,
-                            View view, int position, long id) {
-                        mListType = position;
-                        refreshData();
-                    }
-
-                    @Override
-                    public void onNothingSelected(AdapterView<?> arg0) {
-                    }
-                });
-
-        mListTypeSelect.setSelection(mListType);
-
-        mKernelWakelockWarning = (TextView) view
-                .findViewById(R.id.ui_kernel_wakelock_warning);
-        mProgress = (LinearLayout) view.findViewById(R.id.ui_progress);
-
-        return view;
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        outState.putBoolean("updatingData", mUpdatingData);
-        outState.putInt("listType", mListType);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        refreshData();
-    }
-
-    @Override
-    public void onPause() {
-        if (mPopup != null) {
-            mPopup.dismiss();
-        }
-        getPrefs().edit().putInt("listType", mListType).commit();
-        super.onPause();
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        inflater.inflate(R.menu.wakelocks_menu, menu);
-
-        menu.add(0, MENU_REFRESH, 0, R.string.mt_refresh)
-                .setIcon(R.drawable.ic_menu_refresh_new)
-                .setAlphabeticShortcut('r')
-                .setShowAsAction(
-                        MenuItem.SHOW_AS_ACTION_IF_ROOM
-                                | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
-
-        menu.add(1, MENU_SHARE, 0, R.string.mt_share)
-                .setIcon(R.drawable.ic_menu_share_material)
-                .setAlphabeticShortcut('s')
-                .setShowAsAction(
-                        MenuItem.SHOW_AS_ACTION_IF_ROOM
-                                | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-        case MENU_REFRESH:
-            refreshData();
-            break;
-        case R.id.reset:
-            createResetPoint();
-            break;
-        case MENU_SHARE:
-            if (mShareIntent != null) {
-                Intent intent = Intent.createChooser(mShareIntent, null);
-                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                mContext.startActivity(intent);
-            }
-            break;
-        }
-        return super.onOptionsItemSelected(item);
-    }
-
-    private void createResetPoint() {
-        if (mIsOnBattery) {
-            saveWakelockRef(mContext);
-            refreshData();
-        }
-    }
-
-    private void updateView() {
-        if (mUpdatingData) {
-            return;
-        }
-        mStatesView.removeAllViews();
-
-        if (!sKernelWakelockData) {
-            mKernelWakelockWarning.setVisibility(View.VISIBLE);
-            mStatesView.setVisibility(View.GONE);
-        } else {
-            mStatesView.setVisibility(View.VISIBLE);
-            long totalTimeInSecs = 0;
-            long totalUptimeInSecs = 0;
-            boolean showStats = false;
-            mTotalStateTime.setText(toString(totalTimeInSecs));
-
-            if (mIsOnBattery) {
-                long now = System.currentTimeMillis();
-                long bootTime = now - rawRealtime;
-                long refDumpTime = getRefDataDumpTime();
-                long timeSinceUnplugged = mBatteryStats.computeBatteryRealtime(
-                        rawRealtime * 1000, BatteryStats.STATS_SINCE_UNPLUGGED) / 1000;
-                long unplugTime = now - timeSinceUnplugged;
-                if (refDumpTime == -1 || bootTime > refDumpTime || unplugTime > refDumpTime) {
-                    // ref data was dumped before a reboot before last unplug or no ref data at all
-                    // makes no sense to use require user to create new refpint
-                    mKernelWakelockWarning.setText(getResources().getString(
-                            R.string.no_stat_because_reset_wakelock));
-                    mKernelWakelockWarning.setVisibility(View.VISIBLE);
-                } else {
-                    totalTimeInSecs = Math.max(
-                            (rawRealtime - sRefRealTimestamp) / 1000, 0);
-                    totalUptimeInSecs = Math.max(
-                            (rawUptime - sRefUpTimestamp) / 1000, 0);
-                    mKernelWakelockWarning.setVisibility(View.GONE);
-                    mTotalStateTime.setText(toString(totalTimeInSecs));
-                    showStats = true;
-                }
-            } else {
-                mKernelWakelockWarning.setText(getResources().getString(
-                        R.string.no_stat_because_plugged));
-                mKernelWakelockWarning.setVisibility(View.VISIBLE);
-            }
-
-            long sleepTime = Math.max(totalTimeInSecs - totalUptimeInSecs, 0);
-
-            if (mListType == 0 && showStats) {
-                generateTimeRow(getResources().getString(R.string.awake_time),
-                        totalUptimeInSecs, totalTimeInSecs, mStatesView);
-                generateTimeRow(
-                        getResources().getString(R.string.deep_sleep_time),
-                        sleepTime, totalTimeInSecs, mStatesView);
-            } else if (mListType == 1 && showStats) {
-                int i = 0;
-                Iterator<WakelockStats> nextWakelock = mKernelWakelocks
-                        .iterator();
-                while (nextWakelock.hasNext()) {
-                    WakelockStats entry = nextWakelock.next();
-                    generateWakelockRow(entry,
-                            entry.mPreventSuspendTime / 1000, entry.mCount,
-                            totalTimeInSecs, mStatesView, false);
-                    i++;
-                    if (!mShowAll && i >= MAX_KERNEL_LIST_ITEMS) {
-                        int moreNum = mKernelWakelocks.size() - i;
-                        if (moreNum > 0) {
-                            generateMoreRow(
-                                    String.valueOf(moreNum)
-                                            + " "
-                                            + getResources().getString(
-                                                    R.string.more_line_text),
-                                    mStatesView);
-                        }
-                        break;
-                    }
-                }
-            } else if (mListType == 2 && showStats) {
-                int i = 0;
-                Iterator<WakelockStats> nextWakelock = mUserWakelocks
-                        .iterator();
-                while (nextWakelock.hasNext()) {
-                    WakelockStats entry = nextWakelock.next();
-                    generateWakelockRow(entry,
-                            entry.mPreventSuspendTime / 1000, entry.mCount,
-                            totalTimeInSecs, mStatesView, true);
-                    i++;
-                    if (!mShowAll && i >= MAX_USER_LIST_ITEMS) {
-                        int moreNum = mUserWakelocks.size() - i;
-                        if (moreNum > 0) {
-                            generateMoreRow(
-                                    String.valueOf(moreNum)
-                                            + " "
-                                            + getResources().getString(
-                                                    R.string.more_line_text),
-                                    mStatesView);
-                        }
-                        break;
-                    }
-                }
-            } else if (mListType == 3 && showStats) {
-                boolean moreAdded = false;
-                int j = 0;
-                Iterator<WakelockAppStats> nextWakelock = mAppWakelockList
-                        .iterator();
-                while (nextWakelock.hasNext()) {
-                    WakelockAppStats entry = nextWakelock.next();
-                    generateAppWakelockRow(entry, mStatesView, totalTimeInSecs);
-
-                    Iterator<WakelockStats> nextAppWakelock = entry
-                            .getWakelocks().iterator();
-                    while (nextAppWakelock.hasNext()) {
-                        WakelockStats appEntry = nextAppWakelock.next();
-                        generateWakelockRow(appEntry,
-                                appEntry.mPreventSuspendTime / 1000,
-                                appEntry.mCount, totalTimeInSecs, mStatesView,
-                                false);
-                        j++;
-
-                        if (!mShowAll && j >= MAX_USER_LIST_ITEMS) {
-                            int moreNum = mUserWakelocks.size() - j;
-                            if (moreNum > 0) {
-                                generateMoreRow(
-                                        String.valueOf(moreNum)
-                                                + " "
-                                                + getResources()
-                                                        .getString(
-                                                                R.string.more_line_text),
-                                        mStatesView);
-                                moreAdded = true;
-                            }
-                            break;
-                        }
-                    }
-                    if (moreAdded) {
-                        break;
-                    }
-                }
-            }
-        }
-        updateShareIntent(mShareData.toString());
-    }
-
-    public void refreshData() {
-        // Log.d(TAG, "refreshData " + mUpdatingData);
-
-        if (!mUpdatingData) {
-            new RefreshStateDataTask().execute((Void) null);
-        }
-    }
-
-    private static String toString(long tSec) {
-        long h = (long) Math.floor(tSec / (60 * 60));
-        long m = (long) Math.floor((tSec - h * 60 * 60) / 60);
-        long s = tSec % 60;
-        String sDur;
-        sDur = h + ":";
-        if (m < 10)
-            sDur += "0";
-        sDur += m + ":";
-        if (s < 10)
-            sDur += "0";
-        sDur += s;
-
-        return sDur;
-    }
-
-    protected class RefreshStateDataTask extends AsyncTask<Void, Void, Void> {
-        @Override
-        protected Void doInBackground(Void... v) {
-            load();
-            return null;
-        }
-
-        @Override
-        protected void onPreExecute() {
-            mProgress.setVisibility(View.VISIBLE);
-            mUpdatingData = true;
-        }
-
-        @Override
-        protected void onPostExecute(Void v) {
-            try {
-                mProgress.setVisibility(View.GONE);
-                mUpdatingData = false;
-                updateView();
-            } catch (Exception e) {
-            }
-        }
-    }
-
-    private void updateShareIntent(String data) {
-        mShareIntent = new Intent();
-        mShareIntent.setAction(Intent.ACTION_SEND);
-        mShareIntent.setType("text/plain");
-        mShareIntent.putExtra(Intent.EXTRA_TEXT, data);
-    }
-
-    private static long computeWakeLock(BatteryStats.Timer timer,
-            long realtime, int which) {
-        if (timer != null) {
-            // Convert from microseconds to milliseconds with rounding
-            long totalTimeMicros = timer.getTotalTimeLocked(realtime, which);
-            long totalTimeMillis = microToMillis(totalTimeMicros);
-            return totalTimeMillis;
-        }
-        return 0;
-    }
-
-    private static long microToMillis(long microSecs) {
-        return (microSecs + 500) / 1000;
-    }
-
-    private static long microToSecs(long microSecs) {
-        return (microSecs + 500) / 1000000;
-    }
-
-    private View generateTimeRow(String title, long duration, long totalTime,
-            ViewGroup parent) {
-        LayoutInflater inflater = LayoutInflater.from(mContext);
-        LinearLayout view = (LinearLayout) inflater.inflate(R.layout.time_row,
-                parent, false);
-
-        float per = 0f;
-        String sPer = "";
-        String sDur = "";
-        long tSec = 0;
-
-        if (duration != 0) {
-            per = (float) duration * 100 / totalTime;
-            if (per > 100f) {
-                per = 0f;
-            }
-            tSec = duration;
-        }
-        sPer = String.format("%3d", (int) per) + "%";
-        sDur = toString(tSec);
-
-        TextView text = (TextView) view.findViewById(R.id.ui_text);
-        TextView durText = (TextView) view.findViewById(R.id.ui_duration_text);
-        TextView perText = (TextView) view
-                .findViewById(R.id.ui_percentage_text);
-        ProgressBar bar = (ProgressBar) view.findViewById(R.id.ui_bar);
-
-        text.setText(title);
-        perText.setText(sPer);
-        durText.setText(sDur);
-        bar.setProgress((int) per);
-
-        parent.addView(view);
-        return view;
-    }
-
-    private View generateWakelockRow(final WakelockStats entry, long duration,
-            int count, long totalTime, ViewGroup parent, boolean withMore) {
-        LayoutInflater inflater = LayoutInflater.from(mContext);
-        final LinearLayout view = (LinearLayout) inflater.inflate(
-                R.layout.wakelock_row, parent, false);
-
-        float per = 0f;
-        String sPer = "";
-        String sDur = "";
-        long tSec = 0;
-
-        if (duration != 0) {
-            per = (float) duration * 100 / totalTime;
-            if (per > 100f) {
-                per = 0f;
-            }
-            tSec = duration;
-        }
-        sPer = String.format("%3d", (int) per) + "%";
-        sDur = toString(tSec);
-
-        TextView text = (TextView) view.findViewById(R.id.ui_text);
-        TextView durText = (TextView) view.findViewById(R.id.ui_duration_text);
-        TextView perText = (TextView) view
-                .findViewById(R.id.ui_percentage_text);
-        ProgressBar bar = (ProgressBar) view.findViewById(R.id.ui_bar);
-        TextView countText = (TextView) view.findViewById(R.id.ui_count_text);
-        TextView moreText = (TextView) view.findViewById(R.id.ui_more_text);
-
-        text.setText(entry.mName);
-        perText.setText(sPer);
-        durText.setText(sDur);
-        bar.setProgress((int) per);
-        countText.setText(String.valueOf(count));
-
-        if (withMore) {
-            String[] packages = mContext.getPackageManager().getPackagesForUid(
-                    entry.mUid);
-            String rootPackage = getNormalizedRootPackage(packages);
-            try {
-                ApplicationInfo ai = mContext.getPackageManager()
-                        .getApplicationInfo(rootPackage, 0);
-                CharSequence label = ai.loadLabel(mContext.getPackageManager());
-                moreText.setVisibility(View.VISIBLE);
-                if (label != null) {
-                    moreText.setText(label);
-                } else {
-                    moreText.setText(rootPackage);
-                }
-            } catch (android.content.pm.PackageManager.NameNotFoundException e) {
-                return null;
-            }
-        }
-        view.setOnLongClickListener(new View.OnLongClickListener() {
-            @Override
-            public boolean onLongClick(View v) {
-                handleLongPress(entry, view);
-                return true;
-            }
-        });
-
-        parent.addView(view);
-        return view;
-    }
-
-    private View generateAppWakelockRow(final WakelockAppStats entry,
-            ViewGroup parent, long totalTime) {
-        LayoutInflater inflater = LayoutInflater.from(mContext);
-        final LinearLayout view = (LinearLayout) inflater.inflate(
-                R.layout.wakelock_app_row, parent, false);
-
-        float per = 0f;
-        String sPer = "";
-        String sDur = "";
-        long tSec = 0;
-        long duration = entry.mPreventSuspendTime / 1000;
-
-        if (duration != 0) {
-            per = (float) duration * 100 / totalTime;
-            if (per > 100f) {
-                per = 0f;
-            }
-            tSec = duration;
-        }
-        sPer = String.format("%3d", (int) per) + "%";
-        sDur = toString(tSec);
-        TextView text = (TextView) view.findViewById(R.id.ui_text);
-        TextView moreText = (TextView) view.findViewById(R.id.ui_more_text);
-        TextView durText = (TextView) view.findViewById(R.id.ui_duration_text);
-        TextView perText = (TextView) view
-                .findViewById(R.id.ui_percentage_text);
-        ImageView appIcon = (ImageView) view.findViewById(R.id.ui_icon);
-
-        String[] packages = mContext.getPackageManager().getPackagesForUid(
-                entry.mUid);
-        try {
-            String rootPackage = getNormalizedRootPackage(packages);
-
-            ApplicationInfo ai = mContext.getPackageManager()
-                    .getApplicationInfo(rootPackage, 0);
-            CharSequence label = ai.loadLabel(mContext.getPackageManager());
-            String packageName = rootPackage;
-            String appName = rootPackage;
-            if (label != null) {
-                appName = label.toString();
-            }
-            Drawable appIconDrawable = ai
-                    .loadIcon(mContext.getPackageManager());
-            text.setText(appName);
-            moreText.setVisibility(View.VISIBLE);
-            moreText.setText(packageName);
-            perText.setText(sPer);
-            durText.setText(sDur);
-            appIcon.setImageDrawable(appIconDrawable);
-        } catch (android.content.pm.PackageManager.NameNotFoundException e) {
-            return null;
-        }
-
-        /*
-         * view.setOnClickListener(new View.OnClickListener() {
-         * 
-         * @Override public void onClick(View v) { } });
-         */
-
-        if (packages != null && packages.length == 1) {
-            view.setOnLongClickListener(new View.OnLongClickListener() {
-                @Override
-                public boolean onLongClick(View v) {
-                    handleAppLongPress(entry, view);
-                    return true;
-                }
-            });
-        }
-        parent.addView(view);
-
-        return view;
-    }
-
-    private View generateMoreRow(String title, ViewGroup parent) {
-        LayoutInflater inflater = LayoutInflater.from(mContext);
-        LinearLayout view = (LinearLayout) inflater.inflate(
-                R.layout.wakelock_text_row, parent, false);
-
-        TextView text = (TextView) view.findViewById(R.id.ui_text);
-        text.setText(title);
-
-        view.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                mShowAll = true;
-                updateView();
-            }
-        });
-        parent.addView(view);
-        return view;
-    }
-
-    private View generateTextRow(String title, String titleEnd, ViewGroup parent) {
-        LayoutInflater inflater = LayoutInflater.from(mContext);
-        LinearLayout view = (LinearLayout) inflater.inflate(
-                R.layout.wakelock_text_row, parent, false);
-
-        TextView text = (TextView) view.findViewById(R.id.ui_text);
-        text.setText(title);
-
-        if (titleEnd != null) {
-            TextView textEnd = (TextView) view.findViewById(R.id.ui_text_end);
-            textEnd.setText(titleEnd);
-        }
-        parent.addView(view);
-        return view;
-    }
-
-    public static void readKernelWakelockStats(
-            ArrayList<WakelockStats> wakelockList) {
-
-        FileInputStream is;
-        byte[] buffer = new byte[8192];
-        int len;
-        boolean wakeup_sources = false;
-
-        try {
-            try {
-                is = new FileInputStream("/proc/wakelocks");
-            } catch (java.io.FileNotFoundException e) {
-                try {
-                    is = new FileInputStream("/sys/kernel/debug/wakeup_sources");
-                    wakeup_sources = true;
-                } catch (java.io.FileNotFoundException e2) {
-                    return;
-                }
-            }
-
-            len = is.read(buffer);
-            is.close();
-        } catch (java.io.IOException e) {
-            return;
-        }
-
-        if (len > 0) {
-            int i;
-            for (i = 0; i < len; i++) {
-                if (buffer[i] == '\0') {
-                    len = i;
-                    break;
-                }
-            }
-        }
-
-        sKernelWakelockData = true;
-        parseProcWakelocks(wakelockList, buffer, len, wakeup_sources);
-    }
-
-    private static void parseProcWakelocks(
-            ArrayList<WakelockStats> wakelockList, byte[] wlBuffer, int len,
-            boolean wakeup_sources) {
-        String name;
-        int count;
-        long totalTime;
-        int startIndex;
-        int endIndex;
-        int numUpdatedWlNames = 0;
-        long preventSuspendTime;
-
-        // Advance past the first line.
-        int i;
-        for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++)
-            ;
-        startIndex = endIndex = i + 1;
-
-        HashMap<String, WakelockStats> indexList = new HashMap<String, WakelockStats>();
-        while (endIndex < len) {
-            for (endIndex = startIndex; endIndex < len
-                    && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0'; endIndex++)
-                ;
-            endIndex++; // endIndex is an exclusive upper bound.
-            // Don't go over the end of the buffer, Process.parseProcLine might
-            // write to wlBuffer[endIndex]
-            if (endIndex >= (len - 1)) {
-                return;
-            }
-
-            String[] nameStringArray = sProcWakelocksName;
-            long[] wlData = sProcWakelocksData;
-            // Stomp out any bad characters since this is from a circular buffer
-            // A corruption is seen sometimes that results in the vm crashing
-            // This should prevent crashes and the line will probably fail to
-            // parse
-            for (int j = startIndex; j < endIndex; j++) {
-                if ((wlBuffer[j] & 0x80) != 0)
-                    wlBuffer[j] = (byte) '?';
-            }
-            boolean parsed = Process.parseProcLine(wlBuffer, startIndex,
-                    endIndex, wakeup_sources ? WAKEUP_SOURCES_FORMAT
-                            : PROC_WAKELOCKS_FORMAT, nameStringArray, wlData,
-                    null);
-
-            name = nameStringArray[0];
-            count = (int) wlData[1];
-            if (wakeup_sources) {
-                totalTime = wlData[2];
-                preventSuspendTime = wlData[2];
-            } else {
-                totalTime = (wlData[2] + 500) / 1000000;
-                preventSuspendTime = (wlData[3] + 500) / 1000000;
-            }
-
-            if (parsed && name.length() > 0 && count > 0) {
-                WakelockStats foundEntry = indexList.get(name);
-                if (foundEntry == null) {
-                    foundEntry = new WakelockStats(0, name, count, totalTime,
-                            preventSuspendTime, 0);
-                    wakelockList.add(foundEntry);
-                    indexList.put(name, foundEntry);
-                } else {
-                    foundEntry.mCount += count;
-                    foundEntry.mTotalTime += totalTime;
-                    foundEntry.mPreventSuspendTime += preventSuspendTime;
-                }
-            }
-            startIndex = endIndex;
-        }
-    }
-
-    private WakelockStats fromString(String line) {
-        String[] parts = line.split("\\|\\|");
-        try {
-            return new WakelockStats(Integer.valueOf(parts[0]), parts[1],
-                    Integer.valueOf(parts[2]), Long.valueOf(parts[3]),
-                    Long.valueOf(parts[4]), -1);
-        } catch (java.lang.NumberFormatException e) {
-            return null;
-        }
-    }
-
-    private void clearRefData() {
-        Log.d(TAG, "clearRefData");
-        sRefKernelWakelocks.clear();
-        sRefUserWakelocks.clear();
-        File file = new File(mContext.getFilesDir(), sRefFilename);
-        if (file.exists()) {
-            file.delete();
-        }
-        // will be set to actual values on unplug
-        sRefRealTimestamp = 0;
-        sRefUpTimestamp = 0;
-        sRefBatteryLevel = -1;
-    }
-
-    private static void saveWakelockList(BufferedWriter buf,
-            ArrayList<WakelockStats> wlList) throws java.io.IOException {
-        Iterator<WakelockStats> nextWakelock = wlList.iterator();
-        while (nextWakelock.hasNext()) {
-            WakelockStats entry = nextWakelock.next();
-            String wlLine = entry.toString();
-            buf.write(wlLine);
-            buf.newLine();
-        }
-    }
-
-    private void saveRefWakelockData(Context context, String fileName,
-            ArrayList<WakelockStats> kernelData,
-            ArrayList<WakelockStats> userData) {
-        try {
-            File file = new File(context.getFilesDir(), fileName);
-            BufferedWriter buf = new BufferedWriter(new FileWriter(file));
-
-            buf.write(String.valueOf(sRefRealTimestamp));
-            buf.newLine();
-            buf.write(String.valueOf(sRefUpTimestamp));
-            buf.newLine();
-            buf.write(String.valueOf(sRefBatteryLevel));
-            buf.newLine();
-            saveWakelockList(buf, kernelData);
-            saveWakelockList(buf, userData);
-
-            buf.flush();
-            buf.close();
-        } catch (java.io.IOException e) {
-            Log.e(TAG, "saveRefWakelockData:", e);
-        }
-    }
-
-    private long getRefDataDumpTime() {
-        File file = new File(mContext.getFilesDir(), sRefFilename);
-        if (file.exists()) {
-            return file.lastModified();
-        }
-        return -1;
-    }
-
-    private void saveWakelockRef(Context context) {
-        sRefKernelWakelocks.clear();
-        sRefUserWakelocks.clear();
-        readKernelWakelockStats(sRefKernelWakelocks);
-        readUserWakelockStats(mBatteryStats, sRefUserWakelocks);
-
-        sRefRealTimestamp = SystemClock.elapsedRealtime();
-        sRefUpTimestamp = SystemClock.uptimeMillis();
-        sRefBatteryLevel = mBatteryStats.getDischargeCurrentLevel();
-        saveRefWakelockData(context, sRefFilename, sRefKernelWakelocks,
-                sRefUserWakelocks);
-    }
-
-    private void loadRefWakelockData(String fileName,
-            ArrayList<WakelockStats> kernelData,
-            ArrayList<WakelockStats> userData) {
-        try {
-            File file = new File(mContext.getFilesDir(), fileName);
-            if (!file.exists()) {
-                return;
-            }
-            BufferedReader buf = new BufferedReader(new FileReader(file));
-
-            String line = buf.readLine();
-            sRefRealTimestamp = Long.valueOf(line);
-            line = buf.readLine();
-            sRefUpTimestamp = Long.valueOf(line);
-            line = buf.readLine();
-            sRefBatteryLevel = Integer.valueOf(line);
-
-            while ((line = buf.readLine()) != null) {
-                WakelockStats wl = fromString(line);
-                if (wl != null) {
-                    if (wl.mType == 0) {
-                        kernelData.add(wl);
-                    } else {
-                        userData.add(wl);
-                    }
-                }
-            }
-            buf.close();
-        } catch (Exception e) {
-            Log.e(TAG, "loadRefWakelockData:", e);
-        }
-    }
-
-    private void loadWakelockRef() {
-        sRefKernelWakelocks.clear();
-        sRefUserWakelocks.clear();
-        loadRefWakelockData(sRefFilename, sRefKernelWakelocks,
-                sRefUserWakelocks);
-    }
-
-    private ArrayList<WakelockStats> diffToWakelockStatus(
-            ArrayList<WakelockStats> refList, ArrayList<WakelockStats> list) {
-        if (refList == null || refList.size() == 0) {
-            return list;
-        }
-        HashMap<String, WakelockStats> indexList = new HashMap<String, WakelockStats>();
-        ArrayList<WakelockStats> diffWakelocks = new ArrayList<WakelockStats>();
-
-        Iterator<WakelockStats> nextWakelock = refList.iterator();
-        while (nextWakelock.hasNext()) {
-            WakelockStats entry = nextWakelock.next();
-            indexList.put(entry.mName, entry);
-        }
-        nextWakelock = list.iterator();
-        while (nextWakelock.hasNext()) {
-            WakelockStats entry = nextWakelock.next();
-            WakelockStats savedEntry = indexList.get(entry.mName);
-            if (savedEntry != null) {
-                int diffCount = entry.mCount - savedEntry.mCount;
-                long diffTotalTime = entry.mTotalTime - savedEntry.mTotalTime;
-                long diffPreventSuspendTime = entry.mPreventSuspendTime
-                        - savedEntry.mPreventSuspendTime;
-                if (diffCount > 0 && diffTotalTime > 0) {
-                    WakelockStats newEntry = new WakelockStats(entry.mType,
-                            entry.mName, diffCount, diffTotalTime,
-                            diffPreventSuspendTime, entry.mUid);
-                    diffWakelocks.add(newEntry);
-                }
-            } else {
-                diffWakelocks.add(entry);
-            }
-        }
-        return diffWakelocks;
-    }
-
-    private void readUserWakelockStats(BatteryStats stats,
-            ArrayList<WakelockStats> userData) {
-        SparseArray<? extends BatteryStats.Uid> uidStats = stats.getUidStats();
-        HashMap<String, WakelockStats> indexList = new HashMap<String, WakelockStats>();
-
-        final int NU = uidStats.size();
-        for (int iu = 0; iu < NU; iu++) {
-            BatteryStats.Uid u = uidStats.valueAt(iu);
-            int uid = u.getUid();
-            Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u
-                    .getWakelockStats();
-            if (wakelocks.size() > 0) {
-                for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent : wakelocks
-                        .entrySet()) {
-                    BatteryStats.Uid.Wakelock wl = ent.getValue();
-
-                    BatteryStats.Timer partialWakeTimer = wl
-                            .getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL);
-                    if (partialWakeTimer != null) {
-                        long totalTimeMillis = computeWakeLock(
-                                partialWakeTimer, rawRealtime * 1000,
-                                BatteryStats.STATS_CURRENT);
-                        int count = partialWakeTimer
-                                .getCountLocked(BatteryStats.STATS_CURRENT);
-                        if (totalTimeMillis > 0 && count > 0) {
-                            WakelockStats foundEntry = indexList.get(ent
-                                    .getKey());
-                            if (foundEntry == null) {
-                                foundEntry = new WakelockStats(1, ent.getKey(),
-                                        count, totalTimeMillis,
-                                        totalTimeMillis, uid);
-                                userData.add(foundEntry);
-                                indexList.put(ent.getKey(), foundEntry);
-                            } else {
-                                foundEntry.mCount += count;
-                                foundEntry.mTotalTime += totalTimeMillis;
-                                foundEntry.mPreventSuspendTime += totalTimeMillis;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    private void readKernelWakelockStats(BatteryStats stats,
-            ArrayList<WakelockStats> kernelData) {
-        Log.d(TAG, "readKernelWakelockStats");
-        Map<String, ? extends BatteryStats.Timer> kernelWakelocks = stats
-                .getKernelWakelockStats();
-        if (kernelWakelocks.size() > 0) {
-            for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks
-                    .entrySet()) {
-                BatteryStats.Timer wl = ent.getValue();
-
-                long totalTimeMillis = microToMillis(wl.getTotalTimeLocked(
-                        rawRealtime * 1000, BatteryStats.STATS_CURRENT));
-                int count = wl
-                        .getCountLocked(BatteryStats.STATS_CURRENT);
-
-                if (totalTimeMillis > 0 && count > 0) {
-                    WakelockStats entry = new WakelockStats(0, ent.getKey(),
-                            count, totalTimeMillis, totalTimeMillis, 0);
-                    Log.d(TAG, "readKernelWakelockStats A " + ent.getKey()
-                            + " " + totalTimeMillis + " " + count);
-                    kernelData.add(entry);
-                } else {
-                    Log.d(TAG, "readKernelWakelockStats B " + ent.getKey()
-                            + " " + totalTimeMillis + " " + count);
-                }
-            }
-        }
-    }
-
-    private void load() {
-        mShowAll = false;
-        mShareData = new StringBuffer();
-        mStatsHelper.clearStats();
-        mBatteryStats = mStatsHelper.getStats();
-
-        rawUptime = SystemClock.uptimeMillis();
-        rawRealtime = SystemClock.elapsedRealtime();
-        mIsOnBattery = mBatteryStats.getIsOnBattery();
-
-        mShareData.append("\n================\n");
-        mShareData.append("Kernel wakelocks\n");
-        mShareData.append("================\n");
-        ArrayList<WakelockStats> allKernelWakelocks = new ArrayList<WakelockStats>();
-        readKernelWakelockStats(/* mBatteryStats, */allKernelWakelocks);
-
-        mKernelWakelocks.clear();
-        if (mIsOnBattery) {
-            mKernelWakelocks.addAll(diffToWakelockStatus(
-                    sRefKernelWakelocks, allKernelWakelocks));
-        }
-        Collections.sort(mKernelWakelocks, sWakelockStatsComparator);
-        mShareData.append(mKernelWakelocks.toString());
-        mShareData.append("\n================\n");
-        mShareData.append("Wakelocks\n");
-        mShareData.append("================\n");
-        ArrayList<WakelockStats> allUserWakelocks = new ArrayList<WakelockStats>();
-        readUserWakelockStats(mBatteryStats, allUserWakelocks);
-
-        mUserWakelocks.clear();
-        if (mIsOnBattery) {
-            mUserWakelocks.addAll(diffToWakelockStatus(
-                    sRefUserWakelocks, allUserWakelocks));
-        }
-        Collections.sort(mUserWakelocks, sWakelockStatsComparator);
-        mShareData.append(mUserWakelocks.toString());
-
-        buildAppWakelockList();
-        Collections.sort(mAppWakelockList, sAppWakelockStatsComparator);
-    }
-
-    private void buildAppWakelockList() {
-        mAppWakelockList.clear();
-
-        Iterator<WakelockStats> nextWakelock = mUserWakelocks.iterator();
-        while (nextWakelock.hasNext()) {
-            WakelockStats entry = nextWakelock.next();
-            WakelockAppStats appStats = new WakelockAppStats(entry.mUid);
-            int idx = mAppWakelockList.indexOf(appStats);
-            if (idx == -1) {
-                mAppWakelockList.add(appStats);
-            } else {
-                appStats = mAppWakelockList.get(idx);
-            }
-            appStats.addWakelockStat(entry);
-        }
-    }
-
-    private void handleLongPress(final WakelockStats entry, View view) {
-        final PopupMenu popup = new PopupMenu(mContext, view);
-        mPopup = popup;
-        popup.getMenuInflater().inflate(R.menu.wakelocks_popup_menu,
-                popup.getMenu());
-
-        final String wakeLockName = entry.mName;
-
-        popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
-            public boolean onMenuItemClick(MenuItem item) {
-                if (item.getItemId() == R.id.copy_as_text) {
-                    ClipboardManager clipboard = (ClipboardManager) mContext
-                            .getSystemService(Context.CLIPBOARD_SERVICE);
-                    ClipData clip = ClipData.newPlainText(wakeLockName,
-                            wakeLockName);
-                    clipboard.setPrimaryClip(clip);
-                } else if (item.getItemId() == R.id.google_it) {
-                    try {
-                        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
-                        intent.putExtra(SearchManager.QUERY, "wakelock "
-                                + wakeLockName);
-                        startActivity(intent);
-                    } catch (Exception e) {
-                    }
-                } else {
-                    return false;
-                }
-                return true;
-            }
-        });
-        popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
-            public void onDismiss(PopupMenu menu) {
-                mPopup = null;
-            }
-        });
-        popup.show();
-    }
-
-    private void handleAppLongPress(final WakelockAppStats entry, View view) {
-        final PopupMenu popup = new PopupMenu(mContext, view);
-        mPopup = popup;
-        popup.getMenuInflater().inflate(R.menu.wakelocks_app_popup_menu,
-                popup.getMenu());
-
-        popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
-            public boolean onMenuItemClick(MenuItem item) {
-                if (item.getItemId() == R.id.app_details) {
-                    String[] packages = mContext.getPackageManager()
-                            .getPackagesForUid(entry.mUid);
-                    if (packages != null && packages.length == 1) {
-                        Intent intent = new Intent();
-                        intent.setAction(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
-                        intent.setData(Uri.parse("package:" + packages[0]));
-                        startActivity(intent);
-                    }
-                } else {
-                    return false;
-                }
-                return true;
-            }
-        });
-        popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
-            public void onDismiss(PopupMenu menu) {
-                mPopup = null;
-            }
-        });
-        popup.show();
-    }
-
-    private String getNormalizedRootPackage(final String[] packages) {
-        String rootPackage = null;
-        if (packages == null || packages.length == 0) {
-            rootPackage = "android";
-        } else {
-            List<String> packageList = Arrays.asList(packages);
-            rootPackage = packages[0];
-            if (packageList.contains("android")) {
-                rootPackage = "android";
-            } else if (packageList.contains("com.google.android.gms")) {
-                rootPackage = "com.google.android.gms";
-            } else if (packageList.contains("com.android.systemui")) {
-                rootPackage = "com.android.systemui";
-            } else if (packageList.contains("com.android.phone")) {
-                rootPackage = "com.android.phone";
-            }
-        }
-        return rootPackage;
-    }
-}
diff --git a/src/org/omnirom/omnigears/ui/AlphaPatternDrawable.java b/src/org/omnirom/omnigears/ui/AlphaPatternDrawable.java
deleted file mode 100644
index dbe4b77..0000000
--- a/src/org/omnirom/omnigears/ui/AlphaPatternDrawable.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2010 Daniel Nilsson
- * Copyright (C) 2012 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.ui;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.Bitmap.Config;
-import android.graphics.drawable.Drawable;
-
-/**
- * This drawable that draws a simple white and gray chess board pattern. It's
- * pattern you will often see as a background behind a partly transparent image
- * in many applications.
- *
- * @author Daniel Nilsson
- */
-public class AlphaPatternDrawable extends Drawable {
-
-    private int mRectangleSize = 10;
-
-    private Paint mPaint = new Paint();
-    private Paint mPaintWhite = new Paint();
-    private Paint mPaintGray = new Paint();
-
-    private int numRectanglesHorizontal;
-    private int numRectanglesVertical;
-
-    /**
-     * Bitmap in which the pattern will be cached.
-     */
-    private Bitmap mBitmap;
-
-    public AlphaPatternDrawable(int rectangleSize) {
-        mRectangleSize = rectangleSize;
-        mPaintWhite.setColor(0xffffffff);
-        mPaintGray.setColor(0xffcbcbcb);
-    }
-
-    @Override
-    public void draw(Canvas canvas) {
-        if (mBitmap != null) {
-            canvas.drawBitmap(mBitmap, null, getBounds(), mPaint);
-        }
-    }
-
-    @Override
-    public int getOpacity() {
-        return 0;
-    }
-
-    @Override
-    public void setAlpha(int alpha) {
-        throw new UnsupportedOperationException("Alpha is not supported by this drawwable.");
-    }
-
-    @Override
-    public void setColorFilter(ColorFilter cf) {
-        throw new UnsupportedOperationException("ColorFilter is not supported by this drawwable.");
-    }
-
-    @Override
-    protected void onBoundsChange(Rect bounds) {
-        super.onBoundsChange(bounds);
-
-        int height = bounds.height();
-        int width = bounds.width();
-
-        numRectanglesHorizontal = (int) Math.ceil((width / mRectangleSize));
-        numRectanglesVertical = (int) Math.ceil(height / mRectangleSize);
-
-        generatePatternBitmap();
-    }
-
-    /**
-     * This will generate a bitmap with the pattern as big as the rectangle we
-     * were allow to draw on. We do this to cache the bitmap so we don't need
-     * to recreate it each time draw() is called since it takes a few
-     * milliseconds.
-     */
-    private void generatePatternBitmap() {
-
-        if (getBounds().width() <= 0 || getBounds().height() <= 0) {
-            return;
-        }
-
-        mBitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Config.ARGB_8888);
-        Canvas canvas = new Canvas(mBitmap);
-
-        Rect r = new Rect();
-        boolean verticalStartWhite = true;
-        for (int i = 0; i <= numRectanglesVertical; i++) {
-            boolean isWhite = verticalStartWhite;
-            for (int j = 0; j <= numRectanglesHorizontal; j++) {
-                r.top = i * mRectangleSize;
-                r.left = j * mRectangleSize;
-                r.bottom = r.top + mRectangleSize;
-                r.right = r.left + mRectangleSize;
-
-                canvas.drawRect(r, isWhite ? mPaintWhite : mPaintGray);
-
-                isWhite = !isWhite;
-            }
-
-            verticalStartWhite = !verticalStartWhite;
-        }
-    }
-}
diff --git a/src/org/omnirom/omnigears/ui/ColorPanelView.java b/src/org/omnirom/omnigears/ui/ColorPanelView.java
deleted file mode 100644
index 5941bf1..0000000
--- a/src/org/omnirom/omnigears/ui/ColorPanelView.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2010 Daniel Nilsson
- * Copyright (C) 2012 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.ui;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.RectF;
-import android.util.AttributeSet;
-import android.view.View;
-
-/**
- * This class draws a panel which which will be filled with a color which can be
- * set. It can be used to show the currently selected color which you will get
- * from the {@link ColorPickerView}.
- *
- * @author Daniel Nilsson
- */
-public class ColorPanelView extends View {
-
-    /**
-     * The width in pixels of the border surrounding the color panel.
-     */
-    private final static float BORDER_WIDTH_PX = 1;
-
-    private static float mDensity = 1f;
-
-    private int mBorderColor = 0xff6E6E6E;
-    private int mColor = 0xff000000;
-
-    private Paint mBorderPaint;
-    private Paint mColorPaint;
-
-    private RectF mDrawingRect;
-    private RectF mColorRect;
-
-    private AlphaPatternDrawable mAlphaPattern;
-
-    public ColorPanelView(Context context) {
-        this(context, null);
-    }
-
-    public ColorPanelView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public ColorPanelView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        init();
-    }
-
-    private void init() {
-        mBorderPaint = new Paint();
-        mColorPaint = new Paint();
-        mDensity = getContext().getResources().getDisplayMetrics().density;
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-
-        final RectF rect = mColorRect;
-
-        if (BORDER_WIDTH_PX > 0) {
-            mBorderPaint.setColor(mBorderColor);
-            canvas.drawRect(mDrawingRect, mBorderPaint);
-        }
-
-        if (mAlphaPattern != null) {
-            mAlphaPattern.draw(canvas);
-        }
-
-        mColorPaint.setColor(mColor);
-
-        canvas.drawRect(rect, mColorPaint);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-
-        int width = MeasureSpec.getSize(widthMeasureSpec);
-        int height = MeasureSpec.getSize(heightMeasureSpec);
-
-        setMeasuredDimension(width, height);
-    }
-
-    @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        super.onSizeChanged(w, h, oldw, oldh);
-
-        mDrawingRect = new RectF();
-        mDrawingRect.left = getPaddingLeft();
-        mDrawingRect.right = w - getPaddingRight();
-        mDrawingRect.top = getPaddingTop();
-        mDrawingRect.bottom = h - getPaddingBottom();
-
-        setUpColorRect();
-
-    }
-
-    private void setUpColorRect() {
-        final RectF dRect = mDrawingRect;
-
-        float left = dRect.left + BORDER_WIDTH_PX;
-        float top = dRect.top + BORDER_WIDTH_PX;
-        float bottom = dRect.bottom - BORDER_WIDTH_PX;
-        float right = dRect.right - BORDER_WIDTH_PX;
-
-        mColorRect = new RectF(left, top, right, bottom);
-
-        mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
-
-        mAlphaPattern.setBounds(Math.round(mColorRect.left),
-                Math.round(mColorRect.top),
-                Math.round(mColorRect.right),
-                Math.round(mColorRect.bottom));
-
-    }
-
-    /**
-     * Set the color that should be shown by this view.
-     *
-     * @param color
-     */
-    public void setColor(int color) {
-        mColor = color;
-        invalidate();
-    }
-
-    /**
-     * Get the color currently show by this view.
-     *
-     * @return
-     */
-    public int getColor() {
-        return mColor;
-    }
-
-    /**
-     * Set the color of the border surrounding the panel.
-     *
-     * @param color
-     */
-    public void setBorderColor(int color) {
-        mBorderColor = color;
-        invalidate();
-    }
-
-    /**
-     * Get the color of the border surrounding the panel.
-     */
-    public int getBorderColor() {
-        return mBorderColor;
-    }
-
-}
diff --git a/src/org/omnirom/omnigears/ui/ColorPickerDialog.java b/src/org/omnirom/omnigears/ui/ColorPickerDialog.java
deleted file mode 100644
index b45a82a..0000000
--- a/src/org/omnirom/omnigears/ui/ColorPickerDialog.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2010 Daniel Nilsson
- * Copyright (C) 2012 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.ui;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.Context;
-import android.graphics.Color;
-import android.graphics.PixelFormat;
-import android.os.Bundle;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.text.InputFilter;
-import android.text.InputFilter.LengthFilter;
-import android.util.Pair;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnFocusChangeListener;
-import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.Spinner;
-import android.widget.SpinnerAdapter;
-import android.widget.TextView;
-
-import com.android.settings.R;
-import org.omnirom.omnigears.ui.ColorPanelView;
-import org.omnirom.omnigears.ui.ColorPickerView;
-import org.omnirom.omnigears.ui.ColorPickerView.OnColorChangedListener;
-
-import java.util.ArrayList;
-import java.util.IllegalFormatException;
-import java.util.Locale;
-
-public class ColorPickerDialog extends AlertDialog implements
-        ColorPickerView.OnColorChangedListener, TextWatcher, OnFocusChangeListener {
-
-    private static final String TAG = "ColorPickerDialog";
-    private final static String STATE_KEY_COLOR = "ColorPickerDialog:color";
-
-    private ColorPickerView mColorPicker;
-
-    private EditText mHexColorInput;
-    private ColorPanelView mNewColor;
-    private LayoutInflater mInflater;
-    private boolean mMultiColor = true;
-    private LinearLayout mColorPanelView;
-    private boolean mWithAlpha;
-
-    public ColorPickerDialog(Context context, int initialColor, boolean withAlpha) {
-        super(context);
-        mWithAlpha = withAlpha;
-        init(initialColor);
-    }
-
-    private void init(int color) {
-        // To fight color banding.
-        getWindow().setFormat(PixelFormat.RGBA_8888);
-        setUp(color);
-    }
-
-    /**
-     * This function sets up the dialog with the proper values.  If the speedOff parameters
-     * has a -1 value disable both spinners
-     *
-     * @param color - the color to set
-     * @param speedOn - the flash time in ms
-     * @param speedOff - the flash length in ms
-     */
-    private void setUp(int color) {
-        mInflater = (LayoutInflater) getContext()
-                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        View layout = mInflater.inflate(R.layout.dialog_color_picker, null);
-
-        mColorPicker = (ColorPickerView) layout.findViewById(R.id.color_picker_view);
-        mHexColorInput = (EditText) layout.findViewById(R.id.hex_color_input);
-        mNewColor = (ColorPanelView) layout.findViewById(R.id.color_panel);
-        mColorPanelView = (LinearLayout) layout.findViewById(R.id.color_panel_view);
-
-        mColorPicker.setOnColorChangedListener(this);
-        mHexColorInput.setOnFocusChangeListener(this);
-        setAlphaSliderVisible(mWithAlpha);
-        mColorPicker.setColor(color, true);
-
-        setView(layout);
-
-        mColorPicker.setVisibility(View.VISIBLE);
-        mColorPanelView.setVisibility(View.VISIBLE);
-    }
-
-    @Override
-    public Bundle onSaveInstanceState() {
-        Bundle state = super.onSaveInstanceState();
-        state.putInt(STATE_KEY_COLOR, getColor());
-        return state;
-    }
-
-    @Override
-    public void onRestoreInstanceState(Bundle state) {
-        super.onRestoreInstanceState(state);
-        mColorPicker.setColor(state.getInt(STATE_KEY_COLOR), true);
-    }
-
-    @Override
-    public void onColorChanged(int color) {
-        final boolean hasAlpha = mWithAlpha;
-        final String format = hasAlpha ? "%08x" : "%06x";
-        final int mask = hasAlpha ? 0xFFFFFFFF : 0x00FFFFFF;
-
-        mNewColor.setColor(color);
-        mHexColorInput.setText(String.format(Locale.US, format, color & mask));
-    }
-
-    public void setAlphaSliderVisible(boolean visible) {
-        mHexColorInput.setFilters(new InputFilter[] { new InputFilter.LengthFilter(visible ? 8 : 6) } );
-        mColorPicker.setAlphaSliderVisible(visible);
-    }
-
-    public int getColor() {
-        return mColorPicker.getColor();
-    }
-
-    @Override
-    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-    }
-
-    @Override
-    public void onTextChanged(CharSequence s, int start, int before, int count) {
-    }
-
-    @Override
-    public void afterTextChanged(Editable s) {
-        String hexColor = mHexColorInput.getText().toString();
-        if (!hexColor.isEmpty()) {
-            try {
-                int color = Color.parseColor('#' + hexColor);
-                if (!mWithAlpha) {
-                    color |= 0xFF000000; // set opaque
-                }
-                mColorPicker.setColor(color);
-                mNewColor.setColor(color);
-            } catch (IllegalArgumentException ex) {
-                // Number format is incorrect, ignore
-            }
-        }
-    }
-
-    @Override
-    public void onFocusChange(View v, boolean hasFocus) {
-        if (!hasFocus) {
-            mHexColorInput.removeTextChangedListener(this);
-            InputMethodManager inputMethodManager = (InputMethodManager) getContext()
-                    .getSystemService(Activity.INPUT_METHOD_SERVICE);
-            inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
-        } else {
-            mHexColorInput.addTextChangedListener(this);
-        }
-    }
-}
diff --git a/src/org/omnirom/omnigears/ui/ColorPickerView.java b/src/org/omnirom/omnigears/ui/ColorPickerView.java
deleted file mode 100644
index 72316f3..0000000
--- a/src/org/omnirom/omnigears/ui/ColorPickerView.java
+++ /dev/null
@@ -1,841 +0,0 @@
-/*
- * Copyright (C) 2010 Daniel Nilsson
- * Copyright (C) 2012 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.ui;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ComposeShader;
-import android.graphics.LinearGradient;
-import android.graphics.Paint;
-import android.graphics.Point;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.RectF;
-import android.graphics.Shader;
-import android.graphics.Paint.Align;
-import android.graphics.Paint.Style;
-import android.graphics.Shader.TileMode;
-import android.os.Build;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-
-/**
- * Displays a color picker to the user and allow them to select a color. A
- * slider for the alpha channel is also available. Enable it by setting
- * setAlphaSliderVisible(boolean) to true.
- *
- * @author Daniel Nilsson
- */
-public class ColorPickerView extends View {
-
-    public interface OnColorChangedListener {
-        public void onColorChanged(int color);
-    }
-
-    private final static int PANEL_SAT_VAL = 0;
-    private final static int PANEL_HUE = 1;
-    private final static int PANEL_ALPHA = 2;
-
-    /**
-     * The width in pixels of the border surrounding all color panels.
-     */
-    private final static float BORDER_WIDTH_PX = 1;
-
-    /**
-     * The width in dp of the hue panel.
-     */
-    private float HUE_PANEL_WIDTH = 30f;
-    /**
-     * The height in dp of the alpha panel
-     */
-    private float ALPHA_PANEL_HEIGHT = 20f;
-    /**
-     * The distance in dp between the different color panels.
-     */
-    private float PANEL_SPACING = 10f;
-    /**
-     * The radius in dp of the color palette tracker circle.
-     */
-    private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f;
-    /**
-     * The dp which the tracker of the hue or alpha panel will extend outside of
-     * its bounds.
-     */
-    private float RECTANGLE_TRACKER_OFFSET = 2f;
-
-    private static float mDensity = 1f;
-
-    private OnColorChangedListener mListener;
-
-    private Paint mSatValPaint;
-    private Paint mSatValTrackerPaint;
-
-    private Paint mHuePaint;
-    private Paint mHueTrackerPaint;
-
-    private Paint mAlphaPaint;
-    private Paint mAlphaTextPaint;
-
-    private Paint mBorderPaint;
-
-    private Shader mValShader;
-    private Shader mSatShader;
-    private Shader mHueShader;
-    private Shader mAlphaShader;
-
-    private int mAlpha = 0xff;
-    private float mHue = 360f;
-    private float mSat = 0f;
-    private float mVal = 0f;
-
-    private String mAlphaSliderText = "Alpha";
-    private int mSliderTrackerColor = 0xff1c1c1c;
-    private int mBorderColor = 0xff6E6E6E;
-    private boolean mShowAlphaPanel = false;
-
-    /*
-     * To remember which panel that has the "focus" when processing hardware
-     * button data.
-     */
-    private int mLastTouchedPanel = PANEL_SAT_VAL;
-
-    /**
-     * Offset from the edge we must have or else the finger tracker will get
-     * clipped when it is drawn outside of the view.
-     */
-    private float mDrawingOffset;
-
-    /*
-     * Distance form the edges of the view of where we are allowed to draw.
-     */
-    private RectF mDrawingRect;
-
-    private RectF mSatValRect;
-    private RectF mHueRect;
-    private RectF mAlphaRect;
-
-    private AlphaPatternDrawable mAlphaPattern;
-
-    private Point mStartTouchPoint = null;
-
-    public ColorPickerView(Context context) {
-        this(context, null);
-    }
-
-    public ColorPickerView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public ColorPickerView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        init();
-    }
-
-    private void init() {
-        mDensity = getContext().getResources().getDisplayMetrics().density;
-        PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity;
-        RECTANGLE_TRACKER_OFFSET *= mDensity;
-        HUE_PANEL_WIDTH *= mDensity;
-        ALPHA_PANEL_HEIGHT *= mDensity;
-        PANEL_SPACING = PANEL_SPACING * mDensity;
-
-        mDrawingOffset = calculateRequiredOffset();
-        initPaintTools();
-
-        // Needed for receiving track ball motion events.
-        setFocusableInTouchMode(true);
-        setFocusable(true);
-        setClickable(true);
-    }
-
-    private void initPaintTools() {
-        mSatValPaint = new Paint();
-        mSatValTrackerPaint = new Paint();
-        mHuePaint = new Paint();
-        mHueTrackerPaint = new Paint();
-        mAlphaPaint = new Paint();
-        mAlphaTextPaint = new Paint();
-        mBorderPaint = new Paint();
-
-        mSatValTrackerPaint.setStyle(Style.STROKE);
-        mSatValTrackerPaint.setStrokeWidth(2f * mDensity);
-        mSatValTrackerPaint.setAntiAlias(true);
-
-        mHueTrackerPaint.setColor(mSliderTrackerColor);
-        mHueTrackerPaint.setStyle(Style.STROKE);
-        mHueTrackerPaint.setStrokeWidth(2f * mDensity);
-        mHueTrackerPaint.setAntiAlias(true);
-
-        mAlphaTextPaint.setColor(0xff1c1c1c);
-        mAlphaTextPaint.setTextSize(14f * mDensity);
-        mAlphaTextPaint.setAntiAlias(true);
-        mAlphaTextPaint.setTextAlign(Align.CENTER);
-        mAlphaTextPaint.setFakeBoldText(true);
-    }
-
-    private float calculateRequiredOffset() {
-        float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET);
-        offset = Math.max(offset, BORDER_WIDTH_PX * mDensity);
-
-        return offset * 1.5f;
-    }
-
-    private int[] buildHueColorArray() {
-        int[] hue = new int[361];
-
-        int count = 0;
-        for (int i = hue.length - 1; i >= 0; i--, count++) {
-            hue[count] = Color.HSVToColor(new float[] {
-                    i, 1f, 1f
-            });
-        }
-        return hue;
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        if (mDrawingRect.width() <= 0 || mDrawingRect.height() <= 0) {
-            return;
-        }
-        drawSatValPanel(canvas);
-        drawHuePanel(canvas);
-        drawAlphaPanel(canvas);
-    }
-
-    private void drawSatValPanel(Canvas canvas) {
-        final RectF rect = mSatValRect;
-        int rgb = Color.HSVToColor(new float[] {
-                mHue, 1f, 1f
-        });
-
-        if (BORDER_WIDTH_PX > 0) {
-            mBorderPaint.setColor(mBorderColor);
-            canvas.drawRect(mDrawingRect.left, mDrawingRect.top, rect.right + BORDER_WIDTH_PX,
-                    rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
-        }
-
-        // On Honeycomb+ we need to use software rendering to create the shader properly
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
-            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
-        }
-
-        // Get the overlaying gradients ready and create the ComposeShader
-        if (mValShader == null) {
-            mValShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom,
-                    0xffffffff, 0xff000000, TileMode.CLAMP);
-        }
-        mSatShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,
-                0xffffffff, rgb, TileMode.CLAMP);
-        ComposeShader mShader = new ComposeShader(mValShader, mSatShader, Mode.MULTIPLY);
-        mSatValPaint.setShader(mShader);
-        canvas.drawRect(rect, mSatValPaint);
-
-        Point p = satValToPoint(mSat, mVal);
-        mSatValTrackerPaint.setColor(0xff000000);
-        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity,
-                mSatValTrackerPaint);
-
-        mSatValTrackerPaint.setColor(0xffdddddd);
-        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);
-    }
-
-    private void drawHuePanel(Canvas canvas) {
-        final RectF rect = mHueRect;
-
-        if (BORDER_WIDTH_PX > 0) {
-            mBorderPaint.setColor(mBorderColor);
-            canvas.drawRect(rect.left - BORDER_WIDTH_PX,
-                    rect.top - BORDER_WIDTH_PX,
-                    rect.right + BORDER_WIDTH_PX,
-                    rect.bottom + BORDER_WIDTH_PX,
-                    mBorderPaint);
-        }
-
-        if (mHueShader == null) {
-            mHueShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom,
-                    buildHueColorArray(), null, TileMode.CLAMP);
-            mHuePaint.setShader(mHueShader);
-        }
-
-        canvas.drawRect(rect, mHuePaint);
-
-        float rectHeight = 4 * mDensity / 2;
-
-        Point p = hueToPoint(mHue);
-
-        RectF r = new RectF();
-        r.left = rect.left - RECTANGLE_TRACKER_OFFSET;
-        r.right = rect.right + RECTANGLE_TRACKER_OFFSET;
-        r.top = p.y - rectHeight;
-        r.bottom = p.y + rectHeight;
-
-        canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
-
-    }
-
-    private void drawAlphaPanel(Canvas canvas) {
-        if (!mShowAlphaPanel || mAlphaRect == null || mAlphaPattern == null) {
-            return;
-        }
-
-        final RectF rect = mAlphaRect;
-
-        if (BORDER_WIDTH_PX > 0) {
-            mBorderPaint.setColor(mBorderColor);
-            canvas.drawRect(rect.left - BORDER_WIDTH_PX,
-                    rect.top - BORDER_WIDTH_PX,
-                    rect.right + BORDER_WIDTH_PX,
-                    rect.bottom + BORDER_WIDTH_PX,
-                    mBorderPaint);
-        }
-
-        mAlphaPattern.draw(canvas);
-
-        float[] hsv = new float[] {
-                mHue, mSat, mVal
-        };
-        int color = Color.HSVToColor(hsv);
-        int acolor = Color.HSVToColor(0, hsv);
-
-        mAlphaShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,
-                color, acolor, TileMode.CLAMP);
-
-        mAlphaPaint.setShader(mAlphaShader);
-
-        canvas.drawRect(rect, mAlphaPaint);
-
-        if (mAlphaSliderText != null && mAlphaSliderText != "") {
-            canvas.drawText(mAlphaSliderText, rect.centerX(), rect.centerY() + 4 * mDensity,
-                    mAlphaTextPaint);
-        }
-
-        float rectWidth = 4 * mDensity / 2;
-        Point p = alphaToPoint(mAlpha);
-
-        RectF r = new RectF();
-        r.left = p.x - rectWidth;
-        r.right = p.x + rectWidth;
-        r.top = rect.top - RECTANGLE_TRACKER_OFFSET;
-        r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET;
-
-        canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
-    }
-
-    private Point hueToPoint(float hue) {
-        final RectF rect = mHueRect;
-        final float height = rect.height();
-
-        Point p = new Point();
-        p.y = (int) (height - (hue * height / 360f) + rect.top);
-        p.x = (int) rect.left;
-        return p;
-    }
-
-    private Point satValToPoint(float sat, float val) {
-
-        final RectF rect = mSatValRect;
-        final float height = rect.height();
-        final float width = rect.width();
-
-        Point p = new Point();
-
-        p.x = (int) (sat * width + rect.left);
-        p.y = (int) ((1f - val) * height + rect.top);
-
-        return p;
-    }
-
-    private Point alphaToPoint(int alpha) {
-        final RectF rect = mAlphaRect;
-        final float width = rect.width();
-
-        Point p = new Point();
-        p.x = (int) (width - (alpha * width / 0xff) + rect.left);
-        p.y = (int) rect.top;
-        return p;
-    }
-
-    private float[] pointToSatVal(float x, float y) {
-        final RectF rect = mSatValRect;
-        float[] result = new float[2];
-        float width = rect.width();
-        float height = rect.height();
-
-        if (x < rect.left) {
-            x = 0f;
-        } else if (x > rect.right) {
-            x = width;
-        } else {
-            x = x - rect.left;
-        }
-
-        if (y < rect.top) {
-            y = 0f;
-        } else if (y > rect.bottom) {
-            y = height;
-        } else {
-            y = y - rect.top;
-        }
-
-        result[0] = 1.f / width * x;
-        result[1] = 1.f - (1.f / height * y);
-        return result;
-    }
-
-    private float pointToHue(float y) {
-        final RectF rect = mHueRect;
-        float height = rect.height();
-
-        if (y < rect.top) {
-            y = 0f;
-        } else if (y > rect.bottom) {
-            y = height;
-        } else {
-            y = y - rect.top;
-        }
-        return 360f - (y * 360f / height);
-    }
-
-    private int pointToAlpha(int x) {
-        final RectF rect = mAlphaRect;
-        final int width = (int) rect.width();
-
-        if (x < rect.left) {
-            x = 0;
-        } else if (x > rect.right) {
-            x = width;
-        } else {
-            x = x - (int) rect.left;
-        }
-        return 0xff - (x * 0xff / width);
-    }
-
-    @Override
-    public boolean onTrackballEvent(MotionEvent event) {
-        float x = event.getX();
-        float y = event.getY();
-        boolean update = false;
-
-        if (event.getAction() == MotionEvent.ACTION_MOVE) {
-            switch (mLastTouchedPanel) {
-                case PANEL_SAT_VAL:
-                    float sat,
-                    val;
-                    sat = mSat + x / 50f;
-                    val = mVal - y / 50f;
-                    if (sat < 0f) {
-                        sat = 0f;
-                    } else if (sat > 1f) {
-                        sat = 1f;
-                    }
-
-                    if (val < 0f) {
-                        val = 0f;
-                    } else if (val > 1f) {
-                        val = 1f;
-                    }
-                    mSat = sat;
-                    mVal = val;
-                    update = true;
-                    break;
-                case PANEL_HUE:
-                    float hue = mHue - y * 10f;
-                    if (hue < 0f) {
-                        hue = 0f;
-                    } else if (hue > 360f) {
-                        hue = 360f;
-                    }
-                    mHue = hue;
-                    update = true;
-                    break;
-                case PANEL_ALPHA:
-                    if (!mShowAlphaPanel || mAlphaRect == null) {
-                        update = false;
-                    } else {
-                        int alpha = (int) (mAlpha - x * 10);
-                        if (alpha < 0) {
-                            alpha = 0;
-                        } else if (alpha > 0xff) {
-                            alpha = 0xff;
-                        }
-                        mAlpha = alpha;
-                        update = true;
-                    }
-                    break;
-            }
-        }
-
-        if (update) {
-            if (mListener != null) {
-                mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] {
-                        mHue, mSat, mVal
-                }));
-            }
-            invalidate();
-            return true;
-        }
-        return super.onTrackballEvent(event);
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        boolean update = false;
-
-        switch (event.getAction()) {
-            case MotionEvent.ACTION_DOWN:
-                mStartTouchPoint = new Point((int) event.getX(), (int) event.getY());
-                update = moveTrackersIfNeeded(event);
-                break;
-            case MotionEvent.ACTION_MOVE:
-                update = moveTrackersIfNeeded(event);
-                break;
-            case MotionEvent.ACTION_UP:
-                mStartTouchPoint = null;
-                update = moveTrackersIfNeeded(event);
-                break;
-        }
-
-        if (update) {
-            requestFocus();
-            if (mListener != null) {
-                mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] {
-                        mHue, mSat, mVal
-                }));
-            }
-            invalidate();
-            return true;
-        }
-
-        return super.onTouchEvent(event);
-    }
-
-    private boolean moveTrackersIfNeeded(MotionEvent event) {
-
-        if (mStartTouchPoint == null)
-            return false;
-
-        boolean update = false;
-        int startX = mStartTouchPoint.x;
-        int startY = mStartTouchPoint.y;
-
-        if (mHueRect.contains(startX, startY)) {
-            mLastTouchedPanel = PANEL_HUE;
-            mHue = pointToHue(event.getY());
-            update = true;
-        } else if (mSatValRect.contains(startX, startY)) {
-            mLastTouchedPanel = PANEL_SAT_VAL;
-            float[] result = pointToSatVal(event.getX(), event.getY());
-            mSat = result[0];
-            mVal = result[1];
-            update = true;
-        } else if (mAlphaRect != null && mAlphaRect.contains(startX, startY)) {
-            mLastTouchedPanel = PANEL_ALPHA;
-            mAlpha = pointToAlpha((int) event.getX());
-            update = true;
-        }
-
-        return update;
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int width = 0;
-        int height = 0;
-
-        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
-        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-
-        int widthAllowed = MeasureSpec.getSize(widthMeasureSpec);
-        int heightAllowed = MeasureSpec.getSize(heightMeasureSpec);
-
-        widthAllowed = chooseWidth(widthMode, widthAllowed);
-        heightAllowed = chooseHeight(heightMode, heightAllowed);
-
-        if (!mShowAlphaPanel) {
-            height = (int) (widthAllowed - PANEL_SPACING - HUE_PANEL_WIDTH);
-
-            // If calculated height (based on the width) is more than the
-            // allowed height.
-            if (height > heightAllowed && heightMode != MeasureSpec.UNSPECIFIED) {
-                height = heightAllowed;
-                width = (int) (height + PANEL_SPACING + HUE_PANEL_WIDTH);
-            } else {
-                width = widthAllowed;
-            }
-        } else {
-
-            width = (int) (heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH);
-
-            if (width > widthAllowed && widthMode != MeasureSpec.UNSPECIFIED) {
-                width = widthAllowed;
-                height = (int) (widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT);
-            } else {
-                height = heightAllowed;
-            }
-        }
-        setMeasuredDimension(width, height);
-    }
-
-    private int chooseWidth(int mode, int size) {
-        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
-            return size;
-        } else { // (mode == MeasureSpec.UNSPECIFIED)
-            return getPrefferedWidth();
-        }
-    }
-
-    private int chooseHeight(int mode, int size) {
-        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
-            return size;
-        } else { // (mode == MeasureSpec.UNSPECIFIED)
-            return getPrefferedHeight();
-        }
-    }
-
-    private int getPrefferedWidth() {
-        int width = getPrefferedHeight();
-        if (mShowAlphaPanel) {
-            width -= (PANEL_SPACING + ALPHA_PANEL_HEIGHT);
-        }
-        return (int) (width + HUE_PANEL_WIDTH + PANEL_SPACING);
-    }
-
-    private int getPrefferedHeight() {
-        int height = (int) (200 * mDensity);
-        if (mShowAlphaPanel) {
-            height += PANEL_SPACING + ALPHA_PANEL_HEIGHT;
-        }
-        return height;
-    }
-
-    @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        super.onSizeChanged(w, h, oldw, oldh);
-
-        mDrawingRect = new RectF();
-        mDrawingRect.left = mDrawingOffset + getPaddingLeft();
-        mDrawingRect.right = w - mDrawingOffset - getPaddingRight();
-        mDrawingRect.top = mDrawingOffset + getPaddingTop();
-        mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom();
-
-        setUpSatValRect();
-        setUpHueRect();
-        setUpAlphaRect();
-    }
-
-    private void setUpSatValRect() {
-        final RectF dRect = mDrawingRect;
-        float panelSide = dRect.height() - BORDER_WIDTH_PX * 2;
-
-        if (mShowAlphaPanel) {
-            panelSide -= PANEL_SPACING + ALPHA_PANEL_HEIGHT;
-        }
-
-        float left = dRect.left + BORDER_WIDTH_PX;
-        float top = dRect.top + BORDER_WIDTH_PX;
-        float bottom = top + panelSide;
-        float right = left + panelSide;
-        mSatValRect = new RectF(left, top, right, bottom);
-    }
-
-    private void setUpHueRect() {
-        final RectF dRect = mDrawingRect;
-
-        float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX;
-        float top = dRect.top + BORDER_WIDTH_PX;
-        float bottom = dRect.bottom - BORDER_WIDTH_PX
-                - (mShowAlphaPanel ? (PANEL_SPACING + ALPHA_PANEL_HEIGHT) : 0);
-        float right = dRect.right - BORDER_WIDTH_PX;
-
-        mHueRect = new RectF(left, top, right, bottom);
-    }
-
-    private void setUpAlphaRect() {
-        if (!mShowAlphaPanel) {
-            return;
-        }
-
-        final RectF dRect = mDrawingRect;
-        float left = dRect.left + BORDER_WIDTH_PX;
-        float top = dRect.bottom - ALPHA_PANEL_HEIGHT + BORDER_WIDTH_PX;
-        float bottom = dRect.bottom - BORDER_WIDTH_PX;
-        float right = dRect.right - BORDER_WIDTH_PX;
-
-        mAlphaRect = new RectF(left, top, right, bottom);
-        mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
-        mAlphaPattern.setBounds(Math.round(mAlphaRect.left), Math
-                .round(mAlphaRect.top), Math.round(mAlphaRect.right), Math
-                .round(mAlphaRect.bottom));
-    }
-
-    /**
-     * Set a OnColorChangedListener to get notified when the color selected by
-     * the user has changed.
-     *
-     * @param listener
-     */
-    public void setOnColorChangedListener(OnColorChangedListener listener) {
-        mListener = listener;
-    }
-
-    /**
-     * Set the color of the border surrounding all panels.
-     *
-     * @param color
-     */
-    public void setBorderColor(int color) {
-        mBorderColor = color;
-        invalidate();
-    }
-
-    /**
-     * Get the color of the border surrounding all panels.
-     */
-    public int getBorderColor() {
-        return mBorderColor;
-    }
-
-    /**
-     * Get the current color this view is showing.
-     *
-     * @return the current color.
-     */
-    public int getColor() {
-        return Color.HSVToColor(mAlpha, new float[] {
-                mHue, mSat, mVal
-        });
-    }
-
-    /**
-     * Set the color the view should show.
-     *
-     * @param color The color that should be selected.
-     */
-    public void setColor(int color) {
-        setColor(color, false);
-    }
-
-    /**
-     * Set the color this view should show.
-     *
-     * @param color The color that should be selected.
-     * @param callback If you want to get a callback to your
-     *            OnColorChangedListener.
-     */
-    public void setColor(int color, boolean callback) {
-        int alpha = Color.alpha(color);
-        int red = Color.red(color);
-        int blue = Color.blue(color);
-        int green = Color.green(color);
-        float[] hsv = new float[3];
-
-        Color.RGBToHSV(red, green, blue, hsv);
-        mAlpha = alpha;
-        mHue = hsv[0];
-        mSat = hsv[1];
-        mVal = hsv[2];
-
-        if (callback && mListener != null) {
-            mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] {
-                    mHue, mSat, mVal
-            }));
-        }
-        invalidate();
-    }
-
-    /**
-     * Get the drawing offset of the color picker view. The drawing offset is
-     * the distance from the side of a panel to the side of the view minus the
-     * padding. Useful if you want to have your own panel below showing the
-     * currently selected color and want to align it perfectly.
-     *
-     * @return The offset in pixels.
-     */
-    public float getDrawingOffset() {
-        return mDrawingOffset;
-    }
-
-    /**
-     * Set if the user is allowed to adjust the alpha panel. Default is false.
-     * If it is set to false no alpha will be set.
-     *
-     * @param visible
-     */
-    public void setAlphaSliderVisible(boolean visible) {
-        if (mShowAlphaPanel != visible) {
-            mShowAlphaPanel = visible;
-
-            /*
-             * Reset all shader to force a recreation. Otherwise they will not
-             * look right after the size of the view has changed.
-             */
-            mValShader = null;
-            mSatShader = null;
-            mHueShader = null;
-            mAlphaShader = null;
-            requestLayout();
-        }
-
-    }
-
-    public boolean isAlphaSliderVisible() {
-        return mShowAlphaPanel;
-    }
-
-    public void setSliderTrackerColor(int color) {
-        mSliderTrackerColor = color;
-        mHueTrackerPaint.setColor(mSliderTrackerColor);
-        invalidate();
-    }
-
-    public int getSliderTrackerColor() {
-        return mSliderTrackerColor;
-    }
-
-    /**
-     * Set the text that should be shown in the alpha slider. Set to null to
-     * disable text.
-     *
-     * @param res string resource id.
-     */
-    public void setAlphaSliderText(int res) {
-        String text = getContext().getString(res);
-        setAlphaSliderText(text);
-    }
-
-    /**
-     * Set the text that should be shown in the alpha slider. Set to null to
-     * disable text.
-     *
-     * @param text Text that should be shown.
-     */
-    public void setAlphaSliderText(String text) {
-        mAlphaSliderText = text;
-        invalidate();
-    }
-
-    /**
-     * Get the current value of the text that will be shown in the alpha slider.
-     *
-     * @return
-     */
-    public String getAlphaSliderText() {
-        return mAlphaSliderText;
-    }
-}
diff --git a/src/org/omnirom/omnigears/ui/ShortcutDialog.java b/src/org/omnirom/omnigears/ui/ShortcutDialog.java
deleted file mode 100644
index 139c686..0000000
--- a/src/org/omnirom/omnigears/ui/ShortcutDialog.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- *  Copyright (C) 2016 The OmniROM Project
- *
- * This program 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 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
- *
-package org.omnirom.omnigears.ui;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.graphics.Point;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ArrayAdapter;
-import android.widget.BaseAdapter;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import org.omnirom.omnigears.R;
-import org.omnirom.omnigears.ui.dslv.DragSortController;
-import org.omnirom.omnigears.ui.dslv.DragSortListView;
-
-import java.net.URISyntaxException;
-import java.text.Collator;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Set;
-import java.util.HashSet;
-
-public class ShortcutDialog extends AlertDialog implements
-        DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
-    private LayoutInflater mInflater;
-    private List<String> mShortcutList;
-    private ShortcutListAdapter mShortcutAdapter;
-    private DragSortListView mShortcutConfigList;
-    private AlertDialog mAddShortcutDialog;
-    private final List<MyApplicationInfo> mPackageInfoList = new ArrayList<MyApplicationInfo>();
-
-    ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
-            ViewGroup.LayoutParams.MATCH_PARENT,
-            ViewGroup.LayoutParams.WRAP_CONTENT);
-
-    class MyApplicationInfo {
-        ApplicationInfo info;
-        CharSequence label;
-        ResolveInfo resolveInfo;
-    }
-
-    public class ShortcutListAdapter extends ArrayAdapter<String> {
-        public ShortcutListAdapter(Context context) {
-            super(context, R.layout.shortcut_app_item, mShortcutList);
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            AppViewHolder holder = AppViewHolder.createOrRecycle(mInflater, convertView);
-            convertView = holder.rootView;
-            String intentString = getItem(position);
-            Intent intent = null;
-            try {
-                intent = Intent.parseUri(intentString, 0);
-            } catch (URISyntaxException e) {
-                // TODO should never happen - better build a intent list
-                return convertView;
-            }
-            final List<ResolveInfo> pkgAppsList = getContext().getPackageManager().queryIntentActivities(intent, 0);
-            if (pkgAppsList.size() > 0) {
-                Drawable icon = pkgAppsList.get(0).activityInfo.loadIcon(getContext().getPackageManager());
-                CharSequence label = pkgAppsList.get(0).activityInfo.loadLabel(getContext().getPackageManager());
-                holder.appName.setText(label);
-                holder.appIcon.setImageDrawable(icon);
-            }
-            return convertView;
-        }
-    }
-
-    private class ShortcutDragSortController extends DragSortController {
-
-        public ShortcutDragSortController() {
-            super(mShortcutConfigList, R.id.drag_handle,
-                    DragSortController.ON_DOWN,
-                    DragSortController.FLING_RIGHT_REMOVE);
-            setRemoveEnabled(true);
-            setSortEnabled(true);
-            setBackgroundColor(0x363636);
-        }
-
-        @Override
-        public void onDragFloatView(View floatView, Point floatPoint,
-                Point touchPoint) {
-            floatView.setLayoutParams(params);
-            mShortcutConfigList.setFloatAlpha(0.8f);
-        }
-
-        @Override
-        public View onCreateFloatView(int position) {
-            View v = mShortcutAdapter.getView(position, null,
-                    mShortcutConfigList);
-            v.setLayoutParams(params);
-            return v;
-        }
-
-        @Override
-        public void onDestroyFloatView(View floatView) {
-        }
-    }
-
-    public ShortcutDialog(Context context) {
-        super(context);
-        mInflater = (LayoutInflater) context
-                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
-        final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
-        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
-        List<ResolveInfo> installedAppsInfo = getContext().getPackageManager().queryIntentActivities(
-                mainIntent, 0);
-
-        for (ResolveInfo info : installedAppsInfo) {
-            MyApplicationInfo myInfo = new MyApplicationInfo();
-            myInfo.resolveInfo = info;
-            myInfo.label = getResolveInfoTitle(info);
-            mPackageInfoList.add(myInfo);
-        }
-        Collections.sort(mPackageInfoList, sDisplayNameComparator);
-
-        mShortcutList = new ArrayList<String>();
-        String shortcutStrings = Settings.Secure.getString(getContext().getContentResolver(), Settings.Secure.LOCK_SHORTCUTS);
-        if (shortcutStrings != null && shortcutStrings.length() != 0) {
-            String[] values = TextUtils.split(shortcutStrings, "##");
-
-            for (String intentString : values) {
-                Intent intent = null;
-                try {
-                    intent = Intent.parseUri(intentString, 0);
-                } catch (URISyntaxException e) {
-                    continue;
-                }
-
-                final List<ResolveInfo> pkgAppsList = getContext().getPackageManager().queryIntentActivities(intent, 0);
-                if (pkgAppsList.size() == 0) {
-                    continue;
-                }
-                mShortcutList.add(intentString);
-            }
-        }
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        final Context context = getContext();
-        final View view = getLayoutInflater().inflate(R.layout.shortcut_dialog,
-                null);
-        setView(view);
-        setTitle(R.string.lockscreen_shortcut_apps_title);
-        setCancelable(true);
-
-        setButton(DialogInterface.BUTTON_POSITIVE,
-                context.getString(android.R.string.ok), this);
-        setButton(DialogInterface.BUTTON_NEUTRAL,
-                context.getString(R.string.lockscreen_shortcut_add), this);
-        setButton(DialogInterface.BUTTON_NEGATIVE,
-                context.getString(android.R.string.cancel), this);
-
-        super.onCreate(savedInstanceState);
-
-        mShortcutConfigList = (DragSortListView) view
-                .findViewById(R.id.shortcut_apps);
-        mShortcutAdapter = new ShortcutListAdapter(context);
-        mShortcutConfigList.setAdapter(mShortcutAdapter);
-
-        final DragSortController dragSortController = new ShortcutDragSortController();
-        mShortcutConfigList.setFloatViewManager(dragSortController);
-        mShortcutConfigList
-                .setDropListener(new DragSortListView.DropListener() {
-                    @Override
-                    public void drop(int from, int to) {
-                        String intent = mShortcutList.remove(from);
-                        mShortcutList.add(to, intent);
-                        mShortcutAdapter.notifyDataSetChanged();
-                    }
-                });
-        mShortcutConfigList
-                .setRemoveListener(new DragSortListView.RemoveListener() {
-                    @Override
-                    public void remove(int which) {
-                        mShortcutList.remove(which);
-                        mShortcutAdapter.notifyDataSetChanged();
-                    }
-                });
-        mShortcutConfigList.setOnTouchListener(new View.OnTouchListener() {
-            @Override
-            public boolean onTouch(View view, MotionEvent motionEvent) {
-                return dragSortController.onTouch(view, motionEvent);
-            }
-        });
-        mShortcutConfigList.setItemsCanFocus(false);
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-
-        Button neutralButton = getButton(DialogInterface.BUTTON_NEUTRAL);
-        neutralButton.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                showAddShortcutDialog();
-            }
-        });
-    }
-
-    @Override
-    protected void onStop() {
-        super.onStop();
-        if (mAddShortcutDialog != null) {
-            mAddShortcutDialog.dismiss();
-        }
-    }
-
-    @Override
-    public void onDismiss(DialogInterface dialog) {
-        if (mAddShortcutDialog != null) {
-            mAddShortcutDialog = null;
-        }
-    }
-
-    @Override
-    public void onClick(DialogInterface dialog, int which) {
-        if (which == DialogInterface.BUTTON_POSITIVE) {
-            Settings.Secure.putString(getContext().getContentResolver(), Settings.Secure.LOCK_SHORTCUTS,
-                    TextUtils.join("##", mShortcutList.toArray()));
-        } else if (which == DialogInterface.BUTTON_NEGATIVE) {
-            cancel();
-        }
-    }
-
-    private String getResolveInfoTitle(ResolveInfo info) {
-        CharSequence label = info.loadLabel(getContext().getPackageManager());
-        if (label == null) label = info.activityInfo.name;
-        return label != null ? label.toString() : null;
-    }
-
-    private Intent getIntentForResolveInfo(ResolveInfo info, String action) {
-        Intent intent = new Intent(action);
-        ActivityInfo ai = info.activityInfo;
-        intent.setClassName(ai.packageName, ai.name);
-        return intent;
-    }
-
-    private void showAddShortcutDialog() {
-        if (mAddShortcutDialog != null && mAddShortcutDialog.isShowing()) {
-            return;
-        }
-
-        mAddShortcutDialog = new AddShortcutDialog(getContext());
-        mAddShortcutDialog.setOnDismissListener(this);
-        mAddShortcutDialog.show();
-    }
-
-    public void applyChanges(List<String> shortcutListEdit) {
-        mShortcutList.clear();
-        mShortcutList.addAll(shortcutListEdit);
-        mShortcutAdapter.notifyDataSetChanged();
-    }
-
-    private class AddShortcutDialog extends AlertDialog implements
-            DialogInterface.OnClickListener {
-        private AppListAdapter mAppAdapter;
-        private List<String> mShortcutListEdit;
-        private ListView mListView;
-
-        public class AppListAdapter extends ArrayAdapter<MyApplicationInfo> {
-            public AppListAdapter(Context context) {
-                super(context, R.layout.app_select_item, mPackageInfoList);
-            }
-
-            @Override
-            public View getView(int position, View convertView, ViewGroup parent) {
-                AppSelectViewHolder holder = AppSelectViewHolder.createOrRecycle(mInflater, convertView);
-                convertView = holder.rootView;
-                MyApplicationInfo info = getItem(position);
-                holder.appName.setText(info.label);
-                Drawable icon = info.resolveInfo.loadIcon(getContext().getPackageManager());
-                if (icon != null) {
-                    holder.appIcon.setImageDrawable(icon);
-                } else {
-                    holder.appIcon.setImageDrawable(null);
-                }
-
-                Intent intent = getIntentForResolveInfo(info.resolveInfo, Intent.ACTION_MAIN);
-                intent.addCategory(Intent.CATEGORY_LAUNCHER);
-                String value = intent.toUri(0).toString();
-                holder.checkBox.setChecked(mShortcutListEdit.contains(value));
-                return convertView;
-            }
-        }
-
-        protected AddShortcutDialog(Context context) {
-            super(context);
-        }
-
-        @Override
-        public void onClick(DialogInterface dialog, int which) {
-            if (which == DialogInterface.BUTTON_POSITIVE) {
-                applyChanges(mShortcutListEdit);
-            } else if (which == DialogInterface.BUTTON_NEGATIVE) {
-                cancel();
-            }
-        }
-
-        @Override
-        protected void onCreate(Bundle savedInstanceState) {
-            final Context context = getContext();
-            final View view = getLayoutInflater().inflate(
-                    R.layout.preference_app_list, null);
-            setView(view);
-            setTitle(R.string.lockscreen_shortcut_add_dialog_title);
-            setCancelable(true);
-
-            setButton(DialogInterface.BUTTON_POSITIVE,
-                    context.getString(android.R.string.ok), this);
-            setButton(DialogInterface.BUTTON_NEGATIVE,
-                    context.getString(android.R.string.cancel), this);
-
-            super.onCreate(savedInstanceState);
-            mShortcutListEdit = new ArrayList<String>();
-            mShortcutListEdit.addAll(mShortcutList);
-            mListView = (ListView) view.findViewById(R.id.app_list);
-            mAppAdapter = new AppListAdapter(getContext());
-            mListView.setAdapter(mAppAdapter);
-            mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-                @Override
-                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                    final AppSelectViewHolder holder = (AppSelectViewHolder) view.getTag();
-                    final boolean isChecked = !holder.checkBox.isChecked();
-                    holder.checkBox.setChecked(isChecked);
-
-                    MyApplicationInfo myInfo = mAppAdapter.getItem(position);
-                    ResolveInfo info = myInfo.resolveInfo;
-                    Intent intent = getIntentForResolveInfo(info, Intent.ACTION_MAIN);
-                    intent.addCategory(Intent.CATEGORY_LAUNCHER);
-                    String value = intent.toUri(0).toString();
-
-                    if (isChecked) {
-                        mShortcutListEdit.add(value);
-                    } else {
-                        mShortcutListEdit.remove(value);
-                    }
-                }
-            });
-        }
-    }
-
-    public static class AppSelectViewHolder {
-        public View rootView;
-        public TextView appName;
-        public ImageView appIcon;
-        public CheckBox checkBox;
-
-        public static AppSelectViewHolder createOrRecycle(LayoutInflater inflater, View convertView) {
-            if (convertView == null) {
-                convertView = inflater.inflate(R.layout.app_select_item, null);
-
-                // Creates a ViewHolder and store references to the two children views
-                // we want to bind data to.
-                AppSelectViewHolder holder = new AppSelectViewHolder();
-                holder.rootView = convertView;
-                holder.appName = (TextView) convertView.findViewById(R.id.app_name);
-                holder.appIcon = (ImageView) convertView.findViewById(R.id.app_icon);
-                holder.checkBox = (CheckBox) convertView.findViewById(android.R.id.checkbox);
-                convertView.setTag(holder);
-                return holder;
-            } else {
-                // Get the ViewHolder back to get fast access to the TextView
-                // and the ImageView.
-                return (AppSelectViewHolder)convertView.getTag();
-            }
-        }
-    }
-
-    public static class AppViewHolder {
-        public View rootView;
-        public TextView appName;
-        public ImageView appIcon;
-
-        public static AppViewHolder createOrRecycle(LayoutInflater inflater, View convertView) {
-            if (convertView == null) {
-                convertView = inflater.inflate(R.layout.shortcut_app_item, null);
-
-                // Creates a ViewHolder and store references to the two children views
-                // we want to bind data to.
-                AppViewHolder holder = new AppViewHolder();
-                holder.rootView = convertView;
-                holder.appName = (TextView) convertView.findViewById(R.id.app_name);
-                holder.appIcon = (ImageView) convertView.findViewById(R.id.app_icon);
-                convertView.setTag(holder);
-                return holder;
-            } else {
-                // Get the ViewHolder back to get fast access to the TextView
-                // and the ImageView.
-                return (AppViewHolder)convertView.getTag();
-            }
-        }
-    }
-
-    private final static Comparator<MyApplicationInfo> sDisplayNameComparator
-            = new Comparator<MyApplicationInfo>() {
-
-        private final Collator collator = Collator.getInstance();
-
-        public final int compare(MyApplicationInfo a, MyApplicationInfo b) {
-            return collator.compare(a.label, b.label);
-        }
-    };
-}*/
diff --git a/src/org/omnirom/omnigears/ui/dslv/DragGripView.java b/src/org/omnirom/omnigears/ui/dslv/DragGripView.java
deleted file mode 100644
index 8922035..0000000
--- a/src/org/omnirom/omnigears/ui/dslv/DragGripView.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2013 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.ui.dslv;
-
-import org.omnirom.omnigears.R;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.View;
-
-public class DragGripView extends View {
-    private static final int[] ATTRS = new int[]{
-            android.R.attr.gravity,
-            android.R.attr.color,
-    };
-
-    private static final int HORIZ_RIDGES = 3;
-
-    private int mGravity = Gravity.START;
-    private int mColor = Color.BLACK;
-
-    private Paint mRidgePaint;
-
-    private float mRidgeSize;
-    private float mRidgeGap;
-
-    private int mWidth;
-    private int mHeight;
-
-    public DragGripView(Context context) {
-        this(context, null, 0);
-    }
-
-    public DragGripView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public DragGripView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        final TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
-        mGravity = a.getInteger(0, mGravity);
-        mColor = a.getColor(1, mColor);
-        a.recycle();
-
-        TypedValue value = new TypedValue();
-        getContext().getTheme().resolveAttribute(android.R.attr.colorControlNormal, value, true);
-        mColor = getContext().getColor(value.resourceId);
-
-        final Resources res = getResources();
-        mRidgeSize = res.getDimensionPixelSize(R.dimen.drag_grip_ridge_size);
-        mRidgeGap = res.getDimensionPixelSize(R.dimen.drag_grip_ridge_gap);
-
-        mRidgePaint = new Paint();
-        mRidgePaint.setColor(mColor);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        setMeasuredDimension(
-                View.resolveSize(
-                        (int) (HORIZ_RIDGES * (mRidgeSize + mRidgeGap) - mRidgeGap)
-                                + getPaddingLeft() + getPaddingRight(),
-                        widthMeasureSpec),
-                View.resolveSize(
-                        (int) mRidgeSize,
-                        heightMeasureSpec));
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-
-        float drawWidth = HORIZ_RIDGES * (mRidgeSize + mRidgeGap) - mRidgeGap;
-        float drawLeft;
-
-        switch (Gravity.getAbsoluteGravity(mGravity, getLayoutDirection())
-                & Gravity.HORIZONTAL_GRAVITY_MASK) {
-            case Gravity.CENTER_HORIZONTAL:
-                drawLeft = getPaddingLeft()
-                        + ((mWidth - getPaddingLeft() - getPaddingRight()) - drawWidth) / 2;
-                break;
-            case Gravity.RIGHT:
-                drawLeft = getWidth() - getPaddingRight() - drawWidth;
-                break;
-            default:
-                drawLeft = getPaddingLeft();
-        }
-
-        int vertRidges = (int) ((mHeight - getPaddingTop() - getPaddingBottom() + mRidgeGap)
-                / (mRidgeSize + mRidgeGap));
-        float drawHeight = vertRidges * (mRidgeSize + mRidgeGap) - mRidgeGap;
-        float drawTop = getPaddingTop()
-                + ((mHeight - getPaddingTop() - getPaddingBottom()) - drawHeight) / 2;
-
-        for (int y = 0; y < vertRidges; y++) {
-            for (int x = 0; x < HORIZ_RIDGES; x++) {
-                canvas.drawRect(
-                        drawLeft + x * (mRidgeSize + mRidgeGap),
-                        drawTop + y * (mRidgeSize + mRidgeGap),
-                        drawLeft + x * (mRidgeSize + mRidgeGap) + mRidgeSize,
-                        drawTop + y * (mRidgeSize + mRidgeGap) + mRidgeSize,
-                        mRidgePaint);
-            }
-        }
-    }
-
-    @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        super.onSizeChanged(w, h, oldw, oldh);
-        mHeight = h;
-        mWidth = w;
-    }
-}
diff --git a/src/org/omnirom/omnigears/ui/dslv/DragSortController.java b/src/org/omnirom/omnigears/ui/dslv/DragSortController.java
deleted file mode 100644
index a456923..0000000
--- a/src/org/omnirom/omnigears/ui/dslv/DragSortController.java
+++ /dev/null
@@ -1,489 +0,0 @@
-/**
- * A subclass of the Android ListView component that enables drag
- * and drop re-ordering of list items.
- *
- * Copyright 2012 Carl Bauer
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.ui.dslv;
-
-import android.graphics.Point;
-import android.view.GestureDetector;
-import android.view.HapticFeedbackConstants;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.widget.AdapterView;
-
-/**
- * Class that starts and stops item drags on a {@link DragSortListView}
- * based on touch gestures. This class also inherits from
- * {@link SimpleFloatViewManager}, which provides basic float View
- * creation.
- *
- * An instance of this class is meant to be passed to the methods
- * {@link DragSortListView#setTouchListener()} and
- * {@link DragSortListView#setFloatViewManager()} of your
- * {@link DragSortListView} instance.
- */
-public class DragSortController extends SimpleFloatViewManager implements View.OnTouchListener, GestureDetector.OnGestureListener {
-
-    /**
-     * Drag init mode enum.
-     */
-    public static final int ON_DOWN = 0;
-    public static final int ON_DRAG = 1;
-    public static final int ON_LONG_PRESS = 2;
-
-    private int mDragInitMode = ON_DOWN;
-
-    private boolean mSortEnabled = true;
-
-    /**
-     * Remove mode enum.
-     */
-    public static final int CLICK_REMOVE = 0;
-    public static final int FLING_RIGHT_REMOVE = 1;
-    public static final int FLING_LEFT_REMOVE = 2;
-    public static final int SLIDE_RIGHT_REMOVE = 3;
-    public static final int SLIDE_LEFT_REMOVE = 4;
-
-    /**
-     * The current remove mode.
-     */
-    private int mRemoveMode;
-
-    private boolean mRemoveEnabled = false;
-
-    private GestureDetector mDetector;
-
-    private GestureDetector mFlingRemoveDetector;
-
-    private int mTouchSlop;
-
-    public static final int MISS = -1;
-
-    private int mHitPos = MISS;
-
-    private int mClickRemoveHitPos = MISS;
-
-    private int[] mTempLoc = new int[2];
-
-    private int mItemX;
-    private int mItemY;
-
-    private int mCurrX;
-    private int mCurrY;
-
-    private boolean mDragging = false;
-
-    private float mFlingSpeed = 500f;
-
-    private float mOrigFloatAlpha = 1.0f;
-
-    private int mDragHandleId;
-
-    private int mClickRemoveId;
-
-    private DragSortListView mDslv;
-
-
-    /**
-     * Calls {@link #DragSortController(DragSortListView, int)} with a
-     * 0 drag handle id, FLING_RIGHT_REMOVE remove mode,
-     * and ON_DOWN drag init. By default, sorting is enabled, and
-     * removal is disabled.
-     *
-     * @param dslv The DSLV instance
-     */
-    public DragSortController(DragSortListView dslv) {
-        this(dslv, 0, ON_DOWN, FLING_RIGHT_REMOVE);
-    }
-
-    public DragSortController(DragSortListView dslv, int dragHandleId, int dragInitMode, int removeMode) {
-        this(dslv, dragHandleId, dragInitMode, removeMode, 0);
-    }
-
-    /**
-     * By default, sorting is enabled, and removal is disabled.
-     *
-     * @param dslv The DSLV instance
-     * @param dragHandleId The resource id of the View that represents
-     * the drag handle in a list item.
-     */
-    public DragSortController(DragSortListView dslv, int dragHandleId, int dragInitMode, int removeMode, int clickRemoveId) {
-        super(dslv);
-        mDslv = dslv;
-        mDetector = new GestureDetector(dslv.getContext(), this);
-        mFlingRemoveDetector = new GestureDetector(dslv.getContext(), mFlingRemoveListener);
-        mFlingRemoveDetector.setIsLongpressEnabled(false);
-        mTouchSlop = ViewConfiguration.get(dslv.getContext()).getScaledTouchSlop();
-        mDragHandleId = dragHandleId;
-        mClickRemoveId = clickRemoveId;
-        setRemoveMode(removeMode);
-        setDragInitMode(dragInitMode);
-        mOrigFloatAlpha = dslv.getFloatAlpha();
-    }
-
-
-    public int getDragInitMode() {
-        return mDragInitMode;
-    }
-
-    /**
-     * Set how a drag is initiated. Needs to be one of
-     * {@link ON_DOWN}, {@link ON_DRAG}, or {@link ON_LONG_PRESS}.
-     *
-     * @param mode The drag init mode.
-     */
-    public void setDragInitMode(int mode) {
-        mDragInitMode = mode;
-    }
-
-    /**
-     * ROMAN'S ADDITION. Returns whether or not a drag is currently occurring.
-     */
-    public boolean isDragging() {
-        return mDragging;
-    }
-
-    /**
-     * Enable/Disable list item sorting. Disabling is useful if only item
-     * removal is desired. Prevents drags in the vertical direction.
-     *
-     * @param enabled Set <code>true</code> to enable list
-     * item sorting.
-     */
-    public void setSortEnabled(boolean enabled) {
-        mSortEnabled = enabled;
-    }
-
-    public boolean isSortEnabled() {
-        return mSortEnabled;
-    }
-
-    /**
-     * One of {@link CLICK_REMOVE}, {@link FLING_RIGHT_REMOVE},
-     * {@link FLING_LEFT_REMOVE},
-     * {@link SLIDE_RIGHT_REMOVE}, or {@link SLIDE_LEFT_REMOVE}.
-     */
-    public void setRemoveMode(int mode) {
-        mRemoveMode = mode;
-    }
-
-    public int getRemoveMode() {
-        return mRemoveMode;
-    }
-
-    /**
-     * Enable/Disable item removal without affecting remove mode.
-     */
-    public void setRemoveEnabled(boolean enabled) {
-        mRemoveEnabled = enabled;
-    }
-
-    public boolean isRemoveEnabled() {
-        return mRemoveEnabled;
-    }
-
-    /**
-     * Set the resource id for the View that represents the drag
-     * handle in a list item.
-     *
-     * @param id An android resource id.
-     */
-    public void setDragHandleId(int id) {
-        mDragHandleId = id;
-    }
-
-    /**
-     * Set the resource id for the View that represents click
-     * removal button.
-     *
-     * @param id An android resource id.
-     */
-    public void setClickRemoveId(int id) {
-        mClickRemoveId = id;
-    }
-
-
-    /**
-     * Sets flags to restrict certain motions of the floating View
-     * based on DragSortController settings (such as remove mode).
-     * Starts the drag on the DragSortListView.
-     *
-     * @param position The list item position (includes headers).
-     * @param deltaX Touch x-coord minus left edge of floating View.
-     * @param deltaY Touch y-coord minus top edge of floating View.
-     *
-     * @return True if drag started, false otherwise.
-     */
-     public boolean startDrag(int position, int deltaX, int deltaY) {
-
-        int dragFlags = 0;
-        if (mSortEnabled) {
-            dragFlags |= DragSortListView.DRAG_POS_Y | DragSortListView.DRAG_NEG_Y;
-            //dragFlags |= DRAG_POS_Y; //for fun
-        }
-        if (mRemoveEnabled) {
-            if (mRemoveMode == FLING_RIGHT_REMOVE) {
-                dragFlags |= DragSortListView.DRAG_POS_X;
-            } else if (mRemoveMode == FLING_LEFT_REMOVE) {
-                dragFlags |= DragSortListView.DRAG_NEG_X;
-            }
-        }
-
-        mDragging = mDslv.startDrag(position - mDslv.getHeaderViewsCount(), dragFlags, deltaX, deltaY);
-        return mDragging;
-    }
-
-    @Override
-    public boolean onTouch(View v, MotionEvent ev) {
-        mDetector.onTouchEvent(ev);
-        if (mRemoveEnabled && mDragging && (mRemoveMode == FLING_RIGHT_REMOVE || mRemoveMode == FLING_LEFT_REMOVE)) {
-            mFlingRemoveDetector.onTouchEvent(ev);
-        }
-
-        int action = ev.getAction() & MotionEvent.ACTION_MASK;
-
-        switch (action) {
-        case MotionEvent.ACTION_DOWN:
-            mCurrX = (int) ev.getX();
-            mCurrY = (int) ev.getY();
-            break;
-        case MotionEvent.ACTION_UP:
-            if (mRemoveEnabled) {
-                final int x = (int) ev.getX();
-                int thirdW = mDslv.getWidth() / 3;
-                int twoThirdW = mDslv.getWidth() - thirdW;
-                if ((mRemoveMode == SLIDE_RIGHT_REMOVE && x > twoThirdW) ||
-                        (mRemoveMode == SLIDE_LEFT_REMOVE && x < thirdW)) {
-                    mDslv.stopDrag(true);
-                }
-            }
-        case MotionEvent.ACTION_CANCEL:
-            mDragging = false;
-            break;
-        }
-
-        return false;
-    }
-
-    /**
-     * Overrides to provide fading when slide removal is enabled.
-     */
-    @Override
-    public void onDragFloatView(View floatView, Point position, Point touch) {
-
-        if (mRemoveEnabled) {
-            int x = touch.x;
-
-            if (mRemoveMode == SLIDE_RIGHT_REMOVE) {
-                int width = mDslv.getWidth();
-                int thirdWidth = width / 3;
-
-                float alpha;
-                if (x < thirdWidth) {
-                    alpha = 1.0f;
-                } else if (x < width - thirdWidth) {
-                    alpha = ((float) (width - thirdWidth - x)) / ((float) thirdWidth);
-                } else {
-                    alpha = 0.0f;
-                }
-                mDslv.setFloatAlpha(mOrigFloatAlpha * alpha);
-            } else if (mRemoveMode == SLIDE_LEFT_REMOVE) {
-                int width = mDslv.getWidth();
-                int thirdWidth = width / 3;
-
-                float alpha;
-                if (x < thirdWidth) {
-                    alpha = 0.0f;
-                } else if (x < width - thirdWidth) {
-                    alpha = ((float) (x - thirdWidth)) / ((float) thirdWidth);
-                } else {
-                    alpha = 1.0f;
-                }
-                mDslv.setFloatAlpha(mOrigFloatAlpha * alpha);
-            }
-        }
-    }
-
-    /**
-     * Get the position to start dragging based on the ACTION_DOWN
-     * MotionEvent. This function simply calls
-     * {@link #dragHandleHitPosition(MotionEvent)}. Override
-     * to change drag handle behavior;
-     * this function is called internally when an ACTION_DOWN
-     * event is detected.
-     *
-     * @param ev The ACTION_DOWN MotionEvent.
-     *
-     * @return The list position to drag if a drag-init gesture is
-     * detected; MISS if unsuccessful.
-     */
-    public int startDragPosition(MotionEvent ev) {
-        return dragHandleHitPosition(ev);
-    }
-
-    /**
-     * Checks for the touch of an item's drag handle (specified by
-     * {@link #setDragHandleId(int)}), and returns that item's position
-     * if a drag handle touch was detected.
-     *
-     * @param ev The ACTION_DOWN MotionEvent.
-
-     * @return The list position of the item whose drag handle was
-     * touched; MISS if unsuccessful.
-     */
-    public int dragHandleHitPosition(MotionEvent ev) {
-        return viewIdHitPosition(ev, mDragHandleId);
-    }
-
-    public int viewIdHitPosition(MotionEvent ev, int id) {
-        final int x = (int) ev.getX();
-        final int y = (int) ev.getY();
-
-        int touchPos = mDslv.pointToPosition(x, y); //includes headers/footers
-
-        final int numHeaders = mDslv.getHeaderViewsCount();
-        final int numFooters = mDslv.getFooterViewsCount();
-        final int count = mDslv.getCount();
-
-        //Log.d("mobeta", "touch down on position " + itemnum);
-        // We're only interested if the touch was on an
-        // item that's not a header or footer.
-        if (touchPos != AdapterView.INVALID_POSITION && touchPos >= numHeaders && touchPos < (count - numFooters)) {
-            final View item = mDslv.getChildAt(touchPos - mDslv.getFirstVisiblePosition());
-            final int rawX = (int) ev.getRawX();
-            final int rawY = (int) ev.getRawY();
-
-            //View dragBox = (View) item.getTag();
-            View dragBox = (View) item.findViewById(id);
-            if (dragBox != null) {
-                dragBox.getLocationOnScreen(mTempLoc);
-
-                if (rawX > mTempLoc[0] && rawY > mTempLoc[1] &&
-                        rawX < mTempLoc[0] + dragBox.getWidth() &&
-                        rawY < mTempLoc[1] + dragBox.getHeight()) {
-
-                    mItemX = item.getLeft();
-                    mItemY = item.getTop();
-
-                    return touchPos;
-                }
-            }
-        }
-
-        return MISS;
-    }
-
-    @Override
-    public boolean onDown(MotionEvent ev) {
-        if (mRemoveEnabled && mRemoveMode == CLICK_REMOVE) {
-            mClickRemoveHitPos = viewIdHitPosition(ev, mClickRemoveId);
-        }
-
-        mHitPos = startDragPosition(ev);
-        if (mHitPos != MISS && mDragInitMode == ON_DOWN) {
-            startDrag(mHitPos, (int) ev.getX() - mItemX, (int) ev.getY() - mItemY);
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
-        //Log.d("mobeta", "lift listener scrolled dX="+distanceX+" dY="+distanceY);
-
-        if (mHitPos != MISS && mDragInitMode == ON_DRAG && !mDragging) {
-            final int x1 = (int) e1.getX();
-            final int y1 = (int) e1.getY();
-            final int x2 = (int) e2.getX();
-            final int y2 = (int) e2.getY();
-
-            boolean start = false;
-            if (mRemoveEnabled && mSortEnabled) {
-                start = true;
-            } else if (mRemoveEnabled) {
-                start = Math.abs(x2 - x1) > mTouchSlop;
-            } else if (mSortEnabled) {
-                start = Math.abs(y2 - y1) > mTouchSlop;
-            }
-
-            if (start) {
-                startDrag(mHitPos, x2 - mItemX, y2 - mItemY);
-            }
-        }
-        // return whatever
-        return false;
-    }
-
-    @Override
-    public void onLongPress(MotionEvent e) {
-        //Log.d("mobeta", "lift listener long pressed");
-        if (mHitPos != MISS && mDragInitMode == ON_LONG_PRESS) {
-            mDslv.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
-            startDrag(mHitPos, mCurrX - mItemX, mCurrY - mItemY);
-        }
-    }
-
-    // complete the OnGestureListener interface
-    @Override
-    public final boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
-        return false;
-    }
-
-    // complete the OnGestureListener interface
-    @Override
-    public boolean onSingleTapUp(MotionEvent ev) {
-        if (mRemoveEnabled && mRemoveMode == CLICK_REMOVE) {
-            if (mClickRemoveHitPos != MISS) {
-                mDslv.removeItem(mClickRemoveHitPos - mDslv.getHeaderViewsCount());
-            }
-        }
-        return true;
-    }
-
-    // complete the OnGestureListener interface
-    @Override
-    public void onShowPress(MotionEvent ev) {
-        // do nothing
-    }
-
-    private GestureDetector.OnGestureListener mFlingRemoveListener =
-            new GestureDetector.SimpleOnGestureListener() {
-                @Override
-                public final boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
-                    //Log.d("mobeta", "on fling remove called");
-                    if (mRemoveEnabled) {
-                        switch (mRemoveMode) {
-                        case FLING_RIGHT_REMOVE:
-                            if (velocityX > mFlingSpeed) {
-                                mDslv.stopDrag(true);
-                            }
-                            break;
-                        case FLING_LEFT_REMOVE:
-                            if (velocityX < -mFlingSpeed) {
-                                mDslv.stopDrag(true);
-                            }
-                            break;
-                        }
-                    }
-                    return false;
-                }
-            };
-
-}
-
diff --git a/src/org/omnirom/omnigears/ui/dslv/DragSortCursorAdapter.java b/src/org/omnirom/omnigears/ui/dslv/DragSortCursorAdapter.java
deleted file mode 100644
index 31b3f11..0000000
--- a/src/org/omnirom/omnigears/ui/dslv/DragSortCursorAdapter.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/**
- * A subclass of the Android ListView component that enables drag
- * and drop re-ordering of list items.
- *
- * Copyright 2012 Carl Bauer
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.ui.dslv;
-
-import java.util.ArrayList;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.util.SparseIntArray;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CursorAdapter;
-
-
-/**
- * A subclass of {@link android.widget.CursorAdapter} that provides
- * reordering of the elements in the Cursor based on completed
- * drag-sort operations. The reordering is a simple mapping of
- * list positions into Cursor positions (the Cursor is unchanged).
- * To persist changes made by drag-sorts, one can retrieve the
- * mapping with the {@link #getCursorPositions()} method, which
- * returns the reordered list of Cursor positions.
- *
- * An instance of this class is passed
- * to {@link DragSortListView#setAdapter(ListAdapter)} and, since
- * this class implements the {@link DragSortListView.DragSortListener}
- * interface, it is automatically set as the DragSortListener for
- * the DragSortListView instance.
- */
-public abstract class DragSortCursorAdapter extends CursorAdapter implements DragSortListView.DragSortListener {
-
-    public static final int REMOVED = -1;
-
-    /**
-     * Key is ListView position, value is Cursor position
-     */
-    private SparseIntArray mListMapping = new SparseIntArray();
-
-    private ArrayList<Integer> mRemovedCursorPositions = new ArrayList<Integer>();
-
-    @SuppressWarnings("deprecation")
-    public DragSortCursorAdapter(Context context, Cursor c) {
-        super(context, c);
-    }
-
-    public DragSortCursorAdapter(Context context, Cursor c, boolean autoRequery) {
-        super(context, c, autoRequery);
-    }
-
-    public DragSortCursorAdapter(Context context, Cursor c, int flags) {
-        super(context, c, flags);
-    }
-
-    /**
-     * Swaps Cursor and clears list-Cursor mapping.
-     *
-     * @see android.widget.CursorAdapter#swapCursor(android.database.Cursor)
-     */
-    @Override
-    public Cursor swapCursor(Cursor newCursor) {
-        Cursor old = super.swapCursor(newCursor);
-        resetMappings();
-        return old;
-    }
-
-    /**
-     * Changes Cursor and clears list-Cursor mapping.
-     *
-     * @see android.widget.CursorAdapter#changeCursor(android.database.Cursor)
-     */
-    @Override
-    public void changeCursor(Cursor cursor) {
-        super.changeCursor(cursor);
-        resetMappings();
-    }
-
-    /**
-     * Resets list-cursor mapping.
-     */
-    public void reset() {
-        resetMappings();
-        notifyDataSetChanged();
-    }
-
-    private void resetMappings() {
-        mListMapping.clear();
-        mRemovedCursorPositions.clear();
-    }
-
-    @Override
-    public Object getItem(int position) {
-        return super.getItem(mListMapping.get(position, position));
-    }
-
-    @Override
-    public long getItemId(int position) {
-        return super.getItemId(mListMapping.get(position, position));
-    }
-
-    @Override
-    public View getDropDownView(int position, View convertView, ViewGroup parent) {
-        return super.getDropDownView(mListMapping.get(position, position), convertView, parent);
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        return super.getView(mListMapping.get(position, position), convertView, parent);
-    }
-
-    /**
-     * On drop, this updates the mapping between Cursor positions
-     * and ListView positions. The Cursor is unchanged. Retrieve
-     * the current mapping with {@link getCursorPositions()}.
-     *
-     * @see DragSortListView.DropListener#drop(int, int)
-     */
-    @Override
-    public void drop(int from, int to) {
-        if (from != to) {
-            int cursorFrom = mListMapping.get(from, from);
-
-            if (from > to) {
-                for (int i = from; i > to; --i) {
-                    mListMapping.put(i, mListMapping.get(i - 1, i - 1));
-                }
-            } else {
-                for (int i = from; i < to; ++i) {
-                    mListMapping.put(i, mListMapping.get(i + 1, i + 1));
-                }
-            }
-            mListMapping.put(to, cursorFrom);
-
-            cleanMapping();
-            notifyDataSetChanged();
-        }
-    }
-
-    /**
-     * On remove, this updates the mapping between Cursor positions
-     * and ListView positions. The Cursor is unchanged. Retrieve
-     * the current mapping with {@link getCursorPositions()}.
-     *
-     * @see DragSortListView.RemoveListener#remove(int)
-     */
-    @Override
-    public void remove(int which) {
-        int cursorPos = mListMapping.get(which, which);
-        if (!mRemovedCursorPositions.contains(cursorPos)) {
-            mRemovedCursorPositions.add(cursorPos);
-        }
-
-        int newCount = getCount();
-        for (int i = which; i < newCount; ++i) {
-            mListMapping.put(i, mListMapping.get(i + 1, i + 1));
-        }
-
-        mListMapping.delete(newCount);
-
-        cleanMapping();
-        notifyDataSetChanged();
-    }
-
-    /**
-     * Does nothing. Just completes DragSortListener interface.
-     */
-    @Override
-    public void drag(int from, int to) {
-        // do nothing
-    }
-
-    /**
-     * Remove unnecessary mappings from sparse array.
-     */
-    private void cleanMapping() {
-        ArrayList<Integer> toRemove = new ArrayList<Integer>();
-
-        int size = mListMapping.size();
-        for (int i = 0; i < size; ++i) {
-            if (mListMapping.keyAt(i) == mListMapping.valueAt(i)) {
-                toRemove.add(mListMapping.keyAt(i));
-            }
-        }
-
-        size = toRemove.size();
-        for (int i = 0; i < size; ++i) {
-            mListMapping.delete(toRemove.get(i));
-        }
-    }
-
-    @Override
-    public int getCount() {
-        return super.getCount() - mRemovedCursorPositions.size();
-    }
-
-    /**
-     * Get the Cursor position mapped to by the provided list position
-     * (given all previously handled drag-sort
-     * operations).
-     *
-     * @param position List position
-     *
-     * @return The mapped-to Cursor position
-     */
-    public int getCursorPosition(int position) {
-        return mListMapping.get(position, position);
-    }
-
-    /**
-     * Get the current order of Cursor positions presented by the
-     * list.
-     */
-    public ArrayList<Integer> getCursorPositions() {
-        ArrayList<Integer> result = new ArrayList<Integer>();
-
-        for (int i = 0; i < getCount(); ++i) {
-            result.add(mListMapping.get(i, i));
-        }
-
-        return result;
-    }
-
-    /**
-     * Get the list position mapped to by the provided Cursor position.
-     * If the provided Cursor position has been removed by a drag-sort,
-     * this returns {@link #REMOVED}.
-     *
-     * @param cursorPosition A Cursor position
-     * @return The mapped-to list position or REMOVED
-     */
-    public int getListPosition(int cursorPosition) {
-        if (mRemovedCursorPositions.contains(cursorPosition)) {
-            return REMOVED;
-        }
-
-        int index = mListMapping.indexOfValue(cursorPosition);
-        if (index < 0) {
-            return cursorPosition;
-        } else {
-            return mListMapping.keyAt(index);
-        }
-    }
-
-
-}
diff --git a/src/org/omnirom/omnigears/ui/dslv/DragSortItemView.java b/src/org/omnirom/omnigears/ui/dslv/DragSortItemView.java
deleted file mode 100644
index d837eb5..0000000
--- a/src/org/omnirom/omnigears/ui/dslv/DragSortItemView.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * A subclass of the Android ListView component that enables drag
- * and drop re-ordering of list items.
- *
- * Copyright 2012 Carl Bauer
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.ui.dslv;
-
-import android.content.Context;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AbsListView;
-
-/**
- * Lightweight ViewGroup that wraps list items obtained from user's
- * ListAdapter. ItemView expects a single child that has a definite
- * height (i.e. the child's layout height is not MATCH_PARENT).
- * The width of
- * ItemView will always match the width of its child (that is,
- * the width MeasureSpec given to ItemView is passed directly
- * to the child, and the ItemView measured width is set to the
- * child's measured width). The height of ItemView can be anything;
- *
- * The purpose of this class is to optimize slide
- * shuffle animations.
- */
-public class DragSortItemView extends ViewGroup {
-
-    private int mGravity = Gravity.TOP;
-
-    public DragSortItemView(Context context) {
-        super(context);
-
-        // always init with standard ListView layout params
-        setLayoutParams(new AbsListView.LayoutParams(
-                LayoutParams.MATCH_PARENT,
-                LayoutParams.WRAP_CONTENT));
-
-        setClipChildren(true);
-    }
-
-    public void setGravity(int gravity) {
-        mGravity = gravity;
-    }
-
-    public int getGravity() {
-        return mGravity;
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        final View child = getChildAt(0);
-
-        if (child == null) {
-            return;
-        }
-
-        if (mGravity == Gravity.TOP) {
-            child.layout(0, 0, getMeasuredWidth(), child.getMeasuredHeight());
-        } else {
-            child.layout(0, getMeasuredHeight() - child.getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight());
-        }
-    }
-
-    /**
-     *
-     */
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int height = MeasureSpec.getSize(heightMeasureSpec);
-        int width = MeasureSpec.getSize(widthMeasureSpec);
-
-        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-
-        final View child = getChildAt(0);
-        if (child == null) {
-            setMeasuredDimension(0, width);
-            return;
-        }
-
-        if (child.isLayoutRequested()) {
-            // Always let child be as tall as it wants.
-            measureChild(child, widthMeasureSpec,
-                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
-        }
-
-        if (heightMode == MeasureSpec.UNSPECIFIED) {
-            LayoutParams lp = getLayoutParams();
-
-            if (lp.height > 0) {
-                height = lp.height;
-            } else {
-                height = child.getMeasuredHeight();
-            }
-        }
-
-        setMeasuredDimension(width, height);
-    }
-
-}
diff --git a/src/org/omnirom/omnigears/ui/dslv/DragSortListView.java b/src/org/omnirom/omnigears/ui/dslv/DragSortListView.java
deleted file mode 100644
index 9a83410..0000000
--- a/src/org/omnirom/omnigears/ui/dslv/DragSortListView.java
+++ /dev/null
@@ -1,2638 +0,0 @@
-/*
- * DragSortListView.
- *
- * A subclass of the Android ListView component that enables drag
- * and drop re-ordering of list items.
- *
- * Copyright 2012 Carl Bauer
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.ui.dslv;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-
-import org.omnirom.omnigears.R;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.database.DataSetObserver;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Point;
-import android.graphics.drawable.Drawable;
-import android.os.Environment;
-import android.os.SystemClock;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.SparseIntArray;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AbsListView;
-import android.widget.BaseAdapter;
-import android.widget.HeaderViewListAdapter;
-import android.widget.ListAdapter;
-import android.widget.ListView;
-
-
-/**
- * ListView subclass that mediates drag and drop resorting of items.
- *
- *
- * @author heycosmo
- *
- */
-public class DragSortListView extends ListView {
-    /**
-     * The View that floats above the ListView and represents
-     * the dragged item.
-     */
-    private View mFloatView;
-
-    /**
-     * The float View location. First based on touch location
-     * and given deltaX and deltaY. Then restricted by callback
-     * to FloatViewManager.onDragFloatView(). Finally restricted
-     * by bounds of DSLV.
-     */
-    private Point mFloatLoc = new Point();
-
-    private Point mTouchLoc = new Point();
-
-    /**
-     * The middle (in the y-direction) of the floating View.
-     */
-    private int mFloatViewMid;
-
-    /**
-     * Flag to make sure float View isn't measured twice
-     */
-    private boolean mFloatViewOnMeasured = false;
-
-    /**
-     * Watch the Adapter for data changes. Cancel a drag if
-     * coincident with a change.
-     */
-    private DataSetObserver mObserver;
-
-    /**
-     * Transparency for the floating View (XML attribute).
-     */
-    private float mFloatAlpha = 1.0f;
-    private float mCurrFloatAlpha = 1.0f;
-
-    /**
-     * While drag-sorting, the current position of the floating
-     * View. If dropped, the dragged item will land in this position.
-     */
-    private int mFloatPos;
-
-    /**
-     * The first expanded ListView position that helps represent
-     * the drop slot tracking the floating View.
-     */
-    private int mFirstExpPos;
-
-    /**
-     * The second expanded ListView position that helps represent
-     * the drop slot tracking the floating View. This can equal
-     * mFirstExpPos if there is no slide shuffle occurring; otherwise
-     * it is equal to mFirstExpPos + 1.
-     */
-    private int mSecondExpPos;
-
-    /**
-     * Flag set if slide shuffling is enabled.
-     */
-    private boolean mAnimate = false;
-
-    /**
-     * The user dragged from this position.
-     */
-    private int mSrcPos;
-
-    /**
-     * Offset (in x) within the dragged item at which the user
-     * picked it up (or first touched down with the digitalis).
-     */
-    private int mDragDeltaX;
-
-    /**
-     * Offset (in y) within the dragged item at which the user
-     * picked it up (or first touched down with the digitalis).
-     */
-    private int mDragDeltaY;
-
-    /**
-     * A listener that receives callbacks whenever the floating View
-     * hovers over a new position.
-     */
-    private DragListener mDragListener;
-
-    /**
-     * A listener that receives a callback when the floating View
-     * is dropped.
-     */
-    private DropListener mDropListener;
-
-    /**
-     * A listener that receives a callback when the floating View
-     * (or more precisely the originally dragged item) is removed
-     * by one of the provided gestures.
-     */
-    private RemoveListener mRemoveListener;
-
-    /**
-     * Enable/Disable item dragging
-     */
-    private boolean mDragEnabled = true;
-
-    /**
-     * Drag state enum.
-     */
-    private final static int IDLE = 0;
-    private final static int REMOVING = 1;
-    private final static int DROPPING = 2;
-    private final static int STOPPED = 3;
-    private final static int DRAGGING = 4;
-
-    private int mDragState = IDLE;
-
-    /**
-     * Height in pixels to which the originally dragged item
-     * is collapsed during a drag-sort. Currently, this value
-     * must be greater than zero.
-     */
-    private int mItemHeightCollapsed = 1;
-
-    /**
-     * Height of the floating View. Stored for the purpose of
-     * providing the tracking drop slot.
-     */
-    private int mFloatViewHeight;
-
-    /**
-     * Convenience member. See above.
-     */
-    private int mFloatViewHeightHalf;
-
-    /**
-     * Save the given width spec for use in measuring children
-     */
-    private int mWidthMeasureSpec = 0;
-
-    /**
-     * Sample Views ultimately used for calculating the height
-     * of ListView items that are off-screen.
-     */
-    private View[] mSampleViewTypes = new View[1];
-
-    /**
-     * Drag-scroll encapsulator!
-     */
-    private DragScroller mDragScroller;
-
-    /**
-     * Determines the start of the upward drag-scroll region
-     * at the top of the ListView. Specified by a fraction
-     * of the ListView height, thus screen resolution agnostic.
-     */
-    private float mDragUpScrollStartFrac = 1.0f / 3.0f;
-
-    /**
-     * Determines the start of the downward drag-scroll region
-     * at the bottom of the ListView. Specified by a fraction
-     * of the ListView height, thus screen resolution agnostic.
-     */
-    private float mDragDownScrollStartFrac = 1.0f / 3.0f;
-
-    /**
-     * The following are calculated from the above fracs.
-     */
-    private int mUpScrollStartY;
-    private int mDownScrollStartY;
-    private float mDownScrollStartYF;
-    private float mUpScrollStartYF;
-
-    /**
-     * Calculated from above above and current ListView height.
-     */
-    private float mDragUpScrollHeight;
-
-    /**
-     * Calculated from above above and current ListView height.
-     */
-    private float mDragDownScrollHeight;
-
-
-    /**
-     * Maximum drag-scroll speed in pixels per ms. Only used with
-     * default linear drag-scroll profile.
-     */
-    private float mMaxScrollSpeed = 0.5f;
-
-    /**
-     * Defines the scroll speed during a drag-scroll. User can
-     * provide their own; this default is a simple linear profile
-     * where scroll speed increases linearly as the floating View
-     * nears the top/bottom of the ListView.
-     */
-    private DragScrollProfile mScrollProfile = new DragScrollProfile() {
-        @Override
-        public float getSpeed(float w, long t) {
-            return mMaxScrollSpeed * w;
-        }
-    };
-
-    /**
-     * Current touch x.
-     */
-    private int mX;
-
-    /**
-     * Current touch y.
-     */
-    private int mY;
-
-    /**
-     * Last touch y.
-     */
-    private int mLastY;
-
-    /**
-     * Drag flag bit. Floating View can move in the positive
-     * x direction.
-     */
-    public final static int DRAG_POS_X = 0x1;
-
-    /**
-     * Drag flag bit. Floating View can move in the negative
-     * x direction.
-     */
-    public final static int DRAG_NEG_X = 0x2;
-
-    /**
-     * Drag flag bit. Floating View can move in the positive
-     * y direction. This is subtle. What this actually means is
-     * that, if enabled, the floating View can be dragged below its starting
-     * position. Remove in favor of upper-bounding item position?
-     */
-    public final static int DRAG_POS_Y = 0x4;
-
-    /**
-     * Drag flag bit. Floating View can move in the negative
-     * y direction. This is subtle. What this actually means is
-     * that the floating View can be dragged above its starting
-     * position. Remove in favor of lower-bounding item position?
-     */
-    public final static int DRAG_NEG_Y = 0x8;
-
-    /**
-     * Flags that determine limits on the motion of the
-     * floating View. See flags above.
-     */
-    private int mDragFlags = 0;
-
-    /**
-     * Last call to an on*TouchEvent was a call to
-     * onInterceptTouchEvent.
-     */
-    private boolean mLastCallWasIntercept = false;
-
-    /**
-     * A touch event is in progress.
-     */
-    private boolean mInTouchEvent = false;
-
-    /**
-     * Let the user customize the floating View.
-     */
-    private FloatViewManager mFloatViewManager = null;
-
-    /**
-     * Given to ListView to cancel its action when a drag-sort
-     * begins.
-     */
-    private MotionEvent mCancelEvent;
-
-    /**
-     * Enum telling where to cancel the ListView action when a
-     * drag-sort begins
-     */
-    private static final int NO_CANCEL = 0;
-    private static final int ON_TOUCH_EVENT = 1;
-    private static final int ON_INTERCEPT_TOUCH_EVENT = 2;
-
-    /**
-     * Where to cancel the ListView action when a
-     * drag-sort begins
-     */
-    private int mCancelMethod = NO_CANCEL;
-
-    /**
-     * Determines when a slide shuffle animation starts. That is,
-     * defines how close to the edge of the drop slot the floating
-     * View must be to initiate the slide.
-     */
-    private float mSlideRegionFrac = 0.25f;
-
-    /**
-     * Number between 0 and 1 indicating the relative location of
-     * a sliding item (only used if drag-sort animations
-     * are turned on). Nearly 1 means the item is
-     * at the top of the slide region (nearly full blank item
-     * is directly below).
-     */
-    private float mSlideFrac = 0.0f;
-
-    /**
-     * Wraps the user-provided ListAdapter. This is used to wrap each
-     * item View given by the user inside another View (currenly
-     * a RelativeLayout) which
-     * expands and collapses to simulate the item shuffling.
-     */
-    private AdapterWrapper mAdapterWrapper;
-
-    /**
-     * Turn on custom debugger.
-     */
-    private boolean mTrackDragSort = false;
-
-    /**
-     * Debugging class.
-     */
-    private DragSortTracker mDragSortTracker;
-
-    /**
-     * Needed for adjusting item heights from within layoutChildren
-     */
-    private boolean mBlockLayoutRequests = false;
-
-    /**
-     * Set to true when a down event happens during drag sort;
-     * for example, when drag finish animations are
-     * playing.
-     */
-    private boolean mIgnoreTouchEvent = false;
-
-    /**
-     * Caches DragSortItemView child heights. Sometimes DSLV has to
-     * know the height of an offscreen item. Since ListView virtualizes
-     * these, DSLV must get the item from the ListAdapter to obtain
-     * its height. That process can be expensive, but often the same
-     * offscreen item will be requested many times in a row. Once an
-     * offscreen item height is calculated, we cache it in this guy.
-     * Actually, we cache the height of the child of the
-     * DragSortItemView since the item height changes often during a
-     * drag-sort.
-     */
-    private static final int sCacheSize = 3;
-    private HeightCache mChildHeightCache = new HeightCache(sCacheSize);
-
-    private RemoveAnimator mRemoveAnimator;
-
-    private LiftAnimator mLiftAnimator;
-
-    private DropAnimator mDropAnimator;
-
-    public DragSortListView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        int defaultDuration = 150;
-        int removeAnimDuration = defaultDuration; //ms
-        int dropAnimDuration = defaultDuration; //ms
-
-        if (attrs != null) {
-            TypedArray a = getContext().obtainStyledAttributes(attrs,
-                    R.styleable.DragSortListView, 0, 0);
-
-            mItemHeightCollapsed = Math.max(1, a.getDimensionPixelSize(
-                    R.styleable.DragSortListView_collapsed_height, 1));
-
-            mTrackDragSort = a.getBoolean(
-                    R.styleable.DragSortListView_track_drag_sort, false);
-
-            if (mTrackDragSort) {
-                mDragSortTracker = new DragSortTracker();
-            }
-
-            // alpha between 0 and 255, 0=transparent, 255=opaque
-            mFloatAlpha = a.getFloat(R.styleable.DragSortListView_float_alpha, mFloatAlpha);
-            mCurrFloatAlpha = mFloatAlpha;
-
-            mDragEnabled = a.getBoolean(R.styleable.DragSortListView_drag_enabled, mDragEnabled);
-
-            mSlideRegionFrac = Math.max(0.0f,
-                    Math.min(1.0f, 1.0f - a.getFloat(
-                    R.styleable.DragSortListView_slide_shuffle_speed,
-                    0.75f)));
-
-            mAnimate = mSlideRegionFrac > 0.0f;
-
-            float frac = a.getFloat(
-                    R.styleable.DragSortListView_drag_scroll_start,
-                    mDragUpScrollStartFrac);
-
-            setDragScrollStart(frac);
-
-            mMaxScrollSpeed = a.getFloat(
-                    R.styleable.DragSortListView_max_drag_scroll_speed,
-                    mMaxScrollSpeed);
-
-            removeAnimDuration = a.getInt(
-                    R.styleable.DragSortListView_remove_animation_duration,
-                    removeAnimDuration);
-
-            dropAnimDuration = a.getInt(
-                    R.styleable.DragSortListView_drop_animation_duration,
-                    dropAnimDuration);
-
-            boolean useDefault = a.getBoolean(
-                    R.styleable.DragSortListView_use_default_controller,
-                    true);
-
-            if (useDefault) {
-                boolean removeEnabled = a.getBoolean(
-                        R.styleable.DragSortListView_remove_enabled,
-                        false);
-                int removeMode = a.getInt(
-                        R.styleable.DragSortListView_remove_mode,
-                        DragSortController.FLING_RIGHT_REMOVE);
-                boolean sortEnabled = a.getBoolean(
-                        R.styleable.DragSortListView_sort_enabled,
-                        true);
-                int dragInitMode = a.getInt(
-                        R.styleable.DragSortListView_drag_start_mode,
-                        DragSortController.ON_DOWN);
-                int dragHandleId = a.getResourceId(
-                        R.styleable.DragSortListView_drag_handle_id,
-                        0);
-                int clickRemoveId = a.getResourceId(
-                        R.styleable.DragSortListView_click_remove_id,
-                        0);
-                int bgColor = a.getColor(
-                        R.styleable.DragSortListView_float_background_color,
-                        Color.BLACK);
-
-                DragSortController controller = new DragSortController(
-                        this, dragHandleId, dragInitMode, removeMode,
-                        clickRemoveId);
-                controller.setRemoveEnabled(removeEnabled);
-                controller.setSortEnabled(sortEnabled);
-                controller.setBackgroundColor(bgColor);
-
-                mFloatViewManager = controller;
-                setOnTouchListener(controller);
-            }
-
-            a.recycle();
-        }
-
-        mDragScroller = new DragScroller();
-
-        float smoothness = 0.5f;
-        if (removeAnimDuration > 0) {
-            mRemoveAnimator = new RemoveAnimator(smoothness, removeAnimDuration);
-        }
-        //mLiftAnimator = new LiftAnimator(smoothness, 100);
-        if (dropAnimDuration > 0) {
-            mDropAnimator = new DropAnimator(smoothness, dropAnimDuration);
-        }
-
-        if(mCancelEvent!=null){
-            mCancelEvent.recycle();
-        }
-        mCancelEvent = MotionEvent.obtain(0,0,MotionEvent.ACTION_CANCEL,0f,0f,0f,0f,0,0f,0f,0,0);
-
-        // construct the dataset observer
-        mObserver = new DataSetObserver() {
-                    private void cancel() {
-                        if (mDragState == DRAGGING) {
-                            cancelDrag();
-                        }
-                    }
-
-                    @Override
-                    public void onChanged() {
-                        cancel();
-                    }
-
-                    @Override
-                    public void onInvalidated() {
-                        cancel();
-                    }
-                };
-    }
-
-    /**
-     * Usually called from a FloatViewManager. The float alpha
-     * will be reset to the xml-defined value every time a drag
-     * is stopped.
-     */
-    public void setFloatAlpha(float alpha) {
-        mCurrFloatAlpha = alpha;
-    }
-
-    public float getFloatAlpha() {
-        return mCurrFloatAlpha;
-    }
-
-    /**
-     * Set maximum drag scroll speed in positions/second. Only applies
-     * if using default ScrollSpeedProfile.
-     *
-     * @param max Maximum scroll speed.
-     */
-    public void setMaxScrollSpeed(float max) {
-        mMaxScrollSpeed = max;
-    }
-
-    /**
-     * For each DragSortListView Listener interface implemented by
-     * <code>adapter</code>, this method calls the appropriate
-     * set*Listener method with <code>adapter</code> as the argument.
-     *
-     * @param adapter The ListAdapter providing data to back
-     * DragSortListView.
-     *
-     * @see android.widget.ListView#setAdapter(android.widget.ListAdapter)
-     */
-    @Override
-    public void setAdapter(ListAdapter adapter) {
-        mAdapterWrapper = new AdapterWrapper(adapter);
-
-        if (adapter != null) {
-            adapter.registerDataSetObserver(mObserver);
-
-            if (adapter instanceof DropListener) {
-                setDropListener((DropListener) adapter);
-            }
-            if (adapter instanceof DragListener) {
-                setDragListener((DragListener) adapter);
-            }
-            if (adapter instanceof RemoveListener) {
-                setRemoveListener((RemoveListener) adapter);
-            }
-        }
-
-        super.setAdapter(mAdapterWrapper);
-    }
-
-    /**
-     * As opposed to {@link ListView#getAdapter()}, which returns
-     * a heavily wrapped ListAdapter (DragSortListView wraps the
-     * input ListAdapter {\emph and} ListView wraps the wrapped one).
-     *
-     * @return The ListAdapter set as the argument of {@link setAdapter()}
-     */
-    public ListAdapter getInputAdapter() {
-        if (mAdapterWrapper == null) {
-            return null;
-        } else {
-            return mAdapterWrapper.getAdapter();
-        }
-    }
-
-    private class AdapterWrapper extends HeaderViewListAdapter {
-        private ListAdapter mAdapter;
-
-        public AdapterWrapper(ListAdapter adapter) {
-            super(null, null, adapter);
-            mAdapter = adapter;
-        }
-
-        public ListAdapter getAdapter() {
-            return mAdapter;
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-
-            DragSortItemView v;
-            View child;
-            //Log.d("mobeta", "getView: position="+position+" convertView="+convertView);
-            if (convertView != null) {
-                v = (DragSortItemView) convertView;
-                View oldChild = v.getChildAt(0);
-
-                child = mAdapter.getView(position, oldChild, v);
-                if (child != oldChild) {
-                    // shouldn't get here if user is reusing convertViews properly
-                    v.removeViewAt(0);
-                    v.addView(child);
-                }
-            } else {
-                v = new DragSortItemView(getContext());
-                v.setLayoutParams(new AbsListView.LayoutParams(
-                        ViewGroup.LayoutParams.MATCH_PARENT,
-                        ViewGroup.LayoutParams.WRAP_CONTENT));
-                child = mAdapter.getView(position, null, v);
-                v.addView(child);
-            }
-
-            // Set the correct item height given drag state; passed
-            // View needs to be measured if measurement is required.
-            adjustItem(position + getHeaderViewsCount(), v, true);
-
-            return v;
-        }
-    }
-
-    private void drawDivider(int expPosition, Canvas canvas) {
-
-        final Drawable divider = getDivider();
-        final int dividerHeight = getDividerHeight();
-        //Log.d("mobeta", "div="+divider+" divH="+dividerHeight);
-
-        if (divider != null && dividerHeight != 0) {
-            final ViewGroup expItem = (ViewGroup) getChildAt(expPosition - getFirstVisiblePosition());
-            if (expItem != null) {
-                final int l = getPaddingLeft();
-                final int r = getWidth() - getPaddingRight();
-                final int t;
-                final int b;
-
-                final int childHeight = expItem.getChildAt(0).getHeight();
-
-                if (expPosition > mSrcPos) {
-                    t = expItem.getTop() + childHeight;
-                    b = t + dividerHeight;
-                } else {
-                    b = expItem.getBottom() - childHeight;
-                    t = b - dividerHeight;
-                }
-                //Log.d("mobeta", "l="+l+" t="+t+" r="+r+" b="+b);
-
-                // Have to clip to support ColorDrawable on <= Gingerbread
-                canvas.save();
-                canvas.clipRect(l, t, r, b);
-                divider.setBounds(l, t, r, b);
-                divider.draw(canvas);
-                canvas.restore();
-            }
-        }
-    }
-
-    @Override
-    protected void dispatchDraw(Canvas canvas) {
-        super.dispatchDraw(canvas);
-
-        if (mDragState != IDLE) {
-            // draw the divider over the expanded item
-            if (mFirstExpPos != mSrcPos) {
-                drawDivider(mFirstExpPos, canvas);
-            }
-            if (mSecondExpPos != mFirstExpPos && mSecondExpPos != mSrcPos) {
-                drawDivider(mSecondExpPos, canvas);
-            }
-        }
-
-        if (mFloatView != null) {
-            // draw the float view over everything
-            final int w = mFloatView.getWidth();
-            final int h = mFloatView.getHeight();
-            final int alpha = (int) (255f * mCurrFloatAlpha);
-
-            canvas.save();
-            //Log.d("mobeta", "clip rect bounds: " + canvas.getClipBounds());
-            canvas.translate(mFloatLoc.x, mFloatLoc.y);
-            canvas.clipRect(0, 0, w, h);
-
-            //Log.d("mobeta", "clip rect bounds: " + canvas.getClipBounds());
-            canvas.saveLayerAlpha(0, 0, w, h, alpha, Canvas.ALL_SAVE_FLAG);
-            mFloatView.draw(canvas);
-            canvas.restore();
-            canvas.restore();
-        }
-    }
-
-    private int getItemHeight(int position) {
-        View v = getChildAt(position - getFirstVisiblePosition());
-
-        if (v != null) {
-            // item is onscreen, just get the height of the View
-            return v.getHeight();
-        } else {
-            // item is offscreen. get child height and calculate
-            // item height based on current shuffle state
-            return calcItemHeight(position, getChildHeight(position));
-        }
-    }
-
-    private class HeightCache {
-
-        private SparseIntArray mMap;
-        private ArrayList<Integer> mOrder;
-        private int mMaxSize;
-
-        public HeightCache(int size) {
-            mMap = new SparseIntArray(size);
-            mOrder = new ArrayList<Integer>(size);
-            mMaxSize = size;
-        }
-
-        /**
-         * Add item height at position if doesn't already exist.
-         */
-        public void add(int position, int height) {
-            int currHeight = mMap.get(position, -1);
-            if (currHeight != height) {
-                if (currHeight == -1) {
-                    if (mMap.size() == mMaxSize) {
-                        // remove oldest entry
-                        mMap.delete(mOrder.remove(0));
-                    }
-                } else {
-                    // move position to newest slot
-                    mOrder.remove((Integer) position);
-                }
-                mMap.put(position, height);
-                mOrder.add(position);
-            }
-        }
-
-        public int get(int position) {
-            return mMap.get(position, -1);
-        }
-
-        public void clear() {
-            mMap.clear();
-            mOrder.clear();
-        }
-
-    }
-
-    /**
-     * Get the shuffle edge for item at position when top of
-     * item is at y-coord top. Assumes that current item heights
-     * are consistent with current float view location and
-     * thus expanded positions and slide fraction. i.e. Should not be
-     * called between update of expanded positions/slide fraction
-     * and layoutChildren.
-     *
-     * @param position
-     * @param top
-     * @param height Height of item at position. If -1, this function
-     * calculates this height.
-     *
-     * @return Shuffle line between position-1 and position (for
-     * the given view of the list; that is, for when top of item at
-     * position has y-coord of given `top`). If
-     * floating View (treated as horizontal line) is dropped
-     * immediately above this line, it lands in position-1. If
-     * dropped immediately below this line, it lands in position.
-     */
-    private int getShuffleEdge(int position, int top) {
-
-        final int numHeaders = getHeaderViewsCount();
-        final int numFooters = getFooterViewsCount();
-
-        // shuffle edges are defined between items that can be
-        // dragged; there are N-1 of them if there are N draggable
-        // items.
-
-        if (position <= numHeaders || (position >= getCount() - numFooters)) {
-            return top;
-        }
-
-        int divHeight = getDividerHeight();
-
-        int edge;
-
-        int maxBlankHeight = mFloatViewHeight - mItemHeightCollapsed;
-        int childHeight = getChildHeight(position);
-        int itemHeight = getItemHeight(position);
-
-        // first calculate top of item given that floating View is
-        // centered over src position
-        int otop = top;
-        if (mSecondExpPos <= mSrcPos) {
-            // items are expanded on and/or above the source position
-
-            if (position == mSecondExpPos && mFirstExpPos != mSecondExpPos) {
-                if (position == mSrcPos) {
-                    otop = top + itemHeight - mFloatViewHeight;
-                } else {
-                    int blankHeight = itemHeight - childHeight;
-                    otop = top + blankHeight - maxBlankHeight;
-                }
-            } else if (position > mSecondExpPos && position <= mSrcPos) {
-                otop = top - maxBlankHeight;
-            }
-
-        } else {
-            // items are expanded on and/or below the source position
-
-            if (position > mSrcPos && position <= mFirstExpPos) {
-                otop = top + maxBlankHeight;
-            } else if (position == mSecondExpPos && mFirstExpPos != mSecondExpPos) {
-                int blankHeight = itemHeight - childHeight;
-                otop = top + blankHeight;
-            }
-        }
-
-        // otop is set
-        if (position <= mSrcPos) {
-            edge = otop + (mFloatViewHeight - divHeight - getChildHeight(position - 1)) / 2;
-        } else {
-            edge = otop + (childHeight - divHeight - mFloatViewHeight) / 2;
-        }
-
-        return edge;
-    }
-
-    private boolean updatePositions() {
-
-        final int first = getFirstVisiblePosition();
-        int startPos = mFirstExpPos;
-        View startView = getChildAt(startPos - first);
-
-        if (startView == null) {
-            startPos = first + getChildCount() / 2;
-            startView = getChildAt(startPos - first);
-        }
-        int startTop = startView.getTop();
-
-        int itemHeight = startView.getHeight();
-
-        int edge = getShuffleEdge(startPos, startTop);
-        int lastEdge = edge;
-
-        int divHeight = getDividerHeight();
-
-        //Log.d("mobeta", "float mid="+mFloatViewMid);
-
-        int itemPos = startPos;
-        int itemTop = startTop;
-        if (mFloatViewMid < edge) {
-            // scanning up for float position
-            //Log.d("mobeta", "    edge="+edge);
-            while (itemPos >= 0) {
-                itemPos--;
-                itemHeight = getItemHeight(itemPos);
-
-                if (itemPos == 0) {
-                    edge = itemTop - divHeight - itemHeight;
-                    break;
-                }
-
-                itemTop -= itemHeight + divHeight;
-                edge = getShuffleEdge(itemPos, itemTop);
-                //Log.d("mobeta", "    edge="+edge);
-
-                if (mFloatViewMid >= edge) {
-                    break;
-                }
-
-                lastEdge = edge;
-            }
-        } else {
-            // scanning down for float position
-            //Log.d("mobeta", "    edge="+edge);
-            final int count = getCount();
-            while (itemPos < count) {
-                if (itemPos == count - 1) {
-                    edge = itemTop + divHeight + itemHeight;
-                    break;
-                }
-
-                itemTop += divHeight + itemHeight;
-                itemHeight = getItemHeight(itemPos + 1);
-                edge = getShuffleEdge(itemPos + 1, itemTop);
-                //Log.d("mobeta", "    edge="+edge);
-
-                // test for hit
-                if (mFloatViewMid < edge) {
-                    break;
-                }
-
-                lastEdge = edge;
-                itemPos++;
-            }
-        }
-
-        final int numHeaders = getHeaderViewsCount();
-        final int numFooters = getFooterViewsCount();
-
-        boolean updated = false;
-
-        int oldFirstExpPos = mFirstExpPos;
-        int oldSecondExpPos = mSecondExpPos;
-        float oldSlideFrac = mSlideFrac;
-
-        if (mAnimate) {
-            int edgeToEdge = Math.abs(edge - lastEdge);
-
-            int edgeTop, edgeBottom;
-            if (mFloatViewMid < edge) {
-                edgeBottom = edge;
-                edgeTop = lastEdge;
-            } else {
-                edgeTop = edge;
-                edgeBottom = lastEdge;
-            }
-            //Log.d("mobeta", "edgeTop="+edgeTop+" edgeBot="+edgeBottom);
-
-            int slideRgnHeight = (int) (0.5f * mSlideRegionFrac * edgeToEdge);
-            float slideRgnHeightF = (float) slideRgnHeight;
-            int slideEdgeTop = edgeTop + slideRgnHeight;
-            int slideEdgeBottom = edgeBottom - slideRgnHeight;
-
-            // Three regions
-            if (mFloatViewMid < slideEdgeTop) {
-                mFirstExpPos = itemPos - 1;
-                mSecondExpPos = itemPos;
-                mSlideFrac = 0.5f * ((float) (slideEdgeTop - mFloatViewMid)) / slideRgnHeightF;
-                //Log.d("mobeta", "firstExp="+mFirstExpPos+" secExp="+mSecondExpPos+" slideFrac="+mSlideFrac);
-            } else if (mFloatViewMid < slideEdgeBottom) {
-                mFirstExpPos = itemPos;
-                mSecondExpPos = itemPos;
-            } else {
-                mFirstExpPos = itemPos;
-                mSecondExpPos = itemPos + 1;
-                mSlideFrac = 0.5f * (1.0f + ((float) (edgeBottom - mFloatViewMid)) / slideRgnHeightF);
-                //Log.d("mobeta", "firstExp="+mFirstExpPos+" secExp="+mSecondExpPos+" slideFrac="+mSlideFrac);
-            }
-
-        } else {
-            mFirstExpPos = itemPos;
-            mSecondExpPos = itemPos;
-        }
-
-        // correct for headers and footers
-        if (mFirstExpPos < numHeaders) {
-            itemPos = numHeaders;
-            mFirstExpPos = itemPos;
-            mSecondExpPos = itemPos;
-        } else if (mSecondExpPos >= getCount() - numFooters) {
-            itemPos = getCount() - numFooters - 1;
-            mFirstExpPos = itemPos;
-            mSecondExpPos = itemPos;
-        }
-
-        if (mFirstExpPos != oldFirstExpPos || mSecondExpPos != oldSecondExpPos || mSlideFrac != oldSlideFrac) {
-            updated = true;
-        }
-
-        if (itemPos != mFloatPos) {
-            if (mDragListener != null) {
-                mDragListener.drag(mFloatPos - numHeaders, itemPos - numHeaders);
-            }
-
-            mFloatPos = itemPos;
-            updated = true;
-        }
-
-        return updated;
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-
-        if (mTrackDragSort) {
-            mDragSortTracker.appendState();
-        }
-    }
-
-    private class SmoothAnimator implements Runnable {
-        private long mStartTime;
-
-        private float mDurationF;
-
-        private float mAlpha;
-        private float mA, mB, mC, mD;
-
-        private boolean mCanceled;
-
-        public SmoothAnimator(float smoothness, int duration) {
-            mAlpha = smoothness;
-            mDurationF = (float) duration;
-            mA = mD = 1f / (2f * mAlpha * (1f - mAlpha));
-            mB = mAlpha / (2f * (mAlpha - 1f));
-            mC = 1f / (1f - mAlpha);
-        }
-
-        public float transform(float frac) {
-            if (frac < mAlpha) {
-                return mA * frac * frac;
-            } else if (frac < 1f - mAlpha) {
-                return mB + mC * frac;
-            } else {
-                return 1f - mD * (frac - 1f) * (frac - 1f);
-            }
-        }
-
-        public void start() {
-            mStartTime = SystemClock.uptimeMillis();
-            mCanceled = false;
-            onStart();
-            post(this);
-        }
-
-        public void cancel() {
-            mCanceled = true;
-        }
-
-        public void onStart() {
-            //stub
-        }
-
-        public void onUpdate(float frac, float smoothFrac) {
-            //stub
-        }
-
-        public void onStop() {
-            //stub
-        }
-
-        @Override
-        public void run() {
-            if (mCanceled) {
-                return;
-            }
-
-            float fraction = ((float) (SystemClock.uptimeMillis() - mStartTime)) / mDurationF;
-
-            if (fraction >= 1f) {
-                onUpdate(1f, 1f);
-                onStop();
-            } else {
-                onUpdate(fraction, transform(fraction));
-                post(this);
-            }
-        }
-    }
-
-    /**
-     * Centers floating View under touch point.
-     */
-    private class LiftAnimator extends SmoothAnimator {
-
-        private float mInitDragDeltaY;
-        private float mFinalDragDeltaY;
-
-        public LiftAnimator(float smoothness, int duration) {
-            super(smoothness, duration);
-        }
-
-        @Override
-        public void onStart() {
-            mInitDragDeltaY = mDragDeltaY;
-            mFinalDragDeltaY = mFloatViewHeightHalf;
-        }
-
-        @Override
-        public void onUpdate(float frac, float smoothFrac) {
-            if (mDragState != DRAGGING) {
-                cancel();
-            } else {
-                mDragDeltaY = (int) (smoothFrac * mFinalDragDeltaY + (1f - smoothFrac) * mInitDragDeltaY);
-                mFloatLoc.y = mY - mDragDeltaY;
-                doDragFloatView(true);
-            }
-        }
-    }
-
-    /**
-     * Centers floating View over drop slot before destroying.
-     */
-    private class DropAnimator extends SmoothAnimator {
-
-        private int mDropPos;
-        private int srcPos;
-        private float mInitDeltaY;
-        private float mInitDeltaX;
-
-        public DropAnimator(float smoothness, int duration) {
-            super(smoothness, duration);
-        }
-
-        @Override
-        public void onStart() {
-            mDropPos = mFloatPos;
-            srcPos = mSrcPos;
-            mDragState = DROPPING;
-            mInitDeltaY = mFloatLoc.y - getTargetY();
-            mInitDeltaX = mFloatLoc.x - getPaddingLeft();
-        }
-
-        private int getTargetY() {
-            final int first = getFirstVisiblePosition();
-            final int otherAdjust = (mItemHeightCollapsed + getDividerHeight()) / 2;
-            View v = getChildAt(mDropPos - first);
-            int targetY = -1;
-            if (v != null) {
-                if (mDropPos == srcPos) {
-                    targetY = v.getTop();
-                } else if (mDropPos < srcPos) {
-                    // expanded down
-                    targetY = v.getTop() - otherAdjust;
-                } else {
-                    // expanded up
-                    targetY = v.getBottom() + otherAdjust - mFloatViewHeight;
-                }
-            } else {
-                // drop position is not on screen?? no animation
-                cancel();
-            }
-
-            return targetY;
-        }
-
-        @Override
-        public void onUpdate(float frac, float smoothFrac) {
-            final int targetY = getTargetY();
-            final float deltaY = mFloatLoc.y - targetY;
-            final float f = 1f - smoothFrac;
-            if (f < Math.abs(deltaY / mInitDeltaY)) {
-                mFloatLoc.y = targetY + (int) (mInitDeltaY * f);
-                mFloatLoc.x = getPaddingLeft() + (int) (mInitDeltaX * f);
-                doDragFloatView(true);
-            }
-        }
-
-        @Override
-        public void onStop() {
-            dropFloatView();
-        }
-
-    }
-
-    /**
-     * Collapses expanded items.
-     */
-    private class RemoveAnimator extends SmoothAnimator {
-
-        private float mFirstStartBlank;
-        private float mSecondStartBlank;
-
-        private int mFirstChildHeight = -1;
-        private int mSecondChildHeight = -1;
-
-        private int mFirstPos;
-        private int mSecondPos;
-
-        public RemoveAnimator(float smoothness, int duration) {
-            super(smoothness, duration);
-        }
-
-        @Override
-        public void onStart() {
-            mFirstChildHeight = -1;
-            mSecondChildHeight = -1;
-            mFirstPos = mFirstExpPos;
-            mSecondPos = mSecondExpPos;
-            mDragState = REMOVING;
-            destroyFloatView();
-        }
-
-        @Override
-        public void onUpdate(float frac, float smoothFrac) {
-            float f = 1f - smoothFrac;
-
-            final int firstVis = getFirstVisiblePosition();
-            View item = getChildAt(mFirstPos - firstVis);
-            ViewGroup.LayoutParams lp;
-            int blank;
-            if (item != null) {
-                if (mFirstChildHeight == -1) {
-                    mFirstChildHeight = getChildHeight(mFirstPos, item, false);
-                    mFirstStartBlank = (float) (item.getHeight() - mFirstChildHeight);
-                }
-                blank = Math.max((int) (f * mFirstStartBlank), 1);
-                lp = item.getLayoutParams();
-                lp.height = mFirstChildHeight + blank;
-                item.setLayoutParams(lp);
-            }
-            if (mSecondPos != mFirstPos) {
-                item = getChildAt(mSecondPos - firstVis);
-                if (item != null) {
-                    if (mSecondChildHeight == -1) {
-                        mSecondChildHeight = getChildHeight(mSecondPos, item, false);
-                        mSecondStartBlank = (float) (item.getHeight() - mSecondChildHeight);
-                    }
-                    blank = Math.max((int) (f * mSecondStartBlank), 1);
-                    lp = item.getLayoutParams();
-                    lp.height = mSecondChildHeight + blank;
-                    item.setLayoutParams(lp);
-                }
-            }
-        }
-
-        @Override
-        public void onStop() {
-            doRemoveItem();
-        }
-    }
-
-    /**
-     * Removes an item from the list and animates the removal.
-     *
-     * @param which Position to remove (NOTE: headers/footers ignored!
-     * this is a position in your input ListAdapter).
-     */
-    public void removeItem(int which) {
-        if (mDragState == IDLE || mDragState == DRAGGING) {
-            if (mDragState == IDLE) {
-                // called from outside drag-sort
-                mSrcPos = getHeaderViewsCount() + which;
-                mFirstExpPos = mSrcPos;
-                mSecondExpPos = mSrcPos;
-                mFloatPos = mSrcPos;
-                View v = getChildAt(mSrcPos - getFirstVisiblePosition());
-                if (v != null) {
-                    v.setVisibility(View.INVISIBLE);
-                }
-            }
-
-            if (mInTouchEvent) {
-                switch (mCancelMethod) {
-                case ON_TOUCH_EVENT:
-                    super.onTouchEvent(mCancelEvent);
-                    break;
-                case ON_INTERCEPT_TOUCH_EVENT:
-                    super.onInterceptTouchEvent(mCancelEvent);
-                    break;
-                }
-            }
-
-            if (mRemoveAnimator != null) {
-                mRemoveAnimator.start();
-            } else {
-                doRemoveItem(which);
-            }
-        }
-    }
-
-
-    /**
-     * Move an item, bypassing the drag-sort process. Simply calls
-     * through to {@link DropListener#drop(int, int)}.
-     *
-     * @param from Position to move (NOTE: headers/footers ignored!
-     * this is a position in your input ListAdapter).
-     * @param to Target position (NOTE: headers/footers ignored!
-     * this is a position in your input ListAdapter).
-     */
-    public void moveItem(int from, int to) {
-        if (mDropListener != null) {
-            final int count = getInputAdapter().getCount();
-            if (from >= 0 && from < count && to >= 0 && to < count) {
-                mDropListener.drop(from, to);
-            }
-        }
-    }
-
-    /**
-     * Cancel a drag. Calls {@link #stopDrag(boolean, boolean)} with
-     * <code>true</code> as the first argument.
-     */
-    public void cancelDrag() {
-        if (mDragState == DRAGGING) {
-            mDragScroller.stopScrolling(true);
-            destroyFloatView();
-            clearPositions();
-            adjustAllItems();
-
-            if (mInTouchEvent) {
-                mDragState = STOPPED;
-            } else {
-                mDragState = IDLE;
-            }
-        }
-    }
-
-    private void clearPositions() {
-        mSrcPos = -1;
-        mFirstExpPos = -1;
-        mSecondExpPos = -1;
-        mFloatPos = -1;
-    }
-
-    private void dropFloatView() {
-        // must set to avoid cancelDrag being called from the
-        // DataSetObserver
-        mDragState = DROPPING;
-
-        if (mDropListener != null && mFloatPos >= 0 && mFloatPos < getCount()) {
-            final int numHeaders = getHeaderViewsCount();
-            mDropListener.drop(mSrcPos - numHeaders, mFloatPos - numHeaders);
-        }
-
-        destroyFloatView();
-
-        adjustOnReorder();
-        clearPositions();
-        adjustAllItems();
-
-        // now the drag is done
-        if (mInTouchEvent) {
-            mDragState = STOPPED;
-        } else {
-            mDragState = IDLE;
-        }
-    }
-
-    private void doRemoveItem() {
-        doRemoveItem(mSrcPos - getHeaderViewsCount());
-    }
-
-    /**
-     * Removes dragged item from the list. Calls RemoveListener.
-     */
-    private void doRemoveItem(int which) {
-        // must set to avoid cancelDrag being called from the
-        // DataSetObserver
-        mDragState = REMOVING;
-
-        // end it
-        if (mRemoveListener != null) {
-            mRemoveListener.remove(which);
-        }
-
-        destroyFloatView();
-
-        adjustOnReorder();
-        clearPositions();
-
-        // now the drag is done
-        if (mInTouchEvent) {
-            mDragState = STOPPED;
-        } else {
-            mDragState = IDLE;
-        }
-    }
-
-    private void adjustOnReorder() {
-        final int firstPos = getFirstVisiblePosition();
-        //Log.d("mobeta", "first="+firstPos+" src="+mSrcPos);
-        if (mSrcPos < firstPos) {
-            // collapsed src item is off screen;
-            // adjust the scroll after item heights have been fixed
-            View v = getChildAt(0);
-            int top = 0;
-            if (v != null) {
-                top = v.getTop();
-            }
-            //Log.d("mobeta", "top="+top+" fvh="+mFloatViewHeight);
-            setSelectionFromTop(firstPos - 1, top - getPaddingTop());
-        }
-    }
-
-    /**
-     * Stop a drag in progress. Pass <code>true</code> if you would
-     * like to remove the dragged item from the list.
-     *
-     * @param remove Remove the dragged item from the list. Calls
-     * a registered RemoveListener, if one exists. Otherwise, calls
-     * the DropListener, if one exists.
-     *
-     * @return True if the stop was successful. False if there is
-     * no floating View.
-     */
-    public boolean stopDrag(boolean remove) {
-        if (mFloatView != null) {
-            mDragScroller.stopScrolling(true);
-
-            if (remove) {
-                removeItem(mSrcPos - getHeaderViewsCount());
-            } else {
-                if (mDropAnimator != null) {
-                    mDropAnimator.start();
-                } else {
-                    dropFloatView();
-                }
-            }
-
-            if (mTrackDragSort) {
-                mDragSortTracker.stopTracking();
-            }
-
-            return true;
-        } else {
-            // stop failed
-            return false;
-        }
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        if (mIgnoreTouchEvent) {
-            mIgnoreTouchEvent = false;
-            return false;
-        }
-
-        if (!mDragEnabled) {
-            return super.onTouchEvent(ev);
-        }
-
-        boolean more = false;
-
-        boolean lastCallWasIntercept = mLastCallWasIntercept;
-        mLastCallWasIntercept = false;
-
-        if (!lastCallWasIntercept) {
-            saveTouchCoords(ev);
-        }
-
-        //if (mFloatView != null) {
-        if (mDragState == DRAGGING) {
-            onDragTouchEvent(ev);
-            more = true; //give us more!
-        } else {
-            // what if float view is null b/c we dropped in middle
-            // of drag touch event?
-
-            //if (mDragState != STOPPED) {
-            if (mDragState == IDLE) {
-                if (super.onTouchEvent(ev)) {
-                    more = true;
-                }
-            }
-
-            int action = ev.getAction() & MotionEvent.ACTION_MASK;
-
-            switch (action) {
-            case MotionEvent.ACTION_CANCEL:
-            case MotionEvent.ACTION_UP:
-                doActionUpOrCancel();
-                break;
-            default:
-                if (more) {
-                    mCancelMethod = ON_TOUCH_EVENT;
-                }
-            }
-        }
-
-        return more;
-    }
-
-    private void doActionUpOrCancel() {
-        mCancelMethod = NO_CANCEL;
-        mInTouchEvent = false;
-        if (mDragState == STOPPED) {
-            mDragState = IDLE;
-        }
-        mCurrFloatAlpha = mFloatAlpha;
-        mChildHeightCache.clear();
-    }
-
-    private void saveTouchCoords(MotionEvent ev) {
-        int action = ev.getAction() & MotionEvent.ACTION_MASK;
-        if (action != MotionEvent.ACTION_DOWN) {
-            mLastY = mY;
-        }
-        mX = (int) ev.getX();
-        mY = (int) ev.getY();
-        if (action == MotionEvent.ACTION_DOWN) {
-            mLastY = mY;
-        }
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        if (!mDragEnabled) {
-            return super.onInterceptTouchEvent(ev);
-        }
-
-        saveTouchCoords(ev);
-        mLastCallWasIntercept = true;
-
-        int action = ev.getAction() & MotionEvent.ACTION_MASK;
-
-        if (action == MotionEvent.ACTION_DOWN) {
-            if (mDragState != IDLE) {
-                // intercept and ignore
-                mIgnoreTouchEvent = true;
-                return true;
-            }
-            mInTouchEvent = true;
-        }
-
-        boolean intercept = false;
-
-        // the following deals with calls to super.onInterceptTouchEvent
-        if (mFloatView != null) {
-            // super's touch event canceled in startDrag
-            intercept = true;
-        } else {
-            if (super.onInterceptTouchEvent(ev)) {
-                intercept = true;
-            }
-
-            switch (action) {
-            case MotionEvent.ACTION_CANCEL:
-            case MotionEvent.ACTION_UP:
-                doActionUpOrCancel();
-                break;
-            default:
-                if (intercept) {
-                    mCancelMethod = ON_TOUCH_EVENT;
-                } else {
-                    mCancelMethod = ON_INTERCEPT_TOUCH_EVENT;
-                }
-            }
-        }
-
-        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
-            mInTouchEvent = false;
-        }
-
-        return intercept;
-    }
-
-    /**
-     * Set the width of each drag scroll region by specifying
-     * a fraction of the ListView height.
-     *
-     * @param heightFraction Fraction of ListView height. Capped at
-     * 0.5f.
-     *
-     */
-    public void setDragScrollStart(float heightFraction) {
-        setDragScrollStarts(heightFraction, heightFraction);
-    }
-
-    /**
-     * Set the width of each drag scroll region by specifying
-     * a fraction of the ListView height.
-     *
-     * @param upperFrac Fraction of ListView height for up-scroll bound.
-     * Capped at 0.5f.
-     * @param lowerFrac Fraction of ListView height for down-scroll bound.
-     * Capped at 0.5f.
-     *
-     */
-    public void setDragScrollStarts(float upperFrac, float lowerFrac) {
-        if (lowerFrac > 0.5f) {
-            mDragDownScrollStartFrac = 0.5f;
-        } else {
-            mDragDownScrollStartFrac = lowerFrac;
-        }
-
-        if (upperFrac > 0.5f) {
-            mDragUpScrollStartFrac = 0.5f;
-        } else {
-            mDragUpScrollStartFrac = upperFrac;
-        }
-
-        if (getHeight() != 0) {
-            updateScrollStarts();
-        }
-    }
-
-    private void continueDrag(int x, int y) {
-
-        // proposed position
-        mFloatLoc.x = x - mDragDeltaX;
-        mFloatLoc.y = y - mDragDeltaY;
-
-        doDragFloatView(true);
-
-        int minY = Math.min(y, mFloatViewMid + mFloatViewHeightHalf);
-        int maxY = Math.max(y, mFloatViewMid - mFloatViewHeightHalf);
-
-        // get the current scroll direction
-        int currentScrollDir = mDragScroller.getScrollDir();
-
-        if (minY > mLastY && minY > mDownScrollStartY && currentScrollDir != DragScroller.DOWN) {
-            // dragged down, it is below the down scroll start and it is not scrolling up
-
-            if (currentScrollDir != DragScroller.STOP) {
-                // moved directly from up scroll to down scroll
-                mDragScroller.stopScrolling(true);
-            }
-
-            // start scrolling down
-            mDragScroller.startScrolling(DragScroller.DOWN);
-        } else if (maxY < mLastY && maxY < mUpScrollStartY && currentScrollDir != DragScroller.UP) {
-            // dragged up, it is above the up scroll start and it is not scrolling up
-
-            if (currentScrollDir != DragScroller.STOP) {
-                // moved directly from down scroll to up scroll
-                mDragScroller.stopScrolling(true);
-            }
-
-            // start scrolling up
-            mDragScroller.startScrolling(DragScroller.UP);
-        }
-        else if (maxY >= mUpScrollStartY && minY <= mDownScrollStartY && mDragScroller.isScrolling()) {
-            // not in the upper nor in the lower drag-scroll regions but it is still scrolling
-
-            mDragScroller.stopScrolling(true);
-        }
-    }
-
-    private void updateScrollStarts() {
-        final int padTop = getPaddingTop();
-        final int listHeight = getHeight() - padTop - getPaddingBottom();
-        float heightF = (float) listHeight;
-
-        mUpScrollStartYF = padTop + mDragUpScrollStartFrac * heightF;
-        mDownScrollStartYF = padTop + (1.0f - mDragDownScrollStartFrac) * heightF;
-
-        mUpScrollStartY = (int) mUpScrollStartYF;
-        mDownScrollStartY = (int) mDownScrollStartYF;
-
-        mDragUpScrollHeight = mUpScrollStartYF - padTop;
-        mDragDownScrollHeight = padTop + listHeight - mDownScrollStartYF;
-    }
-
-    @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        super.onSizeChanged(w, h, oldw, oldh);
-        updateScrollStarts();
-    }
-
-    private void adjustAllItems() {
-        final int first = getFirstVisiblePosition();
-        final int last = getLastVisiblePosition();
-
-        int begin = Math.max(0, getHeaderViewsCount() - first);
-        int end = Math.min(last - first, getCount() - 1 - getFooterViewsCount() - first);
-
-        for (int i = begin; i <= end; ++i) {
-            View v = getChildAt(i);
-            if (v != null) {
-                adjustItem(first + i, v, false);
-            }
-        }
-    }
-
-    /**
-     * Sets layout param height, gravity, and visibility  on
-     * wrapped item.
-     */
-    private void adjustItem(int position, View v, boolean invalidChildHeight) {
-
-        // Adjust item height
-
-        int height = calcItemHeight(position, v, invalidChildHeight);
-        ViewGroup.LayoutParams lp = v.getLayoutParams();
-
-        if (height != lp.height) {
-            lp.height = height;
-            v.setLayoutParams(lp);
-        }
-
-        // Adjust item gravity
-
-        if (position == mFirstExpPos || position == mSecondExpPos) {
-            if (position < mSrcPos) {
-                ((DragSortItemView) v).setGravity(Gravity.BOTTOM);
-            } else if (position > mSrcPos) {
-                ((DragSortItemView) v).setGravity(Gravity.TOP);
-            }
-        }
-
-        // Finally adjust item visibility
-
-        int oldVis = v.getVisibility();
-        int vis = View.VISIBLE;
-
-        if (position == mSrcPos && mFloatView != null) {
-            vis = View.INVISIBLE;
-        }
-
-        if (vis != oldVis) {
-            v.setVisibility(vis);
-        }
-    }
-
-    private int getChildHeight(int position) {
-        if (position == mSrcPos) {
-            return 0;
-        }
-
-        View v = getChildAt(position - getFirstVisiblePosition());
-
-        if (v != null) {
-            // item is onscreen, therefore child height is valid,
-            // hence the "true"
-            return getChildHeight(position, v, false);
-        } else {
-            // item is offscreen
-            // first check cache for child height at this position
-            int childHeight = mChildHeightCache.get(position);
-            if (childHeight != -1) {
-                //Log.d("mobeta", "found child height in cache!");
-                return childHeight;
-            }
-
-            final ListAdapter adapter = getAdapter();
-            int type = adapter.getItemViewType(position);
-
-            // There might be a better place for checking for the following
-            final int typeCount = adapter.getViewTypeCount();
-            if (typeCount != mSampleViewTypes.length) {
-                mSampleViewTypes = new View[typeCount];
-            }
-
-            if (type >= 0) {
-                if (mSampleViewTypes[type] == null) {
-                    v = adapter.getView(position, null, this);
-                    mSampleViewTypes[type] = v;
-                } else {
-                    v = adapter.getView(position, mSampleViewTypes[type], this);
-                }
-            } else {
-                // type is HEADER_OR_FOOTER or IGNORE
-                v = adapter.getView(position, null, this);
-            }
-
-            // current child height is invalid, hence "true" below
-            childHeight = getChildHeight(position, v, true);
-
-            // cache it because this could have been expensive
-            mChildHeightCache.add(position, childHeight);
-
-            return childHeight;
-        }
-    }
-
-    private int getChildHeight(int position, View item, boolean invalidChildHeight) {
-        if (position == mSrcPos) {
-            return 0;
-        }
-
-        View child;
-        if (position < getHeaderViewsCount() || position >= getCount() - getFooterViewsCount()) {
-            child = item;
-        } else {
-            child = ((ViewGroup) item).getChildAt(0);
-        }
-
-        ViewGroup.LayoutParams lp = child.getLayoutParams();
-
-        if (lp != null) {
-            if (lp.height > 0) {
-                return lp.height;
-            }
-        }
-
-        int childHeight = child.getHeight();
-
-        if (childHeight == 0 || invalidChildHeight) {
-            measureItem(child);
-            childHeight = child.getMeasuredHeight();
-        }
-
-        return childHeight;
-    }
-
-    private int calcItemHeight(int position, View item, boolean invalidChildHeight) {
-        return calcItemHeight(position, getChildHeight(position, item, invalidChildHeight));
-    }
-
-    private int calcItemHeight(int position, int childHeight) {
-
-        boolean isSliding = mAnimate && mFirstExpPos != mSecondExpPos;
-        int maxNonSrcBlankHeight = mFloatViewHeight - mItemHeightCollapsed;
-        int slideHeight = (int) (mSlideFrac * maxNonSrcBlankHeight);
-
-        int height;
-
-        if (position == mSrcPos) {
-            if (mSrcPos == mFirstExpPos) {
-                if (isSliding) {
-                    height = slideHeight + mItemHeightCollapsed;
-                } else {
-                    height = mFloatViewHeight;
-                }
-            } else if (mSrcPos == mSecondExpPos) {
-                // if gets here, we know an item is sliding
-                height = mFloatViewHeight - slideHeight;
-            } else {
-                height = mItemHeightCollapsed;
-            }
-        } else if (position == mFirstExpPos) {
-            if (isSliding) {
-                height = childHeight + slideHeight;
-            } else {
-                height = childHeight + maxNonSrcBlankHeight;
-            }
-        } else if (position == mSecondExpPos) {
-            // we know an item is sliding (b/c 2ndPos != 1stPos)
-            height = childHeight + maxNonSrcBlankHeight - slideHeight;
-        } else {
-            height = childHeight;
-        }
-
-        return height;
-    }
-
-    @Override
-    public void requestLayout() {
-        if (!mBlockLayoutRequests) {
-            super.requestLayout();
-        }
-    }
-
-    private int adjustScroll(int movePos, View moveItem, int oldFirstExpPos, int oldSecondExpPos) {
-        int adjust = 0;
-
-        final int childHeight = getChildHeight(movePos);
-
-        int moveHeightBefore = moveItem.getHeight();
-        int moveHeightAfter = calcItemHeight(movePos, childHeight);
-
-        int moveBlankBefore = moveHeightBefore;
-        int moveBlankAfter = moveHeightAfter;
-        if (movePos != mSrcPos) {
-            moveBlankBefore -= childHeight;
-            moveBlankAfter -= childHeight;
-        }
-
-        int maxBlank = mFloatViewHeight;
-        if (mSrcPos != mFirstExpPos && mSrcPos != mSecondExpPos) {
-            maxBlank -= mItemHeightCollapsed;
-        }
-
-        if (movePos <= oldFirstExpPos) {
-            if (movePos > mFirstExpPos) {
-                adjust += maxBlank - moveBlankAfter;
-            }
-        } else if (movePos == oldSecondExpPos) {
-            if (movePos <= mFirstExpPos) {
-                adjust += moveBlankBefore - maxBlank;
-            } else if (movePos == mSecondExpPos) {
-                adjust += moveHeightBefore - moveHeightAfter;
-            } else {
-                adjust += moveBlankBefore;
-            }
-        } else {
-            if (movePos <= mFirstExpPos) {
-                adjust -= maxBlank;
-            } else if (movePos == mSecondExpPos) {
-                adjust -= moveBlankAfter;
-            }
-        }
-
-        return adjust;
-    }
-
-    private void measureItem(View item) {
-        ViewGroup.LayoutParams lp = item.getLayoutParams();
-        if (lp == null) {
-            lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-        }
-        int wspec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, getListPaddingLeft() + getListPaddingRight(), lp.width);
-        int hspec;
-        if (lp.height > 0) {
-            hspec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
-        } else {
-            hspec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        }
-        item.measure(wspec, hspec);
-    }
-
-    private void measureFloatView() {
-        if (mFloatView != null) {
-            measureItem(mFloatView);
-            mFloatViewHeight = mFloatView.getMeasuredHeight();
-            mFloatViewHeightHalf = mFloatViewHeight / 2;
-        }
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        //Log.d("mobeta", "onMeasure called");
-        if (mFloatView != null) {
-            if (mFloatView.isLayoutRequested()) {
-                measureFloatView();
-            }
-            mFloatViewOnMeasured = true; //set to false after layout
-        }
-        mWidthMeasureSpec = widthMeasureSpec;
-    }
-
-    @Override
-    protected void layoutChildren() {
-        super.layoutChildren();
-
-        if (mFloatView != null) {
-            if (mFloatView.isLayoutRequested() && !mFloatViewOnMeasured) {
-                // Have to measure here when usual android measure
-                // pass is skipped. This happens during a drag-sort
-                // when layoutChildren is called directly.
-                measureFloatView();
-            }
-            mFloatView.layout(0, 0, mFloatView.getMeasuredWidth(), mFloatView.getMeasuredHeight());
-            mFloatViewOnMeasured = false;
-        }
-    }
-
-
-    protected boolean onDragTouchEvent(MotionEvent ev) {
-        // we are in a drag
-        switch (ev.getAction() & MotionEvent.ACTION_MASK) {
-        case MotionEvent.ACTION_CANCEL:
-            if (mDragState == DRAGGING) {
-                cancelDrag();
-            }
-            doActionUpOrCancel();
-            break;
-        case MotionEvent.ACTION_UP:
-            //Log.d("mobeta", "calling stopDrag from onDragTouchEvent");
-            if (mDragState == DRAGGING) {
-                stopDrag(false);
-            }
-            doActionUpOrCancel();
-            break;
-        case MotionEvent.ACTION_MOVE:
-            continueDrag((int) ev.getX(), (int) ev.getY());
-            break;
-        }
-
-        return true;
-    }
-
-    /**
-     * Start a drag of item at <code>position</code> using the
-     * registered FloatViewManager. Calls through
-     * to {@link #startDrag(int,View,int,int,int)} after obtaining
-     * the floating View from the FloatViewManager.
-     *
-     * @param position Item to drag.
-     * @param dragFlags Flags that restrict some movements of the
-     * floating View. For example, set <code>dragFlags |=
-     * ~{@link #DRAG_NEG_X}</code> to allow dragging the floating
-     * View in all directions except off the screen to the left.
-     * @param deltaX Offset in x of the touch coordinate from the
-     * left edge of the floating View (i.e. touch-x minus float View
-     * left).
-     * @param deltaY Offset in y of the touch coordinate from the
-     * top edge of the floating View (i.e. touch-y minus float View
-     * top).
-     *
-     * @return True if the drag was started, false otherwise. This
-     * <code>startDrag</code> will fail if we are not currently in
-     * a touch event, there is no registered FloatViewManager,
-     * or the FloatViewManager returns a null View.
-     */
-    public boolean startDrag(int position, int dragFlags, int deltaX, int deltaY) {
-        if (!mInTouchEvent || mFloatViewManager == null) {
-            return false;
-        }
-
-        View v = mFloatViewManager.onCreateFloatView(position);
-
-        if (v == null) {
-            return false;
-        } else {
-            return startDrag(position, v, dragFlags, deltaX, deltaY);
-        }
-
-    }
-
-    /**
-     * Start a drag of item at <code>position</code> without using
-     * a FloatViewManager.
-     *
-     * @param position Item to drag.
-     * @param floatView Floating View.
-     * @param dragFlags Flags that restrict some movements of the
-     * floating View. For example, set <code>dragFlags |= 
-     * ~{@link #DRAG_NEG_X}</code> to allow dragging the floating
-     * View in all directions except off the screen to the left.
-     * @param deltaX Offset in x of the touch coordinate from the
-     * left edge of the floating View (i.e. touch-x minus float View
-     * left).
-     * @param deltaY Offset in y of the touch coordinate from the
-     * top edge of the floating View (i.e. touch-y minus float View
-     * top).
-     *
-     * @return True if the drag was started, false otherwise. This
-     * <code>startDrag</code> will fail if we are not currently in
-     * a touch event, <code>floatView</code> is null, or there is
-     * a drag in progress.
-     */
-    public boolean startDrag(int position, View floatView, int dragFlags, int deltaX, int deltaY) {
-        if (mDragState != IDLE || !mInTouchEvent || mFloatView != null || floatView == null) {
-            return false;
-        }
-
-        if (getParent() != null) {
-            getParent().requestDisallowInterceptTouchEvent(true);
-        }
-
-        int pos = position + getHeaderViewsCount();
-        mFirstExpPos = pos;
-        mSecondExpPos = pos;
-        mSrcPos = pos;
-        mFloatPos = pos;
-
-        //mDragState = dragType;
-        mDragState = DRAGGING;
-        mDragFlags = 0;
-        mDragFlags |= dragFlags;
-
-        mFloatView = floatView;
-        measureFloatView(); //sets mFloatViewHeight
-
-        mDragDeltaX = deltaX;
-        mDragDeltaY = deltaY;
-
-        //updateFloatView(mX - mDragDeltaX, mY - mDragDeltaY);
-        mFloatLoc.x = mX - mDragDeltaX;
-        mFloatLoc.y = mY - mDragDeltaY;
-
-        // set src item invisible
-        final View srcItem = getChildAt(mSrcPos - getFirstVisiblePosition());
-
-        if (srcItem != null) {
-            srcItem.setVisibility(View.INVISIBLE);
-        }
-
-        if (mTrackDragSort) {
-            mDragSortTracker.startTracking();
-        }
-
-        // once float view is created, events are no longer passed
-        // to ListView
-        switch (mCancelMethod) {
-        case ON_TOUCH_EVENT:
-            super.onTouchEvent(mCancelEvent);
-            break;
-        case ON_INTERCEPT_TOUCH_EVENT:
-            super.onInterceptTouchEvent(mCancelEvent);
-            break;
-        }
-
-        requestLayout();
-
-        if (mLiftAnimator != null) {
-            mLiftAnimator.start();
-        }
-
-        return true;
-    }
-
-    private void doDragFloatView(boolean forceInvalidate) {
-        int movePos = getFirstVisiblePosition() + getChildCount() / 2;
-        View moveItem = getChildAt(getChildCount() / 2);
-
-        if (moveItem == null) {
-            return;
-        }
-
-        doDragFloatView(movePos, moveItem, forceInvalidate);
-    }
-
-    private void doDragFloatView(int movePos, View moveItem, boolean forceInvalidate) {
-        mBlockLayoutRequests = true;
-
-        updateFloatView();
-
-        int oldFirstExpPos = mFirstExpPos;
-        int oldSecondExpPos = mSecondExpPos;
-
-        boolean updated = updatePositions();
-
-        if (updated) {
-            adjustAllItems();
-            int scroll = adjustScroll(movePos, moveItem, oldFirstExpPos, oldSecondExpPos);
-            //Log.d("mobeta", "  adjust scroll="+scroll);
-
-            setSelectionFromTop(movePos, moveItem.getTop() + scroll - getPaddingTop());
-            layoutChildren();
-        }
-
-        if (updated || forceInvalidate) {
-            invalidate();
-        }
-
-        mBlockLayoutRequests = false;
-    }
-
-    /**
-     * Sets float View location based on suggested values and
-     * constraints set in mDragFlags.
-     */
-    private void updateFloatView() {
-
-        if (mFloatViewManager != null) {
-            mTouchLoc.set(mX, mY);
-            mFloatViewManager.onDragFloatView(mFloatView, mFloatLoc, mTouchLoc);
-        }
-
-        final int floatX = mFloatLoc.x;
-        final int floatY = mFloatLoc.y;
-
-        // restrict x motion
-        int padLeft = getPaddingLeft();
-        if ((mDragFlags & DRAG_POS_X) == 0 && floatX > padLeft) {
-            mFloatLoc.x = padLeft;
-        } else if ((mDragFlags & DRAG_NEG_X) == 0 && floatX < padLeft) {
-            mFloatLoc.x = padLeft;
-        }
-
-        // keep floating view from going past bottom of last header view
-        final int numHeaders = getHeaderViewsCount();
-        final int numFooters = getFooterViewsCount();
-        final int firstPos = getFirstVisiblePosition();
-        final int lastPos = getLastVisiblePosition();
-
-        //Log.d("mobeta", "nHead="+numHeaders+" nFoot="+numFooters+" first="+firstPos+" last="+lastPos);
-        int topLimit = getPaddingTop();
-        if (firstPos < numHeaders) {
-            topLimit = getChildAt(numHeaders - firstPos - 1).getBottom();
-        }
-        if ((mDragFlags & DRAG_NEG_Y) == 0) {
-            if (firstPos <= mSrcPos) {
-                topLimit = Math.max(getChildAt(mSrcPos - firstPos).getTop(), topLimit);
-            }
-        }
-        // bottom limit is top of first footer View or
-        // bottom of last item in list
-        int bottomLimit = getHeight() - getPaddingBottom();
-        if (lastPos >= getCount() - numFooters - 1) {
-            bottomLimit = getChildAt(getCount() - numFooters - 1 - firstPos).getBottom();
-        }
-        if ((mDragFlags & DRAG_POS_Y) == 0) {
-            if (lastPos >= mSrcPos) {
-                bottomLimit = Math.min(getChildAt(mSrcPos - firstPos).getBottom(), bottomLimit);
-            }
-        }
-
-        //Log.d("mobeta", "dragView top=" + (y - mDragDeltaY));
-        //Log.d("mobeta", "limit=" + limit);
-        //Log.d("mobeta", "mDragDeltaY=" + mDragDeltaY);
-
-        if (floatY < topLimit) {
-            mFloatLoc.y = topLimit;
-        } else if (floatY + mFloatViewHeight > bottomLimit) {
-            mFloatLoc.y = bottomLimit - mFloatViewHeight;
-        }
-
-        // get y-midpoint of floating view (constrained to ListView bounds)
-        mFloatViewMid = mFloatLoc.y + mFloatViewHeightHalf;
-    }
-
-    private void destroyFloatView() {
-        if (mFloatView != null) {
-            mFloatView.setVisibility(GONE);
-            if (mFloatViewManager != null) {
-                mFloatViewManager.onDestroyFloatView(mFloatView);
-            }
-            mFloatView = null;
-            invalidate();
-        }
-    }
-
-    /**
-     * Interface for customization of the floating View appearance
-     * and dragging behavior. Implement
-     * your own and pass it to {@link #setFloatViewManager}. If
-     * your own is not passed, the default {@link SimpleFloatViewManager}
-     * implementation is used.
-     */
-    public interface FloatViewManager {
-        /**
-         * Return the floating View for item at <code>position</code>.
-         * DragSortListView will measure and layout this View for you,
-         * so feel free to just inflate it. You can help DSLV by
-         * setting some {@link ViewGroup.LayoutParams} on this View;
-         * otherwise it will set some for you (with a width of FILL_PARENT
-         * and a height of WRAP_CONTENT).
-         *
-         * @param position Position of item to drag (NOTE:
-         * <code>position</code> excludes header Views; thus, if you
-         * want to call {@link ListView#getChildAt(int)}, you will need
-         * to add {@link ListView#getHeaderViewsCount()} to the index).
-         *
-         * @return The View you wish to display as the floating View.
-         */
-        public View onCreateFloatView(int position);
-
-        /**
-         * Called whenever the floating View is dragged. Float View
-         * properties can be changed here. Also, the upcoming location
-         * of the float View can be altered by setting
-         * <code>location.x</code> and <code>location.y</code>.
-         *
-         * @param floatView The floating View.
-         * @param location The location (top-left; relative to DSLV
-         * top-left) at which the float
-         * View would like to appear, given the current touch location
-         * and the offset provided in {@link DragSortListView#startDrag}.
-         * @param touch The current touch location (relative to DSLV
-         * top-left).
-         * @param pendingScroll
-         */
-        public void onDragFloatView(View floatView, Point location, Point touch);
-
-        /**
-         * Called when the float View is dropped; lets you perform
-         * any necessary cleanup. The internal DSLV floating View
-         * reference is set to null immediately after this is called.
-         *
-         * @param floatView The floating View passed to
-         * {@link #onCreateFloatView(int)}.
-         */
-        public void onDestroyFloatView(View floatView);
-    }
-
-    public void setFloatViewManager(FloatViewManager manager) {
-        mFloatViewManager = manager;
-    }
-
-    public void setDragListener(DragListener l) {
-        mDragListener = l;
-    }
-
-    /**
-     * Allows for easy toggling between a DragSortListView
-     * and a regular old ListView. If enabled, items are
-     * draggable, where the drag init mode determines how
-     * items are lifted (see {@link setDragInitMode(int)}).
-     * If disabled, items cannot be dragged.
-     *
-     * @param enabled Set <code>true</code> to enable list
-     * item dragging
-     */
-    public void setDragEnabled(boolean enabled) {
-        mDragEnabled = enabled;
-    }
-
-    public boolean isDragEnabled() {
-        return mDragEnabled;
-    }
-
-    /**
-     * This better reorder your ListAdapter! DragSortListView does not do this
-     * for you; doesn't make sense to. Make sure
-     * {@link BaseAdapter#notifyDataSetChanged()} or something like it is
-     * called in your implementation.
-     *
-     * @param l
-     */
-    public void setDropListener(DropListener l) {
-        mDropListener = l;
-    }
-
-    /**
-     * Probably a no-brainer, but make sure that your remove listener
-     * calls {@link BaseAdapter#notifyDataSetChanged()} or something like it.
-     * When an item removal occurs, DragSortListView
-     * relies on a redraw of all the items to recover invisible views
-     * and such. Strictly speaking, if you remove something, your dataset
-     * has changed...
-     *
-     * @param l
-     */
-    public void setRemoveListener(RemoveListener l) {
-        mRemoveListener = l;
-    }
-
-    public interface DragListener {
-        public void drag(int from, int to);
-    }
-
-    /**
-     * Your implementation of this has to reorder your ListAdapter!
-     * Make sure to call
-     * {@link BaseAdapter#notifyDataSetChanged()} or something like it
-     * in your implementation.
-     *
-     * @author heycosmo
-     *
-     */
-    public interface DropListener {
-        public void drop(int from, int to);
-    }
-
-    /**
-     * Make sure to call
-     * {@link BaseAdapter#notifyDataSetChanged()} or something like it
-     * in your implementation.
-     *
-     * @author heycosmo
-     *
-     */
-    public interface RemoveListener {
-        public void remove(int which);
-    }
-
-    public interface DragSortListener extends DropListener, DragListener, RemoveListener {}
-
-    public void setDragSortListener(DragSortListener l) {
-        setDropListener(l);
-        setDragListener(l);
-        setRemoveListener(l);
-    }
-
-    /**
-     * Completely custom scroll speed profile. Default increases linearly
-     * with position and is constant in time. Create your own by implementing
-     * {@link DragSortListView.DragScrollProfile}.
-     *
-     * @param ssp
-     */
-    public void setDragScrollProfile(DragScrollProfile ssp) {
-        if (ssp != null) {
-            mScrollProfile = ssp;
-        }
-    }
-
-    /**
-     * Interface for controlling
-     * scroll speed as a function of touch position and time. Use
-     * {@link DragSortListView#setDragScrollProfile(DragScrollProfile)} to
-     * set custom profile.
-     *
-     * @author heycosmo
-     *
-     */
-    public interface DragScrollProfile {
-        /**
-         * Return a scroll speed in pixels/millisecond. Always return a
-         * positive number.
-         *
-         * @param w Normalized position in scroll region (i.e. w \in [0,1]).
-         * Small w typically means slow scrolling.
-         * @param t Time (in milliseconds) since start of scroll (handy if you
-         * want scroll acceleration).
-         * @return Scroll speed at position w and time t in pixels/ms.
-         */
-        float getSpeed(float w, long t);
-    }
-
-    private class DragScroller implements Runnable {
-
-        private boolean mAbort;
-
-        private long mPrevTime;
-        private long mCurrTime;
-
-        private int dy;
-        private float dt;
-        private long tStart;
-        private int scrollDir;
-
-        public final static int STOP = -1;
-        public final static int UP = 0;
-        public final static int DOWN = 1;
-
-        private float mScrollSpeed; // pixels per ms
-
-        private boolean mScrolling = false;
-
-        public boolean isScrolling() {
-            return mScrolling;
-        }
-
-        public int getScrollDir() {
-            return mScrolling ? scrollDir : STOP;
-        }
-
-        public DragScroller() {}
-
-        public void startScrolling(int dir) {
-            if (!mScrolling) {
-                //Debug.startMethodTracing("dslv-scroll");
-                mAbort = false;
-                mScrolling = true;
-                tStart = SystemClock.uptimeMillis();
-                mPrevTime = tStart;
-                scrollDir = dir;
-                post(this);
-            }
-        }
-
-        public void stopScrolling(boolean now) {
-            if (now) {
-                DragSortListView.this.removeCallbacks(this);
-                mScrolling = false;
-            } else {
-                mAbort = true;
-            }
-
-            //Debug.stopMethodTracing();
-        }
-
-        @Override
-        public void run() {
-            if (mAbort) {
-                mScrolling = false;
-                return;
-            }
-
-            //Log.d("mobeta", "scroll");
-
-            final int first = getFirstVisiblePosition();
-            final int last = getLastVisiblePosition();
-            final int count = getCount();
-            final int padTop = getPaddingTop();
-            final int listHeight = getHeight() - padTop - getPaddingBottom();
-
-            int minY = Math.min(mY, mFloatViewMid + mFloatViewHeightHalf);
-            int maxY = Math.max(mY, mFloatViewMid - mFloatViewHeightHalf);
-
-            if (scrollDir == UP) {
-                View v = getChildAt(0);
-                //Log.d("mobeta", "vtop="+v.getTop()+" padtop="+padTop);
-                if (v == null) {
-                    mScrolling = false;
-                    return;
-                } else {
-                    if (first == 0 && v.getTop() == padTop) {
-                        mScrolling = false;
-                        return;
-                    }
-                }
-                mScrollSpeed = mScrollProfile.getSpeed((mUpScrollStartYF - maxY) / mDragUpScrollHeight, mPrevTime);
-            } else {
-                View v = getChildAt(last - first);
-                if (v == null) {
-                    mScrolling = false;
-                    return;
-                } else {
-                    if (last == count - 1 && v.getBottom() <= listHeight + padTop) {
-                        mScrolling = false;
-                        return;
-                    }
-                }
-                mScrollSpeed = -mScrollProfile.getSpeed((minY - mDownScrollStartYF) / mDragDownScrollHeight, mPrevTime);
-            }
-
-            mCurrTime = SystemClock.uptimeMillis();
-            dt = (float) (mCurrTime - mPrevTime);
-
-            // dy is change in View position of a list item; i.e. positive dy
-            // means user is scrolling up (list item moves down the screen, remember
-            // y=0 is at top of View).
-            dy = (int) Math.round(mScrollSpeed * dt);
-
-            int movePos;
-            if (dy >= 0) {
-                dy = Math.min(listHeight, dy);
-                movePos = first;
-            } else {
-                dy = Math.max(-listHeight, dy);
-                movePos = last;
-            }
-
-            final View moveItem = getChildAt(movePos - first);
-            int top = moveItem.getTop() + dy;
-
-            if (movePos == 0 && top > padTop) {
-                top = padTop;
-            }
-
-            // always do scroll
-            mBlockLayoutRequests = true;
-
-            setSelectionFromTop(movePos, top - padTop);
-            DragSortListView.this.layoutChildren();
-            invalidate();
-
-            mBlockLayoutRequests = false;
-
-            // scroll means relative float View movement
-            doDragFloatView(movePos, moveItem, false);
-
-            mPrevTime = mCurrTime;
-            //Log.d("mobeta", "  updated prevTime="+mPrevTime);
-
-            post(this);
-        }
-    }
-
-    private class DragSortTracker {
-        StringBuilder mBuilder = new StringBuilder();
-
-        File mFile;
-
-        private int mNumInBuffer = 0;
-        private int mNumFlushes = 0;
-
-        private boolean mTracking = false;
-
-        public DragSortTracker() {
-            File root = Environment.getExternalStorageDirectory();
-            mFile = new File(root, "dslv_state.txt");
-
-            if (!mFile.exists()) {
-                try {
-                    mFile.createNewFile();
-                    Log.d("mobeta", "file created");
-                } catch (IOException e) {
-                    Log.w("mobeta", "Could not create dslv_state.txt");
-                    Log.d("mobeta", e.getMessage());
-                }
-            }
-
-        }
-
-        public void startTracking() {
-            mBuilder.append("<DSLVStates>\n");
-            mNumFlushes = 0;
-            mTracking = true;
-        }
-
-        public void appendState() {
-            if (!mTracking) {
-                return;
-            }
-
-            mBuilder.append("<DSLVState>\n");
-            final int children = getChildCount();
-            final int first = getFirstVisiblePosition();
-            mBuilder.append("    <Positions>");
-            for (int i = 0; i < children; ++i) {
-                mBuilder.append(first + i).append(",");
-            }
-            mBuilder.append("</Positions>\n");
-
-            mBuilder.append("    <Tops>");
-            for (int i = 0; i < children; ++i) {
-                mBuilder.append(getChildAt(i).getTop()).append(",");
-            }
-            mBuilder.append("</Tops>\n");
-            mBuilder.append("    <Bottoms>");
-            for (int i = 0; i < children; ++i) {
-                mBuilder.append(getChildAt(i).getBottom()).append(",");
-            }
-            mBuilder.append("</Bottoms>\n");
-
-            mBuilder.append("    <FirstExpPos>").append(mFirstExpPos).append("</FirstExpPos>\n");
-            mBuilder.append("    <FirstExpBlankHeight>")
-                            .append(getItemHeight(mFirstExpPos) - getChildHeight(mFirstExpPos))
-                            .append("</FirstExpBlankHeight>\n");
-            mBuilder.append("    <SecondExpPos>").append(mSecondExpPos).append("</SecondExpPos>\n");
-            mBuilder.append("    <SecondExpBlankHeight>")
-                            .append(getItemHeight(mSecondExpPos) - getChildHeight(mSecondExpPos))
-                            .append("</SecondExpBlankHeight>\n");
-            mBuilder.append("    <SrcPos>").append(mSrcPos).append("</SrcPos>\n");
-            mBuilder.append("    <SrcHeight>").append(mFloatViewHeight + getDividerHeight()).append("</SrcHeight>\n");
-            mBuilder.append("    <ViewHeight>").append(getHeight()).append("</ViewHeight>\n");
-            mBuilder.append("    <LastY>").append(mLastY).append("</LastY>\n");
-            mBuilder.append("    <FloatY>").append(mFloatViewMid).append("</FloatY>\n");
-            mBuilder.append("    <ShuffleEdges>");
-            for (int i = 0; i < children; ++i) {
-                mBuilder.append(getShuffleEdge(first + i, getChildAt(i).getTop())).append(",");
-            }
-            mBuilder.append("</ShuffleEdges>\n");
-
-            mBuilder.append("</DSLVState>\n");
-            mNumInBuffer++;
-
-            if (mNumInBuffer > 1000) {
-                flush();
-                mNumInBuffer = 0;
-            }
-        }
-
-        public void flush() {
-            if (!mTracking) {
-                return;
-            }
-
-            // save to file on sdcard
-            try {
-                boolean append = true;
-                if (mNumFlushes == 0) {
-                    append = false;
-                }
-                FileWriter writer = new FileWriter(mFile, append);
-
-                writer.write(mBuilder.toString());
-                mBuilder.delete(0, mBuilder.length());
-
-                writer.flush();
-                writer.close();
-
-                mNumFlushes++;
-            } catch (IOException e) {
-                // do nothing
-            }
-        }
-
-        public void stopTracking() {
-            if (mTracking) {
-                mBuilder.append("</DSLVStates>\n");
-                flush();
-                mTracking = false;
-            }
-        }
-    }
-}
diff --git a/src/org/omnirom/omnigears/ui/dslv/SimpleFloatViewManager.java b/src/org/omnirom/omnigears/ui/dslv/SimpleFloatViewManager.java
deleted file mode 100644
index 8e523e6..0000000
--- a/src/org/omnirom/omnigears/ui/dslv/SimpleFloatViewManager.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * A subclass of the Android ListView component that enables drag
- * and drop re-ordering of list items.
- *
- * Copyright 2012 Carl Bauer
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.omnirom.omnigears.ui.dslv;
-
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.graphics.Point;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.ListView;
-
-/**
- * Simple implementation of the FloatViewManager class. Uses list
- * items as they appear in the ListView to create the floating View.
- */
-public class SimpleFloatViewManager implements DragSortListView.FloatViewManager {
-
-    private Bitmap mFloatBitmap;
-
-    private ImageView mImageView;
-
-    private int mFloatBGColor = Color.BLACK;
-
-    protected ListView mListView;
-
-    public SimpleFloatViewManager(ListView lv) {
-        mListView = lv;
-    }
-
-    public void setBackgroundColor(int color) {
-        mFloatBGColor = color;
-    }
-
-    /**
-     * This simple implementation creates a Bitmap copy of the
-     * list item currently shown at ListView <code>position</code>.
-     */
-    @Override
-    public View onCreateFloatView(int position) {
-        // Guaranteed that this will not be null? I think so. Nope, got
-        // a NullPointerException once...
-        View v = mListView.getChildAt(position + mListView.getHeaderViewsCount() - mListView.getFirstVisiblePosition());
-
-        if (v == null) {
-            return null;
-        }
-
-        v.setPressed(false);
-
-        // Create a copy of the drawing cache so that it does not get
-        // recycled by the framework when the list tries to clean up memory
-        //v.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
-        v.setDrawingCacheEnabled(true);
-        mFloatBitmap = Bitmap.createBitmap(v.getDrawingCache());
-        v.setDrawingCacheEnabled(false);
-
-        if (mImageView == null) {
-            mImageView = new ImageView(mListView.getContext());
-        }
-        mImageView.setBackgroundColor(mFloatBGColor);
-        mImageView.setPadding(0, 0, 0, 0);
-        mImageView.setImageBitmap(mFloatBitmap);
-
-        return mImageView;
-    }
-
-    /**
-     * This does nothing
-     */
-    @Override
-    public void onDragFloatView(View floatView, Point position, Point touch) {
-        // do nothing
-    }
-
-    /**
-     * Removes the Bitmap from the ImageView created in
-     * onCreateFloatView() and tells the system to recycle it.
-     */
-    @Override
-    public void onDestroyFloatView(View floatView) {
-        ((ImageView) floatView).setImageDrawable(null);
-
-        mFloatBitmap.recycle();
-        mFloatBitmap = null;
-    }
-
-}
-
diff --git a/src/org/omnirom/omnigears/utils/FontManager.java b/src/org/omnirom/omnigears/utils/FontManager.java
deleted file mode 100644
index 846f238..0000000
--- a/src/org/omnirom/omnigears/utils/FontManager.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2011 George Yunaev @ Ulduzsoft
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- */
-
-package org.omnirom.omnigears.utils;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.util.HashMap;
-import android.util.Log;
-
-public class FontManager
-{
-    // This function enumerates all fonts on Android system and returns the HashMap with the font
-    // absolute file name as key, and the font literal name (embedded into the font) as value.
-    static public HashMap< String, String > enumerateFonts()
-    {
-        String[] fontdirs = { "/system/fonts", "/system/font", "/data/fonts" };
-        HashMap< String, String > fonts = new HashMap< String, String >();
-        TTFAnalyzer analyzer = new TTFAnalyzer();
-
-        for ( String fontdir : fontdirs )
-        {
-            File dir = new File( fontdir );
-
-            if ( !dir.exists() )
-                continue;
-
-            File[] files = dir.listFiles();
-
-            if ( files == null )
-                continue;
-
-            for ( File file : files )
-            {
-                String filename = file.getName();
-                String fontname = analyzer.getTtfFontName( file.getAbsolutePath() );
-                if ( fontname != null ) {
-                    fonts.put( fontname, file.getAbsolutePath() );
-                } else {
-                    if (filename.equals("DroidSans.ttf")) {
-                        fonts.put( "Droid Sans", file.getAbsolutePath() );
-                    }
-                    if (filename.equals("DroidSans-Bold.ttf")) {
-                        fonts.put( "Droid Sans Bold", file.getAbsolutePath() );
-                    }
-                    if (filename.equals("Roboto-Black.ttf")) {
-                        fonts.put( "Roboto Bold", file.getAbsolutePath() );
-                    }
-                    if (filename.equals("Roboto-Black.ttf")) {
-                        fonts.put( "Roboto Bold Italic", file.getAbsolutePath() );
-                    }
-                    if (filename.equals("Roboto-Italic.ttf")) {
-                        fonts.put( "Roboto Italic", file.getAbsolutePath() );
-                    }
-                    if (filename.equals("Roboto-BoldItalic.ttf")) {
-                        fonts.put( "Roboto Bold Italic", file.getAbsolutePath() );
-                    }
-                    if (filename.equals("Roboto-Light.ttf")) {
-                        fonts.put( "Roboto Light", file.getAbsolutePath() );
-                    }
-                    if (filename.equals("Roboto-LightItalic.ttf")) {
-                        fonts.put( "Roboto Light Italic", file.getAbsolutePath() );
-                    }
-                    if (filename.equals("Roboto-Thin.ttf")) {
-                        fonts.put( "Roboto Thin", file.getAbsolutePath() );
-                    }
-                    if (filename.equals("Roboto-ThinItalic.ttf")) {
-                        fonts.put( "Roboto Thin Italic", file.getAbsolutePath() );
-                    }
-                }
-            }
-        }
-
-        return fonts.isEmpty() ? null : fonts;
-    }
-}
-
-// The class which loads the TTF file, parses it and returns the TTF font name
-class TTFAnalyzer
-{
-    // This function parses the TTF file and returns the font name specified in the file
-    public String getTtfFontName( String fontFilename )
-    {
-        try
-        {
-            // Parses the TTF file format.
-            // See http://developer.apple.com/fonts/ttrefman/rm06/Chap6.html
-            m_file = new RandomAccessFile( fontFilename, "r" );
-
-            // Read the version first
-            int version = readDword();
-
-            // The version must be either 'true' (0x74727565) or 0x00010000
-            if ( version != 0x74727565 && version != 0x00010000 )
-                return null;
-
-            // The TTF file consist of several sections called "tables", and we need to know how many of them are there.
-            int numTables = readWord();
-
-            // Skip the rest in the header
-            readWord(); // skip searchRange
-            readWord(); // skip entrySelector
-            readWord(); // skip rangeShift
-
-            // Now we can read the tables
-            for ( int i = 0; i < numTables; i++ )
-            {
-                // Read the table entry
-                int tag = readDword();
-                readDword(); // skip checksum
-                int offset = readDword();
-                int length = readDword();
-
-                // Now here' the trick. 'name' field actually contains the textual string name.
-                // So the 'name' string in characters equals to 0x6E616D65
-                if ( tag == 0x6E616D65 )
-                {
-                    // Here's the name section. Read it completely into the allocated buffer
-                    byte[] table = new byte[ length ];
-
-                    m_file.seek( offset );
-                    read( table );
-
-                    // This is also a table. See http://developer.apple.com/fonts/ttrefman/rm06/Chap6name.html
-                    // According to Table 36, the total number of table records is stored in the second word, at the offset 2.
-                    // Getting the count and string offset - remembering it's big endian.
-                    int count = getWord( table, 2 );
-                    int string_offset = getWord( table, 4 );
-
-                    // Record starts from offset 6
-                    for ( int record = 0; record < count; record++ )
-                    {
-                        // Table 37 tells us that each record is 6 words -> 12 bytes, and that the nameID is 4th word so its offset is 6.
-                        // We also need to account for the first 6 bytes of the header above (Table 36), so...
-                        int nameid_offset = record * 12 + 6;
-                        int platformID = getWord( table, nameid_offset );
-                        int nameid_value = getWord( table, nameid_offset + 6 );
-
-                        // Table 42 lists the valid name Identifiers. We're interested in 4 but not in Unicode encoding (for simplicity).
-                        // The encoding is stored as PlatformID and we're interested in Mac encoding
-                        if ( nameid_value == 4 && platformID == 1 )
-                        {
-                            // We need the string offset and length, which are the word 6 and 5 respectively
-                            int name_length = getWord( table, nameid_offset + 8 );
-                            int name_offset = getWord( table, nameid_offset + 10 );
-
-                            // The real name string offset is calculated by adding the string_offset
-                            name_offset = name_offset + string_offset;
-
-                            // Make sure it is inside the array
-                            if ( name_offset >= 0 && name_offset + name_length < table.length )
-                                return new String( table, name_offset, name_length );
-                        }
-                    }
-                }
-            }
-
-            return null;
-        }
-        catch (FileNotFoundException e)
-        {
-            // Permissions?
-            return null;
-        }
-        catch (IOException e)
-        {
-            // Most likely a corrupted font file
-            return null;
-        }
-    }
-
-    // Font file; must be seekable
-    private RandomAccessFile m_file = null;
-
-    // Helper I/O functions
-    private int readByte() throws IOException
-    {
-        return m_file.read() & 0xFF;
-    }
-
-    private int readWord() throws IOException
-    {
-        int b1 = readByte();
-        int b2 = readByte();
-
-        return b1 << 8 | b2;
-    }
-
-    private int readDword() throws IOException
-    {
-        int b1 = readByte();
-        int b2 = readByte();
-        int b3 = readByte();
-        int b4 = readByte();
-
-        return b1 << 24 | b2 << 16 | b3 << 8 | b4;
-    }
-
-    private void read( byte [] array ) throws IOException
-    {
-        if ( m_file.read( array ) != array.length )
-            throw new IOException();
-    }
-
-    // Helper
-    private int getWord( byte [] array, int offset )
-    {
-        int b1 = array[ offset ] & 0xFF;
-        int b2 = array[ offset + 1 ] & 0xFF;
-
-        return b1 << 8 | b2;
-    }
-}
